摘要:線程有幾種狀態生命周期是怎樣的線程有五種狀態創建就緒運行阻塞死亡。當線程獲得到等待的資源資源或者引起阻塞的條件得到滿足時調用或,會從阻塞狀態進入就緒狀態。使用,允許最多個線程同時訪問資源。
轉載請注明出處: 貼一貼我的后端開發面試題。技術無關:本文是面試回寢室后憑記憶羅列出來的問題,大概90%的問題都在這里面了,有幾個問題的實在是想不起來了= =,有些問題自我感覺回答的不好,所以我是查了資料后重新整理了再貼上答案的。如有錯誤或不適合的,歡迎大家評論點出,謝謝!
雖然面試的是Java實習生職位,但問題不局限于Java語言。
面試過程中只有三個技術無關的話題:
自我介紹。
感覺自己有什么優缺點?
你現在有女朋友了嗎? = =..
這類的話題一般稍微準備一下,都不會有什么問題。
技術相關: 1. Spring MVC 如何接受并處理一個請求的?首先我們會在web.xml中注冊一個DispatcherServlet,并令這個servlet接收所有的請求,項目啟動后Spring會掃描配置文件,根據配置加載和實例化類,其中掃描到的帶有@Controller或者@RestController注解的類則是請求要映射到的類,Spring MVC掃描里面所有和請求映射有關的注解, 如@RequestMapping、@ResponseBody、@RequestParam等。當接收到一個請求時,它會根據請求的url映射到對應的controler,并根據返回值判斷是渲染jsp頁面還是返回普通文本,亦或是返回json。2. AOP實現原理。
AOP是通過動態代理來實現的,有兩種常用的技術,一是JDK的動態代理,二是CGLIB,而無論是前者還是后者,都是生成動態生成類的字節碼來實現的。JDK的動態代理只能處理接口實現的方法,而CGLIB則沒有這個限制。因為字節碼是動態生成的,所以可以在生成的字節碼當中,在目標方法前后插入定義好的方法的調用。3. 注解是怎么用的?為什么要使用注解?
當在一個類、方法或者字段上標上注解后,可以通過obj.getClass().isAnnotationPresent(..)來判斷一個目標是否被特定的注解標識,通過obj.getClass().getAnnotation(..)來獲取標志是注解,以此獲得注解上的信息。使用注解可以幫助我們在項目的編譯期或運行時給類、方法或對象添加一個額外的信息,給編程增加了很大的靈活性。比如用@Override來標志這是重寫父類的方法,那么編譯器就可以在編譯期檢查該方法是否真的是重寫父類的方法,將錯誤扼殺在編譯器。4. 線程有幾種狀態?生命周期是怎樣的?
線程有五種狀態:創建、就緒、運行、阻塞、死亡。5. Java中如何實現同步。
調用start方法時,線程就會進入就緒狀態。
在線程得到cpu時間片時進入運行狀態。
線程調用yield方法可以讓出cpu時間回到就緒狀態。
線程運行時可能由于IO、調用sleep、wait、join方法或者無法獲得同步鎖等原因進入阻塞狀態。
當線程獲得到等待的資源資源或者引起阻塞的條件得到滿足時(調用notify或notifyAll),會從阻塞狀態進入就緒狀態。
當線程的run方法執行結束或者調用interrupt方法時,線程就進入死亡狀態。
6. HashMap與Hashtable的區別。Java實現同步的方法有:
使用synchronized關鍵字為方法或代碼塊加鎖。
使用volatile修飾變量,但是volatile不保證原子性。
使用ReentrantLock或者ReentrantReadWriteLock, 這種方法比synchronized更靈活。
使用Semaphore,允許最多n個線程同時訪問資源。
7. JVM是否了解?HashMap是線程不安全的,Hashtable是線程安全的。
HashMap的key和value接受null,Hashtable不接受。
HashMap繼承自AbstractMap,Hashtable繼承自Directory。
這里我回答了最近正在看《深入理解Java虛擬機》一書,本想著這方面的問題能答上一些的,沒想到面試官直接說
那看樣子還不是很了解,就不問這塊的問題了= =.. 心塞
但是我估摸著大概如果問的話會問:
7.2. 常用的虛擬機參數。JVM的內存一共分為5個部分:
程序計數器: 里面存放著線程執行的指令。
方法區: 存放類的信息,如:類名、方法、成員變量等,也存放著常量池。
虛擬機棧: 存放著局部變量表、操作數棧、方法出口信息等方法執行所需信息。
本地方法棧: 存放程序調用native方法的信息。
堆: 這五個部分中最大的,對象的內存分配都是在堆內存中。
7.3. 垃圾回收算法。-Xmx: 指定最大堆內存
-Xms: 指定初始化堆內存大小。
-Xmn: 指定年輕代內存初始內存大小,同時也是最大內存大小。
-XX:NewSize: 指定年輕代內存大小。
-XX:NewRatio: 指定年輕代和老年代的內存比例。
-XX:MaxHeapSize: 指定程序最大內存。
-XX:+PrintGC: 打印GC日志。
-XX:+PrintGCDetails: 打印詳細的GC日志。
-Xloggc: 打印GC日志保存位置。
7.4 類加載機制。引用計數算法:
該算法對每一個對象都有一個引用計數,沒增加一次引用就+1,減少一次引用-1,在回收時將引用計數為0的對象清理掉。這種算法簡單,但是無法解決循環引用的問題(比如: A引用B, B也引用A,但是A和B都沒有被其它任何對象引用)。標記-清除算法:
該算法分為兩個階段, 第一階段遍歷找出所有需要被回收的對象,并做上標記,第二階段對清理所有被標記的對象,這種算法效率比較低,并且會產生較多的內存碎片。標記-整理算法:
該算法的第一階段和標記-清除算法是一樣的,而第二階段它不是直接清理掉垃圾對象,而且將存活的對象往同一側移動,移動完成后清理掉另一側所有的對象。這種算法不會產生內存碎片,但是效率低下。復制算法:
該算法將內存分為兩個區域,進行垃圾回收時,就將還活著的對象復制到另一塊內存區域中,然后再將整片內存區域清空。這種算法簡單快速,而且不會產生內存碎片,但是因為將內存分成兩塊,所以可用的內存會少很多。分代收集算法:
將內存細分為多個區域,不同區域GC的頻率,并對不同的區域采用適當的收集算法。如JVM將內存分為年輕代和老年代,普通對象最開始分配在年輕代(大對象會直接分配到老年代),同一個對象在經過幾次GC后還存活著,就認為這個對象的生命周期會比較長,將其移入老年代,GC主要發生在年輕代。
Java中主要有Bootstrap類加載器、ExtClassLoader、AppClassLoader,其中Bootstrap類加載器主要加載JAVA_HOME/lib目錄下的類庫,ExtClassLoader加載JAVA_HOME/lib/ext目錄下的類庫,AppClassLoader加載classpath指向目錄下的類庫。8. MyBatis和Hibernate各有什么優缺點?Java的類加載器使用雙親委派模型,除了頂層的Bootstrap類加載器外,其余的類加載器都有父類加載器,當一個類加載器要加載一個類時,它不會直接去加載,而是委托父類加載器嘗試加載,父類加載器如果無法完成,則繼續委托其父類加載器加載,如果在期間有某一個類加載器發現已經加載過這個類,則會將已經加載的類返回,子類不再加載。若所有的類加載器都未加載過這個類,那么最開始嘗試加載的加載器才會去加載這個類。使用這樣的加載機制的好處是: 對于同一個類,如: java.lang.String,能保證整個程序中都是使用的這一個類,否則如果用戶在自己的項目中也寫了一個java.lang.String類,那么項目中將存在兩個String類,一個是java提供的String類,一個是用戶自定義的String類,不僅使項目變得混亂,而且不安全。
我個人因為只簡單接觸過而沒有實際應用過Hibernate,所以沒能從比較好的角度來回答這個問題。
Hibernate的優點是它是一個完全的ORM框架,使用Hibernate可以做到不用手寫SQL,而且無須關心使用何種數據庫,可移植性較好,當需要更變數據庫時需要做的修改很少甚至為0。其缺點是需要根據數據庫的設計在實體進行又一次的配置,且幫程序員做了太多事,如果需要進行調優的話需要對Hibernate有比較深的了解。9. MySQL平時是怎么分析效率和進行SQL優化的?
MyBatis的優缺點差不多和Hibernate相反,我們需要手寫SQL語句和配置結果集和實體類的映射,即使是簡單的單表操作也需要寫SQL(可以通過攔截器來實現CommonMapper,或者可以使用生成器來生成代碼),因此MyBatis要進行SQL調優也簡單直接。其次是MyBatis的二級緩存功能較弱,是針對namespace的。
10. MySQL除了InnoDB還有哪些引擎,有什么區別?較常使用的方法是explain SQL查看執行計劃,根據查詢計劃可以知道是否使用了索引,是否進行來全表掃描以及查詢的順序,依此我們可以建立適當的索引和連接查詢調優。
還有一個是開啟慢查詢記錄執行時間長的SQL語句。通常會在WHERE、JOIN ON和ORDER BY使用到字段上加上索引。
避免查詢時判斷NULL,否則可能會導致全表掃描。
避免使用OR來連接查詢條件,否則可能導致全表掃描,可以改用UNION或UNION ALL。
避免LIKE查詢,否則可能導致全表掃描。
不使用SELECT *,只查詢必須的字段,避免加載無用數據。
能用UNION ALL的時候就不用UNION,UNION過濾重復數據要耗費更多的cpu資源。
因為平時都是用的InnoDB,對其它引擎的了解甚少,所以這個問題沒答上= =,這里直接貼一個鏈接好了。11. 如何動態改變頁面上的元素?
相關鏈接: MySQL存儲引擎介紹
12. 分頁的實現。使用$(..).css({..})來改變元素的樣式。
使用$(..).attr(..)改變元素的屬性。
使用$(..).html(..)改變元素的html內容。
使用$(..).text(..)改變元素的文本內容。
使用$(..).remove(..)刪除元素。
使用$(..).append(..)添加元素。
如果是使用JSP等后端模板的話,一般會將需要分頁的JSP代碼抽成一個多帶帶的JSP文件,并在頁面中動態計算分頁按鈕的展示方式,在母頁中include該JSP文件,然后在前端點擊分頁按鈕時,通過AJAX請求下一頁的內容,服務器端將渲染后的HTML返回給前端,前端通過$(..).html()等方式替換展示內容。13. 解釋一下RESTful,平時是怎么用的
如果是在前后端分離的項目中,一般會使用一些前端的框架,如: React.js、Vue.js等,每次只向后臺請求分頁的數據,一般數據交互格式使用JSON,并替換已有的數據,觸發頁面內容的改變。
14. 有沒有抓過包?GET和POST格式是怎么樣的?RESTful是無狀態的,采用URL+HTTP請求方法來描述資源和行為。
一般在前后端分離的項目中,后端會提供REST接口給前端,其HTTP請求方法一般為:GET : 獲取資源。
POST: 更新資源。
PUT: 創建資源。
DELETE: 刪除資源。
其次,RESTful由于是無狀態的,一般會采用JWT或OAuth的方式來認證一個用戶,Token是保存在前端的,為了安全性一般會配合HTTPS使用。
HTTP請求分為三部分: 請求行、請求頭、請求體:15. 如果是上傳文件的話又是怎樣的?后端如何處理?
請求行: 第一行是METHOD URL protocal,如GET http://abc.com HTTP/1.1。
請求頭: 從第二行開始,每一行的內容都是一個請求頭參數值,直到遇到一個空行為止。
請求體: 請求頭和請求體中間隔著一行空行作為分界,請求體包含著本次請求攜帶的內容。
GET方式的請求沒有請求體,其是將參數追加到URL后面,URL中?后面的內容為請求參數。
POST方式則三部分都有,且POST的請求頭應當包含Content-Type來指明請求體中內容的類型。
上傳文件的話會設置Content-Type為multipart/form-data,并指定boundary的值來標識請求體中內容的分界,而在請求體中,不同的內容(如:文件A和文件B)之間使用boundary的值來標識分界,并且請求體中每部分內容都會有Content-Disposition和Content-Type來指明這部分內容的類型和信息。16. AJAX實現原理。后端的話使用ServletFileUpload來解析請求,獲得FileItem的List,遍歷Item,然后通過Item獲得輸入流,從輸入流中讀取上傳文件的數據,再構建FileOutputStream輸出到磁盤中保存。
如果使用Spring MVC,則可以在接收請求的方法中接收CommonsMultipartFile,并使用transferTo方法保存到磁盤中。
這個也沒答上來,平時都是使用jQuery封裝的AJAX或者其他AJAX框架。
AJAX是利用瀏覽器的AJAX引擎來實現的異步請求,通過XMLHttpRequest對象來發送請求,由AJAX引擎向服務器發送和接收響應,再回調給用戶處理,達到不阻塞用戶界面和無刷新的目的。17. Linux下怎么查找一個文件?
資料來源: AJAX工作原理及其優缺點。
如果是查找二進制文件,可以使用whereis。18. Linux怎么查找一個進程?
如果是查找命令,可以使用which。
如果是其他文件,可以使用find命令(其實什么都可以找), -name指定搜索的名稱或者匹配串, -maxdepth指定搜索的深度。
也可以使用locate命令查找,但是最新變動的文件可能會找不到,因為該命令實際上是搜索數據庫,該數據庫每天自動更新,可以手動執行updatedb更新。
使用ps命令可以查看進程狀態,ps -ef查看所有進程,配合grep命令可以進行篩選, 如查看tomcat進程的命令是: ps -ef | grep tomcat。19. Linux下只知道文件所在目錄和內容,如何查找文件?
這題沒也沒答上= =
使用grep命令可以實現:20. Redis你用它來做什么?
grep -rn /path/to/target/dir -e "pattern"
-r: 遞歸
-n: 顯示行數
-w: 完全匹配
例子: grep -rn. -e "ERROR"
輸出: ./面試:143:輸出: ./面試:144:上面的命令搜索當前目錄及其子目錄中的文件,并輸出含有ERROR內容的行
詳細答案及來源:How to find all files containing specific text on Linux?
21. Redis如果運行過程中崩潰了怎么辦。Redis在我接觸過的項目中主要做了兩件事:
緩存。
存儲需要計算的信息。
Redis也可以用來做消息訂閱、隊列等。
這個問題我估摸著面試官想問的是Redis的數據保障的方法,不然崩潰了除了重啟還能怎么辦?
Redis有提供數據持久化的功能,一種是快照,一種是AOF。22. Redis集群。
快照是在某一個時間點將所有數據寫入到磁盤中,AOF是將被執行的命令復制到硬盤中,快照的文件體積要比AOF的文件體積小。前者在恢復時速度比后者快,但是因為是間隔持久化,所以會有一定量的數據丟失。后者因為是實時寫入的,所以數據的完整性比較好,如果丟失的話一般也就丟失一秒的數據。其次需要做主從復制,這樣一份數據可以保存在多臺服務器上,且可以避免Redis崩潰到重啟完成這段時間內無法提供正常服務,同時從服務器可以分擔主服務器的讀壓力。
沒配置過所以沒答上= =
相關連接: Redis集群教程。23. 剩下的問題都是偏向個人的,沒有什么通用性的回答,大概問了我:
最后前一家公司實習的時候主要做什么?
講一下做過的項目?
項目中有沒有遇到什么難點?怎么解決的?
有沒有做過什么有亮點的東西?
其中在問題3根據我的回答,繼續將情況復雜化讓我給出解決方案,一步一步問。
最后. 如果不是熟悉的技術真的不要往簡歷上寫= = 我因為在項目需要,學習過Android,但是項目完成后就
沒碰過了(近一年),把對Android有一定的了解寫上簡歷,結果問了三個問題就答不上了= =
雖然最終拿到了offer,但是因為各方面原因,最后還是放棄了,在此也提醒一下,秋招千萬不要錯過= =,拖到這個時候,好的實習的真不好找(成都)。
學習技術不能知其然而不知其所以然,日后不僅會持續更新面試內容,同時本專欄會持續發布Java、數據庫、Linux、算法等方面的學習文章。歡迎關注。
最后,如有錯誤或不適合的,請大家評論點出,共同進步,謝謝!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65202.html
摘要:來自朋友去某信用卡管家的做的一道面試題,用原生模擬的方法,不準用和方法。他們的用途相同,都是在特定的作用域中調用函數。不同之處在于,方法傳遞給調用函數的參數是逐個列出的,而則是要寫在數組中。 本文首發我的個人博客:前端小密圈,評論交流送1024邀請碼,嘿嘿嘿?。 來自朋友去某信用卡管家的做的一道面試題,用原生JavaScript模擬ES5的bind方法,不準用call和bind方法。 ...
摘要:來自朋友去某信用卡管家的做的一道面試題,用原生模擬的方法,不準用和方法。他們的用途相同,都是在特定的作用域中調用函數。不同之處在于,方法傳遞給調用函數的參數是逐個列出的,而則是要寫在數組中。 本文首發我的個人博客:前端小密圈,評論交流送1024邀請碼,嘿嘿嘿?。 來自朋友去某信用卡管家的做的一道面試題,用原生JavaScript模擬ES5的bind方法,不準用call和bind方法。 ...
摘要:先介紹一下本人應屆前端開發一枚,非科班出身,專業是化學,大學期間開始自學前端開發,在今年春招實習和秋招的時候投了一些公司,拿到一些京東拼多多虎牙等,總體來說還算滿意,特地寫一篇文章來總結一下面試的那些套路。 showImg(https://segmentfault.com/img/remote/1460000011897700); 先介紹一下本人應屆前端開發一枚,非科班出身,專業是化學...
摘要:先介紹一下本人應屆前端開發一枚,非科班出身,專業是化學,大學期間開始自學前端開發,在今年春招實習和秋招的時候投了一些公司,拿到一些京東拼多多虎牙等,總體來說還算滿意,特地寫一篇文章來總結一下面試的那些套路。 showImg(https://segmentfault.com/img/remote/1460000011897700); 先介紹一下本人應屆前端開發一枚,非科班出身,專業是化學...
閱讀 535·2019-08-30 15:55
閱讀 944·2019-08-29 15:35
閱讀 1198·2019-08-29 13:48
閱讀 1910·2019-08-26 13:29
閱讀 2933·2019-08-23 18:26
閱讀 1237·2019-08-23 18:20
閱讀 2834·2019-08-23 16:43
閱讀 2709·2019-08-23 15:58