1. 程式人生 > >記錄一次跳槽java面試中遇到的問題

記錄一次跳槽java面試中遇到的問題

1、nginx是用來做什麼的?
反向代理,負載均衡。當網站的訪問量達到一定程度後,單臺伺服器不能滿足使用者的請求時,需要用多臺伺服器叢集可以使用nginx做反向代理。並且多臺伺服器可以平均分擔負載,不會因為某臺伺服器負載高宕機而某臺伺服器閒置的情況。

2、spring的依賴注入是什麼?有幾種注入方式?Set注入是怎麼注入的?
依賴注入( Dependecy Injection )和控制反轉( Inversion of Control )是同一個概念, 具體的講:當某個角色 需要另外一個角色協助的時候,在傳統的程式設計過程中,通常由呼叫者來建立被呼叫 者的例項。但在 spring 中 建立被呼叫者的工作不再由呼叫者來完成,因此稱為控制反轉。建立被呼叫者的工作由 spring 來完成,然後注入呼叫者 因此也稱為依賴注入。 spring 以動態靈活的方式來管理物件 
注入的三種方式:set注入和構造注入和介面注入。 設定注入的優點:直觀,自然 構造注入的優點:可以在構造器中決定依賴關係的順序!
Set方式的注入可以注入的內容有:
1.基本型別(8中基本型別+字串)的裝配
2.物件型別的裝配
3.集合的裝配
Spring管理bean就是tomcat啟動的時候通過掃描(comment-scan)註解比如掃描某個包下的有@service的類載入到spring容器中
在Spring中,注入依賴物件可以採用手工裝配或自動裝配,在實際應用開發中建議使用手工裝配,因為自動裝配會產生許多未知情況,開發人員無法預見最終的裝配結果。
手工裝配依賴物件又分為兩種方式:
一種是在XML檔案中,通過在bean節點下配置;如上面講到的使用屬性的setter方法注入依賴物件和使用構造器方法注入依賴物件都是這種方式。
另一種就是在java程式碼中使用註解的方式進行裝配,在程式碼中加入@Resource或者@Autowired
重點:在Spring IOC程式設計的實際開發中推薦使用註解的方式進行依賴注入。

3、AOP的面向切面

將那些與業務無關,卻為業務模組所共同呼叫的 邏輯或責任封裝起來,比如事務管理、許可權驗證,便於減少系統的重複程式碼,降低模組間的耦合度,並有利於未來的可操作性和可維護性

4、一個service中呼叫另一個service的方法時的事務控制問題
配置通知,傳播行為<tx:method name="save*" propagation="REQUIRED" />,當一個seivice中呼叫另一個service時在使用SPRING的事務控制時,事務一般都是加在SERVICE層的,這個時候如果一個SERVICE呼叫另一個SERVICE時有可能會出現事務控制問題,比如第二個SERVICE丟擲了異常,第一個SERVICE卻正常提交了

在事務傳播為propagation="REQUIRED"的時候,如果SERVICE中丟擲檢查型異常( throw new FileNotFoundException("fjkdl"); ),其它的事務可以正常提交,但是如果SERVICE丟擲執行時異常( throw new RuntimeException("runtime e");),則所有的SERVICE共享同一事務(會回滾)。
 如果我們改下配置,如下:
<tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>  
 這個時候,無論SERVICE裡丟擲執行時異常還是檢查型異常,將共享同一事務,也就是說只要有異常,事務將自動回滾。

Spring中事務傳播型別:七種
常見的有兩種
REQUIRED:支援當前事務,如果當前沒有事務,就新建一個事務。這是最常見的選擇。 
SUPPORTS:支援當前事務,如果當前沒有事務,就以非事務方式執行。 

5、java的反射是什麼?

JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法,並且構造這個類的物件;對於任意一個物件,都能夠呼叫它的任意一個方法,並且判定這個物件所屬的類;這種動態獲取的以及動態呼叫物件的方法的功能稱為java語言的反射機制。

