2019-09-09 7087瀏覽量
簡介: 從前幾篇分享中能夠看出吧趣,阿里不愧是“Java技術(shù)光明頂”萌丈,無論是從Java方向的面經(jīng)數(shù)量撵渡、質(zhì)量,還是問題難度上來看颊咬,想要拿到阿里Java研發(fā)崗位的Offer务甥,都需要面試者擁有對于Java相關(guān)基礎(chǔ)知識的深厚“內(nèi)功”。本文中為大家匯總了部分阿里巴巴Java方向面試中的常見問題喳篇,希望能夠幫助大家查漏補(bǔ)缺敞临。
“我是面小易,機(jī)智又聰明麸澜。面試不眨眼挺尿,Offer不手軟〈栋睿”
我面小易又來啦编矾,今天要和大家一起分享的是阿里巴巴Java方向面試中的一些常見問題,涉及了從Java內(nèi)置的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)馁害、常用的服務(wù)器知識窄俏、Java網(wǎng)絡(luò)編程相關(guān)的知識,再到Java的內(nèi)存模型碘菜、Java常用編程框架等各個方面的內(nèi)容凹蜈,希望能夠幫助大家回顧Java的基礎(chǔ)內(nèi)容限寞,進(jìn)而查漏補(bǔ)缺,完善自身的知識體系踪区。
以下為正文
一昆烁、String, StringBuffer, StringBuilder的區(qū)別是什么?String為什么是不可變的缎岗?
1静尼、String是字符串常量,StringBuffer和StringBuilder都是字符串變量传泊。后兩者的字符內(nèi)容可變鼠渺,而前者創(chuàng)建后內(nèi)容不可變。
2眷细、String不可變是因為在JDK中String類被聲明為一個final類拦盹。
3、StringBuffer是線程安全的溪椎,而StringBuilder是非線程安全的普舆。
補(bǔ)充說明:線程安全會帶來額外的系統(tǒng)開銷,所以StringBuilder的效率比StringBuffer高校读。如果對系統(tǒng)中的線程是否安全很掌握沼侣,可用StringBuffer,在線程不安全處加上關(guān)鍵字Synchronize歉秫。
二蛾洛、Vector, ArrayList, LinkedList的區(qū)別是什么?
1雁芙、Vector轧膘、ArrayList都是以類似數(shù)組的形式存儲在內(nèi)存中,LinkedList則以鏈表的形式進(jìn)行存儲兔甘。
2谎碍、List中的元素有序、允許有重復(fù)的元素裂明,Set中的元素?zé)o序椿浓、不允許有重復(fù)元素。
3闽晦、Vector線程同步,ArrayList提岔、LinkedList線程不同步仙蛉。
4、LinkedList適合指定位置插入碱蒙、刪除操作荠瘪,不適合查找夯巷;ArrayList、Vector適合查找哀墓,不適合指定位置的插入趁餐、刪除操作。
5篮绰、ArrayList在元素填滿容器時會自動擴(kuò)充容器大小的約50%后雷,而Vector則是100%,因此ArrayList更節(jié)省空間吠各。
三臀突、HashTable, HashMap, TreeMap的區(qū)別是什么贾漏?
1候学、HashTable線程同步,HashMap非線程同步纵散。
2梳码、HashTable不允許<鍵,值>有空值,HashMap允許<鍵,值>有空值伍掀。
3掰茶、HashTable使用Enumeration,HashMap使用Iterator硕盹。
4符匾、HashTable中hash數(shù)組的默認(rèn)大小是11,增加方式的old*2+1瘩例,HashMap中hash數(shù)組的默認(rèn)大小是16啊胶,增長方式一定是2的指數(shù)倍。
5垛贤、TreeMap能夠把它保存的記錄根據(jù)鍵排序焰坪,默認(rèn)是按升序排序。
面小易說:以上三個問題所涉及的都是Java語言中的一些比較高級的數(shù)據(jù)結(jié)構(gòu)聘惦,從字符串相關(guān)到容器再到哈希表和樹等數(shù)據(jù)結(jié)構(gòu)某饰,因此我們在學(xué)習(xí)Java語言的時候,也需要更加深入地去對比比較類似的數(shù)據(jù)結(jié)構(gòu)的使用場景以及其優(yōu)缺點善绎。
四黔漂、Tomcat,Apache禀酱,JBoss的區(qū)別炬守?
1、Apache是HTTP服務(wù)器剂跟,Tomcat是Web服務(wù)器减途,JBoss是應(yīng)用服務(wù)器酣藻。
2、Apache解析靜態(tài)的Html文件鳍置;Tomcat可解析jsp動態(tài)頁面辽剧、也可充當(dāng)
容器。
面小易說:對于服務(wù)器而言税产,在面試中可能并不會過多涉及怕轿,相對而言,面小易認(rèn)為像是Liunx砖第、Tomcat這些背后的原理可能更受面試官的青睞撤卢。
五、GET梧兼,POST請求之間的區(qū)別放吩?
基礎(chǔ)知識:HTTP的請求格式如下。
主要包含三個信息:1羽杰、請求的類型(GET或POST)渡紫,2、要訪問的資源(如resimga.jif)考赛,3惕澎、HTTP版本(http/1.1)
區(qū)別:
1、Get是從服務(wù)器端獲取數(shù)據(jù)颜骤,Post則是向服務(wù)器端發(fā)送數(shù)據(jù)唧喉。
2、在客戶端忍抽,Get方式通過URL提交數(shù)據(jù)八孝,在URL地址欄可以看到請求消息,該消息被編碼過鸠项;Post數(shù)據(jù)則是放在Html header內(nèi)提交干跛。
3、對于Get方式祟绊,服務(wù)器端用Request.QueryString獲取變量的值楼入;對用Post方式,服務(wù)器端用Request.Form獲取提交的數(shù)據(jù)值牧抽。
4嘉熊、Get方式提交的數(shù)據(jù)最多1024字節(jié),而Post則沒有限制扬舒。
5记舆、Get方式提交的參數(shù)及參數(shù)值會在地址欄顯示,不安全呼巴,而Post不會泽腮,比較安全。
六衣赶、Session, Cookie的區(qū)別是什么诊赊?
1、Session由應(yīng)用服務(wù)器維護(hù)的一個服務(wù)器端的存儲空間府瞄;Cookie是客戶端的存儲空間碧磅,由瀏覽器維護(hù)。
2遵馆、用戶可以通過瀏覽器設(shè)置決定是否保存Cookie鲸郊,而不能決定是否保存Session,因為Session是由服務(wù)器端維護(hù)的货邓。
3秆撮、Session中保存的是對象,Cookie中保存的是字符串换况。
4职辨、Session和Cookie不能跨窗口使用,每打開一個瀏覽器系統(tǒng)會賦予一個SessionID戈二,此時的SessionID不同舒裤,若要完成跨瀏覽器訪問數(shù)據(jù),可以使用 Application觉吭。
5腾供、Session、Cookie都有失效時間鲜滩,過期后會自動刪除伴鳖,減少系統(tǒng)開銷。
七绒北、HTTP 報文包含內(nèi)容
主要包含四部分:
1黎侈、request line
2、header line
3闷游、blank line
4峻汉、request body
面小易說:上面的三個問題是網(wǎng)絡(luò)編程的基礎(chǔ)知識問題,作為Java工程師也需要掌握HTTP的知識脐往,而如今HTTPS同樣也成為了標(biāo)準(zhǔn)休吠,也需要大家進(jìn)一步了解。此外业簿,相對于大家在課本或者課堂中所學(xué)習(xí)的HTTP 1.0/1.1這些協(xié)議而言瘤礁,很多公司已經(jīng)邁入了HTTP 2.0時代,因此兩者之間的差別也需要我們進(jìn)一步了解梅尤。
八柜思、Servlet的生命周期
大致分為4部:Servlet類加載–>實例化–>服務(wù)–>銷毀
Tomcat中Servlet的時序圖如下所示:
1岩调、Web Client向Servlet容器(Tomcat)發(fā)出HTTP請求。
2赡盘、Servlet容器接收Client端的請求号枕。
3、Servlet容器創(chuàng)建一個HttpRequest對象陨享,將Client的請求信息封裝到這個對象中葱淳。
4、Servlet創(chuàng)建一個HttpResponse對象抛姑。
5赞厕、Servlet調(diào)用HttpServlet對象的service方法,把HttpRequest對象和HttpResponse對象作為參數(shù)傳遞給HttpServlet對象中定硝。
6皿桑、HttpServlet調(diào)用HttpRequest對象的方法,獲取Http請求喷斋,并進(jìn)行相應(yīng)處理唁毒。
7、處理完成HttpServlet調(diào)用HttpResponse對象的方法星爪,返回響應(yīng)數(shù)據(jù)浆西。
8、Servlet容器把HttpServlet的響應(yīng)結(jié)果傳回客戶端顽腾。
其中的3個方法說明了Servlet的生命周期:
1近零、init():負(fù)責(zé)初始化Servlet對象。
2抄肖、service():負(fù)責(zé)響應(yīng)客戶端請求久信。
3、destroy():當(dāng)Servlet對象推出時漓摩,負(fù)責(zé)釋放占用資源裙士。
九、Statement與PreparedStatement的區(qū)別,什么是SQL注入管毙,如何防止SQL注入腿椎?
1、PreparedStatement支持動態(tài)設(shè)置參數(shù)夭咬,Statement不支持啃炸。
2、PreparedStatement可避免如類似 單引號 的編碼麻煩卓舵,Statement不可以南用。
3、PreparedStatement支持預(yù)編譯,Statement不支持裹虫。
4肿嘲、在SQL語句出錯時PreparedStatement不易檢查,而Statement則更便于查錯恒界。
5睦刃、PreparedStatement可防止SQL助于,更加安全十酣,而Statement不行。
補(bǔ)充說明-什么是SQL注入以及應(yīng)對策略: 通過SQL語句的拼接達(dá)到無參數(shù)查詢數(shù)據(jù)庫數(shù)據(jù)目的的方法际长。如將要執(zhí)行的SQL語句為 select * from table where name = “+appName+”耸采,利用appName參數(shù)值的輸入,來生成惡意的SQL語句工育,如將[‘or’1’=‘1’] 傳入可在數(shù)據(jù)庫中執(zhí)行虾宇。因此可以采用PrepareStatement來避免SQL注入,在服務(wù)器端接收參數(shù)數(shù)據(jù)后如绸,進(jìn)行驗證嘱朽,此時PrepareStatement會自動檢測,而Statement不行怔接,需要手工檢測搪泳。
十、sendRedirect, foward區(qū)別
1扼脐、foward是服務(wù)器端控制頁面轉(zhuǎn)向岸军,在客戶端的瀏覽器地址中不會顯示轉(zhuǎn)向后的地址;sendRedirect則是完全的跳轉(zhuǎn)瓦侮,瀏覽器中會顯示跳轉(zhuǎn)的地址并重新發(fā)送請求鏈接。原理:forward是服務(wù)器請求資源,服務(wù)器直接訪問目標(biāo)地址的URL荒叼,把那個URL的響應(yīng)內(nèi)容讀取過來荤崇,然后再將這些內(nèi)容返回給瀏覽器,瀏覽器根本不知道服務(wù)器發(fā)送的這些內(nèi)容是從哪來的罚攀,所以地址欄還是原來的地址党觅。
2、redirect是服務(wù)器端根據(jù)邏輯坞生,發(fā)送一個狀態(tài)碼仔役,告訴瀏覽器重新去請求的那個地址,瀏覽器會用剛才的所有參數(shù)重新發(fā)送新的請求是己。
面小易說:以上的三個問題在之前網(wǎng)絡(luò)相關(guān)的知識上更進(jìn)一步又兵,上升到了Java網(wǎng)絡(luò)編程的相關(guān)知識,這部分意在考察面試者對于Java網(wǎng)絡(luò)編程相關(guān)知識的掌握程度。
十一沛厨、談?wù)凥ibernate的理解宙地,一級和二級緩存的作用,在項目中Hibernate都是怎么使用緩存的逆皮?
Hibernate是一個開發(fā)的對象關(guān)系映射框架(ORM)宅粥。它對JDBC進(jìn)行了非常對象封裝,Hibernate允許程序員采用面向?qū)ο蟮姆绞絹聿僮麝P(guān)系數(shù)據(jù)庫电谣。
Hibernate的優(yōu)點:
1秽梅、程序更加面向?qū)ο?br>
2、提高了生產(chǎn)率
3剿牺、方便移植
4企垦、無入侵性
Hibernate的缺點:
1、效率比JDBC略差
2晒来、不適合批量操作
3钞诡、只能配置一種關(guān)聯(lián)關(guān)系
Hibernate有四種查詢方式:
1、get湃崩、load方法荧降,根據(jù)ID號查詢對象。
2攒读、Hibernate Query Language, HQL
3朵诫、標(biāo)準(zhǔn)查詢語言
4、通過SQL查詢
Hibernate工作原理:
1整陌、配置Hibernate對象關(guān)系映射文件拗窃、啟動服務(wù)器
2、服務(wù)器通過實例化Configuration對象泌辫,讀取hibernate.cfg.xml文件的配置內(nèi)容随夸,并根據(jù)相關(guān)的需求建好表以及表之間的映射關(guān)系。
3震放、通過實例化的Configuration對象建立SessionFactory實例宾毒,通過SessionFactory實例創(chuàng)建Session對象。
4殿遂、通過Session對象完成數(shù)據(jù)庫的增刪改查操作诈铛。
Hibernate中的狀態(tài)轉(zhuǎn)移:
臨時狀態(tài)(Transient)
1、不處于Session緩存中
2墨礁、數(shù)據(jù)庫中沒有對象記錄
補(bǔ)充說明-Java是如何進(jìn)入臨時狀態(tài)的:1幢竹、通過new語句創(chuàng)建一個對象時。2恩静、剛調(diào)用Session的delete()方法時焕毫,從Session緩存中刪除一個對象時蹲坷。
持久化狀態(tài)(Persisted)
1、處于Session緩存中
2邑飒、持久化對象數(shù)據(jù)庫中沒有對象記錄
3循签、Session在特定的時刻會保存兩者同步
補(bǔ)充說明-Java如何進(jìn)入持久化狀態(tài):1、Session的save()方法疙咸。2县匠、Session的load().get()方法返回的對象。3撒轮、Session的find()方法返回的list集合中存放的對象乞旦。4、Session的update().save()方法腔召。
流離狀態(tài)(Detached)
1杆查、不再位于Session緩存中
2、游離對象由持久化狀態(tài)轉(zhuǎn)變而來臀蛛,數(shù)據(jù)庫中還沒有相應(yīng)記錄。
補(bǔ)充說明-Java如何進(jìn)入流離狀態(tài):1崖蜜、Session的close()浊仆。2、 Session的evict()方法豫领,從緩存中刪除一個對象抡柿。
具體如下圖所示:
Hibernate中的緩存主要有Session緩存(一級緩存)和SessionFactory緩存(二級緩存,一般由第三方提供)等恐。
十二洲劣、談?wù)凥ibernate與iBatis的區(qū)別,哪個性能會更高一些
1课蔬、Hibernate偏向于對象的操作達(dá)到數(shù)據(jù)庫相關(guān)操作的目的囱稽;而iBatis更偏向于SQL語句的優(yōu)化。
2二跋、Hibernate的使用的查詢語句是自己的HQL战惊,而iBatis則是標(biāo)準(zhǔn)的SQL語句。
3扎即、Hibernate相對復(fù)雜吞获,不易學(xué)習(xí);iBatis類似SQL語句谚鄙,簡單易學(xué)各拷。
性能方面:
1、如果系統(tǒng)數(shù)據(jù)處理量巨大闷营,性能要求極為苛刻時烤黍,往往需要人工編寫高性能的SQL語句或存錯過程,此時iBatis具有更好的可控性,因此性能優(yōu)于Hibernate蚊荣。
2初狰、同樣的需求下,由于Hibernate可以自動生成HQL語句互例,而iBatis需要手動寫SQL語句奢入,此時采用Hibernate的效率高于iBatis。
十三媳叨、對Spring的理解腥光,項目中都用什么?怎么用的糊秆?對IOC武福、和AOP的理解及實現(xiàn)原理。
Spring是一個開源框架痘番,處于MVC模式中的控制層捉片,它能應(yīng)對需求快速的變化,其主要原因它有一種面向切面編程(AOP)的優(yōu)勢汞舱,其次它提升了系統(tǒng)性能伍纫,因為通過依賴倒置機(jī)制(IOC),系統(tǒng)中用到的對象不是在系統(tǒng)加載時就全部實例化昂芜,而是在調(diào)用到這個類時才會實例化該類的對象莹规,從而提升了系統(tǒng)性能。這兩個優(yōu)秀的性能使得Spring受到許多J2EE公司的青睞泌神,如阿里中使用最多的也是Spring相關(guān)技術(shù)良漱。
Spring的優(yōu)點:
1、降低了組件之間的耦合性欢际,實現(xiàn)了軟件各層之間的解耦母市。
2、可以使用容易提供的眾多服務(wù)幼苛,如事務(wù)管理窒篱,消息服務(wù),日志記錄等舶沿。
3墙杯、容器提供了AOP技術(shù),利用它很容易實現(xiàn)如權(quán)限攔截括荡、運行期監(jiān)控等功能高镐。
Spring中AOP技術(shù)是設(shè)計模式中的動態(tài)代理模式。只需實現(xiàn)jdk提供的動態(tài)代理接口InvocationHandler畸冲,所有被代理對象的方法都由InvocationHandler接管實際的處理任務(wù)嫉髓。面向切面編程中還要理解切入點观腊、切面、通知算行、織入等概念梧油。
Spring中IOC則利用了Java強(qiáng)大的反射機(jī)制來實現(xiàn)。所謂依賴注入即組件之間的依賴關(guān)系由容器在運行期決定州邢。其中依賴注入的方法有兩種儡陨,通過構(gòu)造函數(shù)注入,通過set方法進(jìn)行注入量淌。
十四骗村、描述Struts的工作流程
1、在web應(yīng)用啟動時呀枢,加載并初始化ActionServlet胚股,ActionServlet從struts-config.xml文件中讀取配置信息,將它們存放到各個配置對象中裙秋。
2琅拌、當(dāng)ActionServlet接收到一個客戶請求時,首先檢索和用戶請求相匹配的ActionMapping實例摘刑,如果不存在财忽,就返回用戶請求路徑無效信息。
3泣侮、如果ActionForm實例不存在,就創(chuàng)建一個ActionForm對象紧唱,把客戶提交的表單數(shù)據(jù)保存到ActionForm對象中活尊。
4、根據(jù)配置信息決定是否需要驗證表單漏益,如果需要蛹锰,就調(diào)用ActionForm的validate()方法,如果ActionForm的validate()方法返回null或返回一個不包含ActionMessage的ActionErrors對象绰疤,就表示表單驗證成功铜犬。
5、ActionServlet根據(jù)ActionMapping實例包含的映射信息決定請求轉(zhuǎn)發(fā)給哪個Action轻庆,如果相應(yīng)的Action實例不存在癣猾,就先創(chuàng)建一個實例,然后調(diào)用Action的execute()方法余爆。
面小易說:以上部分的相關(guān)問題考察面試者在實際軟件開發(fā)中所使用的Java語言相關(guān)框架以及對于框架原理的了解程度纷宇,這一部分我們需要注意一些常見的框架,不僅需要知道它們是干什么的蛾方,還需要知道它們背后的原理像捶,常會問到的框架有Spring Boot/Spring Cloud全家桶上陕、Hibernate、MyBaits拓春、Netty释簿、Kafka等,最重要的還有阿里巴巴開源的Apache Dubbo框架硼莽。
十五庶溶、關(guān)于Java內(nèi)存模型,一個對象(兩個屬性沉删,四個方法)實例化100次渐尿,現(xiàn)在內(nèi)存中的存儲狀態(tài),幾個對象矾瑰,幾個屬性砖茸,幾個方法。由于Java中new出來的對象都是放在堆中殴穴,所以如果要實例化100次凉夯,將在堆中產(chǎn)生100個對象,一般對象與其中的屬性采幌、方法都屬于一個整體劲够,但如果 屬性和方法是靜態(tài)的,就是用static關(guān)鍵字聲明的休傍,那么屬于類的屬性和方法永遠(yuǎn)只在內(nèi)存中存在一份征绎。
十六、反射講一講磨取,主要是概念,都在哪需要反射機(jī)制人柿,反射的性能,如何優(yōu)化忙厌?
反射機(jī)制的定義:
是在運行狀態(tài)中凫岖,對于任意的一個類,都能夠知道這個類的所有屬性和方法逢净,對任意一個對象都能夠通過反射機(jī)制調(diào)用一個類的任意方法哥放,這種動態(tài)獲取類信息及動態(tài)調(diào)用類對象方法的功能稱為java的反射機(jī)制。
反射的作用:
1爹土、動態(tài)地創(chuàng)建類的實例甥雕,將類綁定到現(xiàn)有的對象中,或從現(xiàn)有的對象中獲取類型着饥。
2犀农、應(yīng)用程序需要在運行時從某個特定的程序集中載入一個特定的類。
十七宰掉、線程同步呵哨,并發(fā)操作怎么控制赁濒?
Java中可在方法名前加關(guān)鍵字syschronized來處理當(dāng)有多個線程同時訪問共享資源時候的問題。syschronized相當(dāng)于一把鎖孟害,當(dāng)有申請者申請該資源時拒炎,如果該資源沒有被占用,那么將資源交付給這個申請者使用挨务,在此期間击你,其他申請者只能申請而不能使用該資源,當(dāng)該資源被使用完成后將釋放該資源上的鎖谎柄,其他申請者可申請使用丁侄。并發(fā)控制主要是為了多線程操作時帶來的資源讀寫問題。如果不加以空間可能會出現(xiàn)死鎖朝巫,讀臟數(shù)據(jù)鸿摇、不可重復(fù)讀、丟失更新等異常劈猿。
并發(fā)操作可以通過加鎖的方式進(jìn)行控制拙吉,鎖又可分為樂觀鎖和悲觀鎖。
悲觀鎖:
悲觀鎖并發(fā)模式假定系統(tǒng)中存在足夠多的數(shù)據(jù)修改操作揪荣,以致于任何確定的讀操作都可能會受到由個別的用戶所制造的數(shù)據(jù)修改的影響筷黔。也就是說悲觀鎖假定沖突總會發(fā)生,通過獨占正在被讀取的數(shù)據(jù)來避免沖突仗颈。但是獨占數(shù)據(jù)會導(dǎo)致其他進(jìn)程無法修改該數(shù)據(jù)佛舱,進(jìn)而產(chǎn)生阻塞,讀數(shù)據(jù)和寫數(shù)據(jù)會相互阻塞挨决。
樂觀鎖:
樂觀鎖假定系統(tǒng)的數(shù)據(jù)修改只會產(chǎn)生非常少的沖突名眉,也就是說任何進(jìn)程都不大可能修改別的進(jìn)程正在訪問的數(shù)據(jù)。樂觀并發(fā)模式下凰棉,讀數(shù)據(jù)和寫數(shù)據(jù)之間不會發(fā)生沖突,只有寫數(shù)據(jù)與寫數(shù)據(jù)之間會發(fā)生沖突陌粹。即讀數(shù)據(jù)不會產(chǎn)生阻塞撒犀,只有寫數(shù)據(jù)才會產(chǎn)生阻塞。
面小易說:最后的幾個問題又回到了Java內(nèi)存模型以及進(jìn)程掏秩、線程的底層知識上或舞,其實無論是對于Java網(wǎng)絡(luò)編程也好,還是對于Java框架的使用也好蒙幻,這都離不開Java語言底層的技術(shù)支撐映凳,因此了解底層知識是做好優(yōu)化的重中之重。