兩週的時間,面試了杭州將近20多家軟件公司,有時下熱門的互聯網行業,也有傳統行業。涉及的行業衆多,社交直播平臺的、安防監控的、消費信貸的、大數據風控、互聯網醫療、電商的等等。這裏寫一下本身面試過程當中的遇到的面試題,藉以反思一下本身面試的不足。css
1.Spring框架的IOC和AOP原理;java
IOC:在傳統的程序實現裏,由代碼來控制組件之間的關係,使用new關鍵字來實現兩個組件之間的結合,這樣會帶來對象之間的耦合,像齒輪轉動同樣,有了IOC,它將實現組件關係從內部像外部轉移,由容器在運行期間將依賴關係注入到組件中。根據類名動態的生成對象,這種編程方式能夠在對象生成的時候才決定究竟是哪種對象。面試
AOP:經過在代理對象中包裹切面,運行期間將切面織入到容器管理的bean中,代理類封裝了目標類,並攔截被通知方法的調用,再將調用轉發給真正的目標bean。當攔截到方法調用,在調用目標bean以前代理會執行切面邏輯。AOP提供了兩種方式來生成代理對象:JDKProxy和Cglib,具體使用哪一種方式由AopProxyFactory根據AdvisedSupport對象的配置來決定。默認策略是若是目標類是接口就使用JDK動態代理請求,不然使用Cglib來代理。redis
2.類加載機制算法
Class文件由類裝載器裝載後,在jvm中將造成一份描述class結構元信息對象,經過該對象能夠獲知class的結構信息,如構造函數、屬性和方法。spring
雙親委派模型:sql
若是一個類加載器接收到類加載請求,它首先把這個請求委託給父類加載器去完成,所以,全部加載請求都應該傳送到頂層啓動類加載器中,只有父加載器反饋本身沒法完成這個加載請求,子加載器纔會嘗試本身去加載。數據庫
裝載:編程
驗證:設計模式
準備:
正式爲類變量分配內存,並設置變量初始值,內存都將在方法區進行分配;
解析:
虛擬機將常量池中的符號引用替換爲直接引用的過程
3.分佈式事務
基於XA協議的兩階段提交和消息+最終一致性
4.經常使用設計模式
單例、工廠、適配器、責任鏈、門面、裝飾、策略、觀察者等 說出幾個,並知道實現方法和應用場景。
5.sql調優
6.分庫分表策略
7.@Resource和@Autowired區別
同:都是作bean注入使用
異:@AutoWired默認按照類型byType裝配對象,依賴對象必須存在,若是容許null值,能夠設置required屬性爲false。@Resource默認按照byName注入,由j2ee提供;
8.java7新特性、java8新特性
9.servlet生命週期
初始化階段調用init方法
響應客戶請求調用service方法
終止階段調用destory方法
10.頁面加載慢的緣由
減小請求數、減小資源大小、找最快的服務器三方面去優化。
優化圖片資源的格式和大小;
開啓網絡壓縮;
使用瀏覽器緩存;
減小重定向,每一次重定向都會致使瀏覽器從新加載請求,延長加載時間;
使用cdn緩存靜態資源
減小dns解析次數
壓縮js和css去掉空格等
11.set底層實現
利用map的key不能重複
12.jvm分代垃圾回收
Eden區用來建立新對象,滿觸發一次young GC,將還被使用的對象複製到from區,Eden區再次用完再次用完,再觸發一次young GC,將eden和from區的還在被使用的對象複製到to區,下一次young GC則是將Eden區和to區還被使用的對象複製到from區,超過閾值對象尚未被釋放,複製到old generation。old用完觸發full GC。合理設置young generation和old generation避免產生full gc.
13.負載均衡算法
輪詢、加權輪詢、隨機、最少鏈接、源地址散列。
14.高可用架構設計
主要手段:數據和服務的冗餘備份和失效轉移
15.高可用服務
分級管理,核心應用與服務優先使用更好的硬件
超時設置,一旦超時,通訊框架拋出異常,應用可選擇重試和請求轉移
異步調用,消費者在消息隊列取
服務降級,拒絕服務和關閉服務,保證核心應用和功能能正常運行
冪等性設計,保證服務調用屢次和一次結果相同;
16.反射機制
17.分佈式緩存的一致性hash(網易)
18.https原理(網易)
19.樂觀鎖和悲觀鎖(網易)
20.數據庫隔離級別
21.spring事務傳播屬性
22.301與302區別(網易)
301永久轉移 302暫時轉移
23.get與post區別
24.表建索引規則
避免對大數據類型創建索引
常用group by和order by的創建索引
用於鏈接的列創建索引
對那些頻繁出如今where子句中的創建索引
肯定表是大量查詢仍是增刪改
25.跨域有幾種方式(網易)
26.HashMap與ConcurrentHashMap
27.分佈式鎖如何實現?
28.kafka技術優勢,以及是怎麼實現的?
29.Tcp/IP協議的三次握手與四次揮手
30.線程間如何通訊?(網易)
同步(synchronized)好比線程A和線程B都持有一個object,線程B須要等到A執行後才能運行。A與B就實現了通訊,本質上是共享內存通訊,多個線程須要訪問同一個共享變量,誰拿了鎖就能夠先執行
wait/notify機制,A調用wait進入阻塞,條件知足時,B調用notify喚醒A
管道通訊就是使用PipedInputStream和PipedOutputStream進行通訊
31.spring如何處理循環依賴?
構造器循環依賴:
<bean id="A" class="com.donsun.student.StudentA">
2 <constructor-arg index="0" ref="B"></constructor-arg>
3 </bean>
4 <bean id="B" class="com.donsun.student.StudentB">
5 <constructor-arg index="0" ref="C"></constructor-arg>
6 </bean>
7 <bean id="C" class="com.donsun.student.StudentC">
8 <constructor-arg index="0" ref="A"></constructor-arg>
9 </bean>
Spring容器會將每個正在建立的Bean 標識符放在一個「當前建立Bean池」中,Bean標識符在建立過程當中將一直保在這個池中,所以若是在建立Bean過程當中發現本身已經在「當前建立Bean池」裏時將拋出BeanCurrentlyInCreationException異常表示循環依賴;而對於建立完畢的Bean將從「當前建立Bean池」中清除掉。
setter循環依賴(單例):
<!--scope="singleton"(默認就是單例方式) -->
2 <bean id="A" class="com.donsun.student.StudentA" scope="singleton">
3 <property name="studentB" ref="B"></property>
4 </bean>
5 <bean id="B" class="com.donsun.student.StudentB" scope="singleton">
6 <property name="studentC" ref="C"></property>
7 </bean>
8 <bean id="C" class="com.donsun.student.StudentC" scope="singleton">
9 <property name="studentA" ref="A"></property>
10 </bean>
這種狀況下,Spring先實例化Bean對象 ,此時Spring會將這個實例化結束的對象放到一個Map中,而且Spring提供了獲取這個未設置屬性的實例化對象引用的方法。當Spring實例化了StudentA、StudentB、StudentC後,緊接着會去設置對象的屬性,此時StudentA依賴StudentB,就會去Map中取出存在裏面的單例StudentB對象,以此類推,不會出來循環的問題;
下面是Spring源碼中的實現方法,。如下的源碼在Spring的Bean包中的DefaultSingletonBeanRegistry.Java類中
1 /** Cache of singleton objects: bean name --> bean instance(緩存單例實例化對象的Map集合) */
2 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
3
4 /** Cache of singleton factories: bean name --> ObjectFactory(單例的工廠Bean緩存集合) */
5 private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16);
6
7 /** Cache of early singleton objects: bean name --> bean instance(早期的單身對象緩存集合) */
8 private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
9
10 /** Set of registered singletons, containing the bean names in registration order(單例的實例化對象名稱集合) */
11 private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
12 /**
13 * 添加單例實例
14 * 解決循環引用的問題
15 * Add the given singleton factory for building the specified singleton
16 * if necessary.
17 * <p>To be called for eager registration of singletons, e.g. to be able to
18 * resolve circular references.
19 * @param beanName the name of the bean
20 * @param singletonFactory the factory for the singleton object
21 */
22 protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) {
23 Assert.notNull(singletonFactory, "Singleton factory must not be null");
24 synchronized (this.singletonObjects) {
25 if (!this.singletonObjects.containsKey(beanName)) {
26 this.singletonFactories.put(beanName, singletonFactory);
27 this.earlySingletonObjects.remove(beanName);
28 this.registeredSingletons.add(beanName);
29 }
30 }
31 }
setter循環依賴(prototype):
2 <bean id="A" class="com.donsun.student.StudentA" scope="prototype">
3 <property name="studentB" ref="B"></property>
4 </bean>
5 <bean id="B" class="com.donsun.student.StudentB" scope="prototype">
6 <property name="studentC" ref="C"></property>
7 </bean>
8 <bean id="C" class="com.donsun.student.StudentC" scope="prototype">
9 <property name="studentA" ref="A"></property>
10 </bean>
由於「prototype」做用域的Bean,Spring容器不進行緩存,所以沒法提早暴露一個建立中的Bean。拋出BeanCurrentlyInCreationException
32.try{}catch(){}finally{}return各類變化返回值
一、無論有沒有出現異常,finally塊中代碼都會執行;
二、當try和catch中有return時,finally仍然會執行;
三、finally是在return後面的表達式運算後執行的(此時並無返回運算後的值,而是先把要返回的值保存起來,無論finally中的代碼怎麼樣,返回的值都不會改變,仍然是以前保存的值),因此函數返回值是在finally執行前肯定的;
四、finally中最好不要包含return,不然程序會提早退出,返回值不是try或catch中保存的返回值。
33.redis回收策略
34.集合迭代效率對比
35.ArrayList與LinkedList區別
36.jvm內存模型
37.java序列化算法
38.紅黑樹
39.synchronized用到的場景
40.線程池配置關鍵參數
41.平時用過哪些框架,看過哪些源碼以及實現原理
42.畫出你作過項目的架構圖
43.廣度優先遍歷與深度優先遍歷
44.你以爲你最擅長什麼?
45.項目怎麼改成分佈式?
46.HashMap中有個對象transient Entry[] table,爲何要加上關鍵字transient呢?
1.看一下HashMap.get()/put()知道, 讀寫Map是根據Object.hashcode()來肯定從哪一個bucket讀/寫. 而Object.hashcode()是native方法, 不一樣的JVM裏多是不同的,若是你使用默認的序列化,那麼反序列化後,元素的位置和以前的是保持一致的,但是因爲 hashCode 的值不同了,那麼定位函數 indexOf()返回的元素下標就會不一樣,這樣不是咱們所想要的結果.
2.transient 是代表該數據不參與序列化。由於 HashMap 中的存儲數據的數組數據成員中,數組還有不少的空間沒有被使用,沒有被使用到的空間被序列化沒有意義。因此須要手動使用 writeObject() 方法,只序列化實際存儲元素的數組。
47.分佈式鎖使用場景(網易)
48.dubbo版本號做用(網易)
當一個接口實現,出現不兼容升級時,能夠用版本號過渡,版本號不一樣的服務相互間
不引用。
在低壓力時間段,先升級一半提供者爲新版本
再將全部消費者升級爲新版本
而後將剩下的一半提供者升級爲新版本
49.秒殺系統設計(網易)
50.內部類與嵌套類區別
51.算法:遞歸實現迴文(網易)
52.算法:程序實現字符串有哪些英文字母空格數字,不能用ascii碼來判斷
53.zookeeper分佈式鎖節點與其餘節點區別(網易)
PERSISTENT_SEQUENTIAL 順序自動編號持久化節點,這種節點會根據當前已存在的節點數自動加
1
54.項目中遇到的問題以及如何解決的?
55.springMvc完整工做流程,哪些關鍵的類
56.spring用到的設計模式舉例
57.死鎖條件
教訓:
1.按照STAR法則製做簡歷;
2.不一樣的公司崗位需求確定不一樣,簡歷要有針對性,不要只准備一份簡歷;
3.要按照崗位需求,在項目中突出與之匹配的技能,先過了篩選這關;
4.要準備好才投簡歷,否則本身心儀的公司讓你去面試,結果你沒怎麼準備,被刷了,那麼機會可能就沒有了!
5.項目裏列出的技術,不能停留於表面的認識,至少你本身內心能過的去,否則你的簡歷在面試官那裏不是羊入虎口嗎~!
6.互聯網公司比較關注分佈式、中間件、併發編程、鎖之類的,建議多瞭解下java併發包以及市面流行的中間件;