6、java虛擬機器是什麼?為什麼java有虛擬機器,c沒有虛擬機器?
(1)可以理解為是執行java位元組碼檔案的機器(虛擬機器程序);
(2)因為java語言寫的程式碼是.java檔案,編譯後是位元組碼檔案,位元組碼不能直接在cpu上執行,所以需要用到虛擬機器把位元組碼檔案轉換成二進位制檔案,而C語言編譯的檔案就是二進位制檔案,所以可以直接在cpu上執行。

7、Java面向物件有幾種規則?

Java面向物件的6大原則:開閉原則、里氏代換原則、依賴倒換原則、介面隔離原則、單一職責原則或聚合複用原則、迪米特法則或最少知識原則

8、linux常見命令

答案就不寫了

9、堆和棧都是存放什麼資訊的?String str = new String(“hello”);說一下這串程式碼裡面的的哪些資訊放在哪裡?
類的靜態成員變數和類的資訊(方法)是放在方法區中,類的成員變數是放在堆中。
方法中定義的引用如str是存放在棧中,new String(“hello”)物件都存放在堆中,hello是存放在字串的常量池中(方法區中)。

10、java的序列化與反序列化是什麼?為什麼要序列化和反序列化?
Java序列化是指把Java物件儲存為二進位制位元組碼的過程,Java反序列化是指把二進位制位元組碼重新轉換成Java物件的過程。
需要把Java物件通過網路進行傳輸的時候。因為資料只能夠以二進位制的形式在網路中進行傳輸,因此當把物件通過網路傳送出去之前需要先序列化成二進位制資料,在接收端讀到二進位制資料之後反序列化成Java物件。

11、一般跟多執行緒有關的都需要鎖、鎖有幾種?為什麼要用到鎖? 
鎖有synchronized與Reentrantlock(重入鎖),平常的程式當中由於是單執行緒去處理的,因此不會出現變數資源同時被多個執行緒同時訪問修改,程式的執行是順序的。然而多執行緒的環境中就會出現變數資源同時被多個執行緒獲取,同時去做修改的狀況。

Reentrantlock擁有和synconized的區別:
Reentrantlock擁有和synconized相同的併發性和記憶體語義,此外還多了鎖投票,定時鎖等候和中斷鎖等候的功能
(1)執行緒A和B都要獲取物件O的鎖定,假設A獲取了物件O鎖,B將等待A釋放對O的鎖定, 如果使用 synchronized,如果A不釋放,B將一直等下去,不能被中斷
如果 使用ReentrantLock,如果A不釋放,可以使B在等待了足夠長的時間以後,中斷等待,而幹別的事情
(2)synconized是虛擬機器層面上的,由虛擬機器來自動釋放鎖,lock是通過程式碼來實現的,只能手動釋放鎖,在finaly程式碼塊中釋放。
(3)在資源競爭不是很激烈的情況下,Synchronized的效能要優於ReetrantLock,但是在資源競爭很激烈的情況下,Synchronized的效能會下降幾十倍,但是ReetrantLock的效能能維持常態;

12、java中的垃圾回收

為了分代垃圾回收,Java堆記憶體分為3代:新生代(複製演算法),老年代(標記整理演算法、標記清除演算法)和永久代。
新生代和老年代是在堆中,永久代是在方法區中
新的物件例項會優先分配在新生代,在經歷幾次Minor GC後(預設15次),還存活的會被移至老年代(某些大物件會直接在老年代分配)。
永久代是否執行GC,取決於採用的JVM。
Minor GC發生在新生代,當Eden區沒有足夠空間時,會發起一次Minor GC,將Eden區中的存活物件移至Survivor區。Major GC發生在老年代,當升到老年代的物件大於老年代剩餘空間時會發生Major GC。
發生Major GC時使用者執行緒會暫停,會降低系統性能和吞吐量。
JVM的引數-Xms和-Xmx用來設定Java堆記憶體的初始大小和最大值。依據個人經驗這個值的比例最好是1:1或者1:1.5。比如,你可以將-Xmx和-Xms都設為1GB,或者-Xmx和-Xms設為1.2GB和1.8GB。
Java中不能手動觸發GC,但可以用不同的引用類來輔助垃圾回收器工作(比如:弱引用或軟引用)。
垃圾回收總結:一個物件在沒有任何強引用指向他或該物件通過根節點不可達時需要被垃圾回收器回收;當垃圾收集器意識到需要進行GC時會觸發Minor GC或Major GC,是自動的,無法強制執行

