方案1:前端
經過join方法保證多線程的順序性的特性java
join:讓主線程等待子線程執行完成後,主線程才執行。這裏join是調用的Object的wait方法node
package com.lzy; public class Main { static Thread thread1 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread1"); } }); static Thread thread2 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread2"); } }); static Thread thread3 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread3"); } }); static Thread thread4 = new Thread(new Runnable() { @Override public void run() { System.out.println("thread4"); } }); public static void main(String[] args) throws InterruptedException { thread1.start(); thread1.join();// 這裏的thread1.join是讓主線程wait thread2.start(); thread2.join(); thread3.start(); thread3.join(); thread4.start(); } }
方案2:mysql
static ExecutorService executorService = Executors.newSingleThreadExecutor();// FIFO
executorService.submit(thread1); executorService.submit(thread2); executorService.submit(thread3); executorService.submit(thread4);
這種方式是使用了單線程配合隊列(LinkedBlockingQueue)完成的。nginx
代碼git
方案3:web
經過共享對象鎖加上可見變量來實現ajax
public class MyService { private volatile int orderNum = 1; // 共享變量 public synchronized void methodA() { try { while (orderNum != 1) { wait(); // 當前線程讓出CPU } for (int i = 0; i < 2; i++) { System.out.println("AAAAA"); } orderNum = 2; notifyAll(); // 通知其餘線程啓動 } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodB() { try { while (orderNum != 2) { wait(); } for (int i = 0; i < 2; i++) { System.out.println("BBBBB"); } orderNum = 3; notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodC() { try { while (orderNum != 3) { wait(); } for (int i = 0; i < 2; i++) { System.out.println("CCCCC"); } orderNum = 1; notifyAll(); } catch (InterruptedException e) { e.printStackTrace(); } } }
import service.MyService; public class ThreadAA extends Thread { private MyService dbtools; public ThreadAA(MyService dbtools) { super(); this.dbtools = dbtools; } @Override public void run() { dbtools.methodA(); } }
import service.MyService; public class ThreadBB extends Thread { private MyService dbtools; public ThreadBB(MyService dbtools) { super(); this.dbtools = dbtools; } @Override public void run() { dbtools.methodB(); } }
import service.MyService; public class ThreadCC extends Thread { private MyService dbtools; public ThreadCC(MyService dbtools) { this.dbtools = dbtools; } @Override public void run() { dbtools.methodC(); } }
import extthread.ThreadCC; import service.MyService; import extthread.ThreadAA; import extthread.ThreadBB; public class Run { public static void main(String[] args) { MyService myService = new MyService(); for (int i = 0; i < 2; i++) { ThreadBB output = new ThreadBB(myService); output.start(); ThreadAA input = new ThreadAA(myService); input.start(); ThreadCC threadCC = new ThreadCC(myService); threadCC.start(); } } }
共享對象鎖,能夠保證每一個方法只能同時有一個線程進入,配合wait和notifyall方法,能夠啓動或者喚醒線程。redis
1.什麼是JMM算法
JAVA Memory Model
併發過程當中如何處理可見性、原子性、有序性的問題。
併發編程中的兩個關鍵問題
a.線程之間如何通訊;wait()、notify()、notifyall()
a)共享內存 - 隱式通訊
b)消息傳遞 - 顯式通訊
b.線程之間如何同步
在共享內存的併發模型中,同步是顯式作的;synchronized
在消息傳遞的併發模型中,因爲消息的併發必須在消息接受以前,全部同步是隱式
2.定位內存可見性問題
什麼對象是內存共享的,什麼不是(見 圖1-1)
Volatile、synchronized
3.
a.對於聲明瞭Volatile的變量進行寫操做的時候,JVM會向處理器發送一條Lock前綴指令。會把這個變量所在的緩存行的數據寫回到系統主內存中。
b.在多個處理器的狀況下,保證各個處理器緩存一致性的特色,就會實現緩存一致性協議
synchronized:可重入鎖、互斥性、可見性。
Volatile 能夠作到原子性、可見性;不能作到複合操做的原子性。
Volatile | Synchronized |
執行控制 | |
內存可見 | 內存可見 |
線程不安全 | 線程安全 |
從主存中取數據 | 鎖加 |
使用在變量級別 | 變量、方法 、類 |
不會線程阻塞 | 會線程阻塞 |
不能夠被編譯器優化 | 能夠被編譯器優化 |
圖1-1
Lock和synchronized的區別
Java5之後出現的:juc(java.util.concurrent.locks)包
1)Lock是一個接口,而synchronized是Java中的關鍵字,synchronized是內置的語言實現;
2)synchronized在發生異常時,會自動釋放線程佔有的鎖,所以不會致使死鎖現象發生;而Lock在發生異常時,若是沒有主動經過unLock()去釋放鎖,則極可能形成死鎖現象,所以使用Lock時須要在finally塊中釋放鎖;
3)Lock可讓等待鎖的線程響應中斷,而synchronized卻不行,使用synchronized時,等待的線程會一直等待下去,不可以響應中斷;
4)經過Lock能夠知道有沒有成功獲取鎖,而synchronized卻沒法辦到。
5)Lock能夠提升多個線程進行讀操做的效率。
在性能上來講,若是競爭資源不激烈,二者的性能是差很少的,而當競爭資源很是激烈時(即有大量線程同時競爭),此時Lock的性能要遠遠優於synchronized。因此說,在具體使用時要根據適當狀況選擇。
一個進程中包含不少線程。
1.繼承Thread類,
2.實現Runnable接口,
3.使用ExecutorService(java5),
4.Callable Future帶返回值的多線程操做
建立、就緒、運行、阻塞、終止
分佈式鎖是針對多進程同步。
解決方式:
1.經過數據庫的方式解決
create table (
id,
method_name(惟一約束)
……
)
多個進程向數據庫插入數據,返回結果大於1的獲取鎖,那麼就能夠去操做共享資源,釋放鎖是經過刪除數據庫中的這條記錄。這種方式是利用了數據庫設置的惟一約束性。
問題:刪除失敗怎麼辦;insert模式不是重入鎖。
2.zookeeper方式
zookeeper節點特色:持久、持久有序、臨時、臨時有序。而且是樹形、相似文件存儲結構
咱們能夠建立一個鎖節點,而後每一個進程都向這個鎖節點下建立一個臨時有序節點,咱們把建立序號最小的節點做爲得到鎖的進程,帶進程操做完了後,刪除該進程建立的節點,此時剩下的節點中的最小節點就是獲的鎖的進程,可是該進程怎麼知道本身獲取到鎖了呢?其實zookeeper還提供了watch機制,該機制是建立節點時綁定watch,即序號大的watch比他小的相鄰的節點,以此類推,當小節點被刪除後就會通知相鄰大節點。
3.基於redis
setnx命令是隻有當key不存在時才爲key設置值,並返回0和1,能夠根據返回值去判斷誰得到了鎖。
1. 集合框架中有哪些是安全的?
線程安全的有Hashtable、Vector、properties
2. 設計模式使用過哪些?
使用過模板模式、單例模式、策略模式、代理模式。
模板模式是使用在命令下發時,使用抽象類實現公共的步驟,主要是數據準備,各自的實現類去完成符合不一樣設備的命令格式的數據,
策略模式是使用在數據解析上,咱們的項目會接受多個平臺的數據,數據同樣可是格式不同,這時就使用了策略模式去解析不一樣格式的數據,返回同一格式的數據。
代理模式主要是使用在短信平臺接入上,項目要求能夠接入多個短信平臺,這時就使用動態代理加載不一樣的實現類。
單例模式主要是用在封裝單線程處理隊列任務的業務場景下,好比把數據放到LinkListBlockQueue中 ,開啓單線程去處理這個隊列。
3. 怎樣實現多線程返回結果
Callable 配合Future實現待返回值的多線程,經過實現Callable的call方法,將callable傳入到線程的submit方法中,最後經過Future獲取結果
4. java 中的排序算法怎樣實現的?
5. hashmap實現
6. Volatile關鍵字的做用
7. 單例模式中加上volatile關鍵字的做用
8.瞭解jvm嗎
9. 雙親委派模型
10. gc運行過程
11. 線程池能夠設置哪些參數
12. 線程池中怎樣給線程命名
13.看過那些書
《重構改善既有代碼的設計》、《java併發編程實戰》、《Effective java》
14.java中給變量賦值是原子操做嗎
1)除long和double以外的基本類型的賦值操做
2)全部引用reference的賦值操做
3)java.concurrent.Atomic.* 包中全部類的一切操做
count++不是原子操做,是3個原子操做組合
15.動態代理的實現方式
16. cglib動態代理有哪些缺陷
1. 不使用https怎樣防止盜鏈?或者使用過怎樣的簽名方式
對用戶的token,時間戳,參數等進行md5簽名,服務器端判斷是否被篡改。
2. 加解密:AES?
AES、Base64
3.若是jwt中token被盜竊了,怎樣阻止用戶登陸或者鎖定帳號
1. 秒殺思路?
前端作頁面靜態化處理,使用ajax作時間同步,開啓秒殺後,啓動時加載商品數量好比20個,使用redis的原子操做incr判斷當前是否超過了20人,前20名的請求進入到隊列,並將這20個用戶的信息存入到redis中,開啓單線程去消費隊列中的數據,操做數據庫時,可使用樂觀鎖對數據枷鎖,只要成功了就更新redis中的用戶信息標記爲秒殺成功,前端查詢秒殺結果是經過ajax異步查詢redis中的信息獲得是否秒殺成功,
1. zookeeper 怎麼使用?
2. ActiveMQ的做用?
實現系統之間的解耦
提供的消息類型有:TextMessage、MapMessage、ObjectMessage、ByteMessage 、StreamMessage
消息模式
p2p:一對一的,只要發送了,不論消費者在不在線,最終均可以接收到
發佈/訂閱:一對多,Topic模式,只有消費者在線才能夠接受 ,也能夠註冊持久化訂閱
2. spring cloud 有哪些模塊
註冊中心Eureka、Ribbon客戶端負載均衡、Feign實現接口調用、Hystrix實現容錯處理、zuul實現網關或者getWay、config實現配置中心。
3. nginx 負載均衡
輪訓、權重、ip_Hash
4. 爲何nginx性能這麼高
得益於它的事件處理機制:
異步非阻塞事件處理機制:運用了epoll模型,提供了一個隊列,排隊解決
5.spring mvc請求過程
6. springbean的生命週期
9.http 常見狀態碼 40一、403
java語言提供的遠程方法調用,服務接口集成remote,使用Naming.rebind方法發佈服務,客戶端使用Naming.lookup方法調用該服務
1. spring boot 怎樣注入map屬性?
springboot 的配置文件若是是properties就不能注入,若是是yml的就能夠,使用縮進的格式定義key和value值
2. 在使用框架時,遇到哪些問題?
好比咱們常用配置文,並使用@Value註解將數據注入進去,可是我遇到在Controller中不能註冊,老是說找不到,進過資料查找發現確實不能注入,由於spring 和springmvc有父子容器的概念,既是自容器能訪問父容器內容,父容器不能訪問自容器的內容,我只在父容器中配置了,並無在自容器中配置。
3. spring Bean生命週期
4. dubbo 支持那些協議
dubbo(默認)、hessian、http、redis、webservice、rmi、thrift、memached
5.dubbo支持序列化方式
dubbo 、jdk、fastjson、hessian2(默認)
6.zookeeper的數據結構
樹下結構、znode
7.zookeeper使用的哪一個算法
paxos
8.spring中怎樣加載properties的方式
9.
1. 作過哪些優化
2. sql層面作過哪些優化
3. tomcat 優化
1. 分庫分表
2. 使用過mycat嗎?
3. 當多張表聯合查詢時,其中一張表的索引不生效,怎樣找出這個索引
使用explain查詢執行計劃
4. mysql 的整數類型有哪些
5.mysql怎樣枷鎖
select * from table where ? lock in share mode;
select * from table where ? for update;
insert into table values (…);
update table set ? where ?;
delete from table where ?;
6.mysql的事物隔離界別
1.讀未提交,2.不可重複讀,3.可重複讀,4.串行化
事務隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
讀未提交(read-uncommitted) | 是 | 是 | 是 |
不可重複讀(read-committed) | 否 | 是 | 是 |
可重複讀(repeatable-read) | 否 | 否 | 是 |
串行化(serializable) | 否 | 否 | 否 |
7.教師表和學生表,老師之間有繼承性,查出某個老師下的全部學生,表結構能夠從新設計
teacher表
id 老師 父親id
1 | A老師 | 0 |
2 | B老師 | 1 |
3 | C老師 | 3 |
student表
id | 學生 | 老師外鍵id |
1 | A學生 | 1老師 |
2 | B學生 | 2老師 |
1. 我們公司和你心目中的公司相比,百分制能打多少分
2.你對我們公司瞭解多少
3.你認爲寫好一個程序最重要的是什麼
4.你最看重一個公司的什麼
5.你對將來有什麼規劃