Jvm的一些常見引數
-server:一定要作為第一個引數,在多個 CPU 時效能佳
(配置堆區:有垃圾回收機制)
-Xms:表示 Java 初始堆大小
-Xmx:表示 Java 最大堆大小
-Xss:表示每個 Java 執行緒堆疊大小
-XX:NewSize:設定新生代記憶體大小。
-XX:MaxNewSize:設定新生代記憶體最大值
-xmn:對前兩個引數同時配置
(配置非堆區:方法區沒有垃圾回收機制,這一塊只能靠程式設計師自己來約束自己)
-XX:PermSize:設定持久代記憶體大小
-XX:MaxPermSize:設定持久代記憶體最大值
注意:最大堆記憶體和最大非堆記憶體的和不能超出作業系統的可用記憶體

12、HashMap,HashTable,ConcurrentHashMap,sychronizedMap的原理和區別
HashMap 是執行緒不安全的:
內部儲存使用了一個 Node 陣列(預設大小是16),《java併發程式設計藝術》中說到HashMap 在併發執行 put 操作時會引起死迴圈,導致 CPU 利用率接近100%。因為多執行緒會導致 HashMap 的 Node 連結串列形成環形資料結構,一旦形成環形資料結構,Node 的 next 節點永遠不為空,就會在獲取 Node 時產生死迴圈。
HashTable 是執行緒安全的:
HashTable 原始碼中是使用 synchronized 來保證執行緒安全的,比如 get 方法和 put 方法,當一個執行緒使用 put 方法時,另一個執行緒不但不可以使用 put 方法,連 get 方法都不可以(當一個執行緒訪問 HashTable 的同步方法時,其他執行緒如果也要訪問同步方法,會被阻塞住)

ConcurrentHashMap是執行緒安全的:
ConcurrentHashMap 不僅執行緒安全而且效率高,因為它包含一個 segment 陣列,將資料分段儲存,給每一段資料配一把鎖,也就是所謂的鎖分段技術,同時最多可以有16個寫執行緒操作Map,讀操作幾乎不受限制。(Segment其實是繼承能了reentranlock,所以它是一種重入鎖)(這是java7中的,java8已經摒棄了 Segment(鎖段)的概念,而是啟用了一種全新的方式實現,利用 CAS 演算法)
SynchronizedMap是執行緒安全的:
 synchronizedMap() 方法後會返回一個 SynchronizedMap 類的物件,而在 SynchronizedMap 類中使用了 synchronized 同步關鍵字來保證對 Map 的操作是執行緒安全的。

最後總結:ConcurrentHashMap效能是優於Hashtable 和 SynchronizedMap (可以用ExecutorService 來併發執行5個執行緒進行測試)

13、HashMap是如何解決衝突的
使用連結法,將索引值相同的元素存放到一個單鏈表裡,為了解決在頻繁衝突時HashMap效能降低的問題,Java 8中做了一個小優化,在衝突的元素個數超過設定的值(預設為8)時,會使用平衡樹來替代連結串列儲存衝突的元素

14、ArrayList和LinkedList區別
ArrayList、Vector是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結構。 
ArrayList、Vector有下標,所以查詢資料快,Vector由於使用了synchronized方法-執行緒安全,所以效能上比ArrayList要差,inkedList使用雙向連結串列實現儲存,按序號索引資料需要進行向前或向後遍歷,但是插入資料時只需要記錄本項前後項即可,插入資料較快。

15、set集合
Set是最簡單的一種集合。集合中的物件不按特定的方式排序,並且沒有重複物件。 Set介面主要實現了兩個實現類:
HashSet: HashSet類按照雜湊演算法來存取集合中的物件,存取速度比較快 
TreeSet :TreeSet類實現了SortedSet介面,能夠對集合中的物件進行排序。 

16、執行緒同步的五種方法
(1)Synchronized關鍵字修飾的方法
(2)Synchronized關鍵字修飾程式碼塊
(3)使用特殊域變數(volatile)實現執行緒同步:
在需要同步的變數上加上volatitle進行修飾
private volatile int acount = 100;
資源變數是透明的,多個執行緒之間共用資源變數,當執行緒A修改資源變數時,執行緒B立馬就獲取到最新的資源變數。
原理:是每次要執行緒要訪問volatile修飾 的變數時都是從記憶體中讀取,而不是從快取當中讀取,因此每個執行緒訪問到的變數值都是一樣的。這樣就保證了同步
Volatile 變數具有 synchronized 的可見性特性,但是不具備原子特性。
volatile不是執行緒安全的,因為此時多個執行緒的執行是無序的,並不能保證多個執行緒執行的有序性和原子性,所以說它不是執行緒安全的。
(4)ReentranLock重入鎖實現執行緒同步:
private Lock lock = new ReentranLock();
lock.lock(); 
lock.unlock();
(5)使用ThreadLocal管理變數來實現同步:
private static Threadlocal<integer> accout = new ThreadLocal<Integer>(){
...
}
每一個使用該變數的執行緒都會獲得該變數的副本,副本之間相互獨立,每個執行緒都可以隨意修改自己的變數副本不會影響別的執行緒。
原理:底層其實是用hashmap根據執行緒標識(key)來儲存副本的變數的(value),所以它不是執行緒安全的


17、實現執行緒的幾種方式
1.繼承Thread類
2.實現Runnable介面
3.實現Callable介面通過FutureTask包裝器來建立Thread執行緒(callable的call方法是有返回值)

18、mysql的sql執行時間較長
可用pt-query-digest等工具分析慢查詢日誌,也可以用explain檢視SQL的執行計劃

19、mysql的四個儲存引擎
(1)、MyISAM儲存引擎:特點:不支援事務、也不支援外來鍵,優勢是訪問速度快,對事務完整性沒有要求
(2)、InnoDB儲存引擎:
該引擎提供了具有提交、回滾和崩潰恢復能力的事務安全
特點:支援自動增長列,支援外來鍵約束
(3)、Memory儲存引擎
(4)、Merge儲存引擎:是一組MyISAM表的組合

20、oracle的sql優化 檢視執行計劃和統計資訊
set autotrace on:包含執行計劃和統計資訊
在執行計劃中只需要看cost(代價)
Cost:代價越大,效能就越低
在統計資訊中只需要看邏輯讀
1042 consistent gets:邏輯讀,邏輯讀越大,效能越低

21、儲存過程和儲存函式的區別
不同點:函式有返回值型別,過程沒有,函式可以在select語句中直接使用,過程不可以
相同點:兩者都可以出參(通過out引數出參)

22、什麼樣的列適合加索引
在where從句,group by從句,order by從句,on從句中出現的列
索引的欄位越小越好
在建立聯合索引時,離散度大的列放大聯合索引的前面
列中只有1和2不適合建索引

23、Redis提供哪幾種資料結構
字串,雜湊,列表,集合,有序集合。

24、spring中用到的設計模式
工廠模式:IOC容器
代理模式:AOP
策略模式:在spring採取動態代理時,根據代理的類有無實現介面有JDK和CGLIB兩種代理方式,就是採用策略模式實現的
單例模式:預設情況下spring中的bean只存在一個例項

25、什麼是多型?
一、繼承中的多型
1、存在繼承關係
2、子類要重寫父類的方法
3、父類資料型別的引用指向子類物件。
父類引用指向子類物件,呼叫方法時會呼叫子類的實現,而不是父類的實現,這叫多型。
二、同一個類中
1、方法的過載,相同的方法名對應著不同的方法實現(方法引數不同),這也做多型。
總結:覆蓋是父類與子類之間多型性的一種表現,過載是一個類中多型性的一種表現。

26、springmvc是單例還是多例,springmvc是不是執行緒安全的?
Springmvc預設是單例模式,因為spring的作用域有5個,分別是:singleton(單例模式)、prototype(原型模式)、request、session、globalSession五個。
Springmvc預設是單例模式,所以成員屬性會出現執行緒安全問題、是非執行緒安全的

27、mybatis和hibenate的區別
hibernate是全自動,而mybatis是半自動
sql直接優化上,mybatis要比hibernate方便很多
hibernate資料庫移植性遠大於mybatis

28、springmvc的工作原理
1、DispatcherServlet前端控制器接收發過來的請求,交給HandlerMapping處理器對映器
2、HandlerMapping處理器對映器,根據請求路徑找到相應的HandlerAdapter處理器介面卡(處理器介面卡就是那些攔截器或Controller)
3、HandlerAdapter處理器介面卡,處理一些功能請求,返回一個ModelAndView物件(包括模型資料、邏輯檢視名)
4、ViewResolver檢視解析器,先根據ModelAndView中設定的View解析具體檢視
5、然後再將Model模型中的資料渲染到View上

29、事務的概念?資料庫的事務的四大特性?
事務的概念:
事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功
資料庫的事務的四大特性:
原子性:是指事務是一個不可再分割的工作單元,事務中的操作要麼都發生,要麼都不發生。
一致性:是指在事務開始之前和事務結束以後,資料庫的完整性約束沒有被破壞。這是說資料庫事務不能破壞關係資料的完整性以及業務邏輯上的一致性。
隔離性:是多個事務併發訪問時,事務之間是隔離的,一個事務不應該影響其它事務執行效果
永續性:是在事務完成以後,該事務所對資料庫所作的更改便持久的儲存在資料庫之中,並不會被回滾


30、資料庫事務的四個隔離級別:
在事務的併發操作中可能會出現 髒讀,不可重複讀,幻讀
髒讀:看到的是老闆還沒提交事務時的資料。這就是髒讀。
不可重複讀:銀行卡刷卡時出現了一個事務範圍內兩個相同的查詢卻返回了不同資料,這就是不可重複讀。
幻讀:超市購買東西第一次刷卡有錢再次刷卡錢沒了,像是產生了幻覺
讀未提交:顧名思義,就是一個事務可以讀取另一個未提交事務的資料。
什麼問題都解決不了
讀已提交:顧名思義,就是一個事務要等另一個事務提交後才能讀取資料。
能解決髒讀問題
可重複讀:就是在開始讀取資料(事務開啟)時,不再允許修改操作(不可重複讀對應的是修改,即UPDATE操作)
能解決不可重複讀問題,髒讀問題
序列化:就是在開始讀取資料(事務開啟)時,不再允許插入操作(幻讀對應的插入操作,即insert操作)
序列化可以解決幻讀,不可重複讀,髒讀問題

絕大多數資料庫是的預設事務隔離級別是讀已提交
但是mysql的預設事務隔離級別是可重複讀

31、貨主釋出貨找車貨源,車主搶單的時候是怎麼處理併發的?(本人專案中涉及到的併發搶單問題)

採用的是樂觀鎖,就是在貨源表加一個version版本的欄位,每次要去修改貨源的狀態時,首先去查當前訂單表中該訂單的version值出來,然後進行update這個訂單狀態(同時修改version值,我的處理是version值+1)的時候再加上where 條件過濾,判斷version值是否還是之前獲取的version值。如果是之前獲取的version值,就可以更改成功,然後再插入一條訂單,否則更改失敗,返回0,不插入訂單,前端接收資訊並進行相應的處理(例:該訂單已被別人搶單)。

32、Spring Boot特點,為什麼要用springboot?
1. 建立獨立的Spring應用程式
2. 嵌入的Tomcat,無需部署WAR檔案
3. 簡化Maven配置
4. 自動配置Spring

5. 全程使用註解,對xml無任何配置

springBoot最大的特點就是當下所倡導的一種理念“習慣優於配置”springBoot它其實並沒有用到特別的技術,而是在專案中預先進行了許多習慣性的配置,內嵌tomcat容器,無程式碼生成並且專案可以沒有一個xml配置,全由註解來完成這一切,其本身提供了準企業級開發的配置。
常見的註解:
1、@SpringBootApplication:Spring Boot專案的核心註解,主要目的是開啟自動配置(通常用於主類上);
2、@Configuration:這是一個配置Spring的配置類;


33、說一下dubbo

dubbo:分散式微服務框架、用來提高效能和rpc遠端呼叫方案,是阿里巴巴SOA服務化治理方案的核心框架。
最大的特點是按照分層的方式來架構,最大限度的解耦合;從服務角度來看可以抽象出服務消費方和服務提供方兩個角色。
rpc:遠端呼叫協議,就是在分散式系統中當a和b系統都有相同的一個功能時,把這個功能(介面、javabean以及介面的實現)抽取出來放到c這個系統中,
然後c這個系統就是服務提供方,a和b(a和b系統只保留介面和javabean,當然還可以把a、b、c這三個系統中的javabean和介面抽取出來放到一個新建的功能c-api中解決程式碼重複問題,在a、b、c系統中新增c-api的依賴就可以了)
個系統就是服務消費方(呼叫方),a和b呼叫c系統功能的這個過程就叫做遠端呼叫。

dubbo入門配置:
dubbo-server.xml配置
將介面實現類載入到spring容器中,然後把介面暴露到dubbo中,然後用dubbo協議在20880埠中暴露服務,並註冊到zookeeper註冊中心。把監控中心也釋出到註冊中心裡面去(監控中心也是一個服務),統計服務的呼叫時才傳送資料到註冊中心中。
當一個系統呼叫另一個系統釋出的服務時httpclient發起get、post請求和使用dubbo協議的區別:
httpclient發起get、post請求:拿到的是json資料、需要自己進行反序列化。
使用dubbo協議會自動完成序列化和反序列化。

dubbo註冊中心,比如當門戶系統請求後臺系統查詢新聞時,先去註冊中心查詢,如果找到了,再呼叫後臺服務查詢新聞。
這樣子在註冊中心可以有效的管理起來。然後監控中心用來統計服務的呼叫(非同步的方式)。
原理:服務消費者和提供者,在記憶體中累計呼叫次數和呼叫時間,定時每分鐘傳送一次統計資料到監控中心。
呼叫關係:
1. 服務容器負責啟動,載入,執行服務提供者。
2. 服務提供者在啟動時,向註冊中心註冊自己提供的服務。
3. 服務消費者在啟動時,向註冊中心訂閱自己所需的服務。
4. 註冊中心返回服務提供者地址列表給消費者,如果有變更,註冊中心將基於長連線推送變更資料給消費者。
5. 服務消費者,從提供者地址列表中,基於軟負載均衡演算法,選一臺提供者進行呼叫,如果呼叫失敗,再選另一臺呼叫。
6. 服務消費者和提供者,在記憶體中累計呼叫次數和呼叫時間,定時每分鐘傳送一次統計資料到監控中心。

http:短連結:使用完之後連結就會斷開(打資料量小併發時用,比如檔案)
dubbo協議:單一長連結:使用完之後不會斷開、一直存在(小資料量大併發時用,因為大併發的情況下,每次都建立連線效能就會下降得很厲害)