前言:
我想每個(gè)程序員比較頭疼的事情都是:工作擰螺絲,面試造火箭吧。但是又必須經(jīng)歷這個(gè)過(guò)程,尤其是弄不清面試官問(wèn)的問(wèn)題,如果你準(zhǔn)備的不是很充分,會(huì)導(dǎo)致面試的時(shí)候手足無(wú)措。今天這篇文章是從已工作5年的程序員面試幾十次中挑選的面試概率比較大的一些題目,都是大家被問(wèn)到過(guò)的(就是這么自信),希望這篇文章能夠?qū)Υ蠹艺夜ぷ饔兴鶐椭?/p>
基礎(chǔ)部分
一丶抽象類和接口的區(qū)別
1.語(yǔ)法區(qū)別
(1)抽象類可以有構(gòu)造方法,接口不能有構(gòu)造方法;
(2)抽象類中可以有普通成員變量,接口中沒有普通成員變量;
(3)抽象類中可以有非抽象的方法,接口中的方法都必須是抽象的;
(4)抽象類中的方法可以是public,protected類型,接口中的方法只能是public類型的,切 默認(rèn)為public abstract類型;
(5)抽象類中可以有靜態(tài)方法,接口中不能有靜態(tài)方法;
(6)抽象類中的靜態(tài)變量訪問(wèn)類型可以是任意的,但接口中的靜態(tài)變量只能是public static final 類型。
(7).一個(gè)類可以實(shí)現(xiàn)多個(gè)接口,但一個(gè)類只能繼承一個(gè)抽象類;
2.應(yīng)用區(qū)別
接口更多是在系統(tǒng)架構(gòu)方面發(fā)揮作用,主要用于定義模塊之間的通信契約;而抽象類在代碼方法 發(fā)揮作用,可以使用代碼塊的重用;
二丶Java中接口可不可以繼承一般類,為什么?
不可以因?yàn)榻涌谥兄荒艹霈F(xiàn)3種成員:
1.公共的靜態(tài)常量(public static final )
2.公共的抽象方法(public abstract )
3.靜態(tài)內(nèi)部類(static class)
而一個(gè)類中,就算什么都不寫,也必須帶一個(gè)構(gòu)造方法,在extends時(shí)就會(huì)被子類繼承,如果是接口也會(huì) 繼承這個(gè)構(gòu)造方法,很明顯構(gòu)造方法不在上面三項(xiàng)之列
而如果類中有一般的方法和成員變量,也會(huì)被子類全部繼承,這些更不能出現(xiàn)在接口中了,所以接口是絕 對(duì)不可能繼承一個(gè)類的
三、基本數(shù)據(jù)類型的默認(rèn)值?基本數(shù)據(jù)類型所占的字節(jié)
1. 默認(rèn)值
(1)byte、short、int、long的默認(rèn)值為0
(2)float、double默認(rèn)值為0.0
(3)char默認(rèn)值為空
(4)boolean默認(rèn)值為false
2.所占字節(jié)
(1)byte 1個(gè)字節(jié)
(2)short 2個(gè)字節(jié)
(3)char 2個(gè)字節(jié)
(4)int 4個(gè)字節(jié)
(5)long 8個(gè)字節(jié)
(6)float 4個(gè)字節(jié)
(7)double 8個(gè)字節(jié)
四丶String屬于那個(gè)類,以及常用的方法
1.java.lang.string
2.substring(),indexOf(),concat(),endswith(),length(),replace()
五丶熟悉的網(wǎng)絡(luò)協(xié)議
1.TCP/IP協(xié)議是一種面向連接的、可靠的協(xié)議。
TCP/IP協(xié)議中的四層分別是應(yīng)用層、傳輸層、網(wǎng)絡(luò)層和鏈路層,每層分別負(fù)責(zé)不同的通信功能,接下來(lái)針對(duì)這四層進(jìn)行詳細(xì)地講解。
鏈路層:用于定義物理傳輸通道,通常是對(duì)某些網(wǎng)絡(luò)連接設(shè)備的驅(qū)動(dòng)協(xié)議,例如針對(duì)光纖、網(wǎng)線提供的驅(qū)動(dòng)。
網(wǎng)絡(luò)層:網(wǎng)絡(luò)層是整個(gè)TCP/IP協(xié)議的核心,它主要用于將傳輸?shù)臄?shù)據(jù)進(jìn)行分組,將分組數(shù)據(jù)發(fā)送到目標(biāo)計(jì)算機(jī)或者網(wǎng)絡(luò)。
傳輸層:主要使網(wǎng)絡(luò)程序進(jìn)行通信,在進(jìn)行網(wǎng)絡(luò)通信時(shí),可以采用TCP協(xié)議,也可以采用UDP協(xié)議。
應(yīng)用層:主要負(fù)責(zé)應(yīng)用程序的協(xié)議,例如HTTP協(xié)議、FTP協(xié)議等。
2.FTP 文件傳輸協(xié)議,允許在網(wǎng)絡(luò)上傳輸文件。
六、String、StringBuffer、StringBuilder
String的值是不可改變的,這就導(dǎo)致每次對(duì)String的操作都會(huì)生成新的String對(duì)象,不禁效率底下, 而且浪費(fèi)大量的內(nèi)存空間;StringBuilder是可變類,任何對(duì)他指向的字符串的操作都不會(huì)產(chǎn)生新的對(duì) 象,但單線程不安全;StringBuffer底層方法使用了synchronized關(guān)鍵字,線程比較安全,但效率 較StringBuilder慢;
七、設(shè)計(jì)模式
單例模式:某個(gè)類只能有一個(gè)實(shí)例,提供一個(gè)全局的訪問(wèn)點(diǎn);
工廠模式:定義一個(gè)創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化那個(gè)類;
代理模式:為其他對(duì)象提供一個(gè)代理以便控制這個(gè)對(duì)象的訪問(wèn);
八、高并發(fā)如何處理?
1.從最基礎(chǔ)的地方做起,優(yōu)化我們寫的代碼,減少必要的資源浪費(fèi)。
a.避免頻繁的new對(duì)象,對(duì)于整個(gè)程序只需要一個(gè)實(shí)例的類,我們可以使用單例模式;對(duì)于String 鏈接操作,使用StringBuffer或StringBuilder,對(duì)于工具類可以通過(guò)靜態(tài)方法來(lái)訪問(wèn);
b.避免使用錯(cuò)誤的方式,使用java中高效率的類,比如ArrayList比Vector性能好;
2.html靜態(tài)化
把一些經(jīng)常不改變的內(nèi)容靜態(tài)化,高并發(fā)時(shí)減少服務(wù)器的壓力;
3.圖片服務(wù)器分離
對(duì)于web服務(wù)器來(lái)說(shuō),圖片是最消耗資源的,于是我們把圖片放到獨(dú)立的服務(wù)器,這樣可以降低 頁(yè)面請(qǐng)求服務(wù)器的系統(tǒng)壓力;
4.緩存
避免每一次都去數(shù)據(jù)庫(kù)中去查詢,減少數(shù)據(jù)庫(kù)的訪問(wèn)量;并且使用redis數(shù)據(jù)庫(kù)來(lái)做緩存,它的 讀寫速度是非常快的;
5.數(shù)據(jù)庫(kù)優(yōu)化
(1)優(yōu)化sql語(yǔ)句
a.Select語(yǔ)句必須指定列名
b.當(dāng)查詢結(jié)果為一條時(shí),使用limit 1
c.避免使用%前綴搜索,避免全表掃描
九、get與post的區(qū)別
GET在瀏覽器回退時(shí)是無(wú)害的,而POST會(huì)再次提交請(qǐng)求。 GET產(chǎn)生的URL地址可以被Bookmark,而POST不可以。 GET請(qǐng)求會(huì)被瀏覽器主動(dòng)cache,而POST不會(huì),除非手動(dòng)設(shè)GET請(qǐng)求只能進(jìn)行url編碼,而POST支持多種編碼方式。 GET請(qǐng)求參數(shù)會(huì)被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會(huì)被保留。 GET請(qǐng)求在URL中傳送的參數(shù)是有長(zhǎng)度限制的,而POST么有。 對(duì)參數(shù)的數(shù)據(jù)類型,GET只接受ASCII字符,而POST沒有限制。 GET比POST更不安全,因?yàn)閰?shù)直接暴露在URL上,所以不能用來(lái)傳遞敏感信息。 GET參數(shù)通過(guò)URL傳遞,POST放在Request body中。
十、JDK1.8新特性
提供lambda表達(dá)式極大地減少了代碼的冗余;
在接口中可以使用default和static關(guān)鍵字來(lái)修飾接口中的普通方法;
提供新的API LocalDate | LocalTime | LocalDateTime
(1)Java.util.Date和SimpleDateFormatter線程上都不安全,而LocalDate和LocalTime和 String一樣都是不可改變類,線程上比較安全,還不能修改;
(2)Java.util.Date月份從0開始,12月是11,而java.time.LocalDate月份和星期都改成了 enum, 就不可能出錯(cuò)了;
集合部分
一、List、Map、Set三個(gè)接口,存取元素時(shí),各有什么特點(diǎn)
(1)Set集合的add有一個(gè)boolean類型的返回值,當(dāng)集合中沒有某個(gè)元素時(shí),則可以成功加入該 元素,返回結(jié)果為true;當(dāng)集合中存在與某個(gè)元素equals方法相等 的元素時(shí),則無(wú)法加入該元素, 取元素時(shí)只能用Iterator接口取得所有元素,在逐一遍歷各個(gè)元素;
(2)List表示有先后順序的集合,調(diào)用add()方法,指定當(dāng)前對(duì)象在集合中的存放位置;一個(gè)對(duì)象可 以被反復(fù)存進(jìn)集合中;每調(diào)用一次add()方法,該對(duì)象就會(huì)被插入集合中一次,其實(shí),并不是把對(duì) 象本身存進(jìn)了集合中,而是在集合中使用一個(gè)索引變量指向了該對(duì)象,當(dāng)一個(gè)對(duì)象被add多次時(shí), 即有多個(gè)索引指向了這個(gè)對(duì)象。List去元素時(shí)可以使用Iterator取出所有元素,在逐一遍歷,還可 以使用get(int index)獲取指定下表的元素;
(3)Map是雙列元素的集合,調(diào)用put(key,value),要存儲(chǔ)一對(duì)key/value,不能存儲(chǔ)重復(fù)的key, 這個(gè)是根據(jù)eauals來(lái)判斷;取元素時(shí)用get(key)來(lái)獲取key所對(duì) 應(yīng)的value,另外還可以獲取 全部key,全部value
二、ArrayList和LinkedList的底層實(shí)現(xiàn)原理?他們?yōu)槭裁淳€程不安全?在多線程并發(fā)操作下,我們應(yīng)該用什么替代?
1.ArrayList底層通過(guò)數(shù)組實(shí)現(xiàn),ArrayList允許按序號(hào)索引元素,而插入元素需要對(duì)數(shù)組進(jìn)行移位等內(nèi)存操作,所以索引快插入較慢;(擴(kuò)容方式)一旦我們實(shí)例化了ArrayList 無(wú)參構(gòu)造函數(shù)默認(rèn)數(shù)組長(zhǎng)度為10。add方法底層如 果增加的元素超過(guò)了10個(gè),那么ArrayList底層會(huì)生成一個(gè)新的數(shù)組,長(zhǎng)度為原來(lái)數(shù)組長(zhǎng)度的1.5倍+1,然后將原數(shù)組內(nèi)容復(fù)制到新數(shù)組中,并且后續(xù)加的內(nèi)容都會(huì)放到新數(shù)組中。當(dāng)新數(shù)組無(wú)法容納增加元素時(shí),重復(fù)該過(guò)程;
2.LinkedList底層通過(guò)雙向鏈表實(shí)現(xiàn),取元素時(shí)需要進(jìn)行前項(xiàng)或后項(xiàng)的遍歷,插入元素時(shí)只需要記錄本項(xiàng)的前后 項(xiàng)即可,所以插入快查詢慢;
3.ArrayList和LinkedList底層方法都沒有加synchronized關(guān)鍵詞,多線程訪問(wèn)時(shí)會(huì)出現(xiàn)多個(gè)線程先后更改數(shù)據(jù)造成得到的數(shù)據(jù)是臟數(shù)據(jù);多線程并發(fā)操作下使用Vector來(lái)代替,Vector底層也是數(shù)組,但底層方法都加synchronized關(guān)鍵字使線程安全,效率較ArrayList差;
三、HashMap和HashTable有什么區(qū)別?其底層實(shí)現(xiàn)是什么?CurrentHashMap的鎖機(jī)制又是如何?如果想將一個(gè)Map變?yōu)橛行虻?該如何實(shí)現(xiàn)?
1.區(qū)別:
(1)HashMap沒有實(shí)現(xiàn)synchronized線程非安全,HashTable實(shí)現(xiàn)了synchronized線程安全;
(2)HashMap允許key和value為null,而HashTable不允許
2.底層原理:數(shù)組+鏈表實(shí)現(xiàn)
3.ConcurrentHashMap鎖分段技術(shù):HashTable效率低下的原因,是因?yàn)樗L問(wèn)HashTable的線程都必須競(jìng)爭(zhēng)同一把鎖,那假如容器中有多把鎖,每一把鎖用于鎖住容器中的一部分?jǐn)?shù)據(jù),那么當(dāng)多線程訪問(wèn)容器中不同的數(shù)據(jù)時(shí),線程間就不會(huì)存在鎖競(jìng)爭(zhēng),從而提高并發(fā)訪問(wèn)率;ConcurrentHashMap使用的就是鎖分段技術(shù),首先將數(shù)據(jù)分成一段一段的存儲(chǔ),然后給每一段數(shù)據(jù)配一把鎖,當(dāng)一個(gè)線程占用鎖訪問(wèn)其中一個(gè)數(shù)據(jù)時(shí),其他段的數(shù)據(jù)也能被其他線程訪問(wèn);
4.實(shí)現(xiàn)TreeMap
框架部分
一、什么是Spring
Spring是一個(gè)輕量級(jí)的開源框架,是為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的;提供IOC來(lái)幫住我們創(chuàng)建對(duì)象及管理對(duì)象之間的依賴關(guān)系,提供AOP來(lái)幫我們完成日志的打印、異常的處理、事物的管理等操作,提供JDBC、ORM來(lái)完成持久層的操作,內(nèi)置SpringMvc控制層框架
二、spring優(yōu)點(diǎn)
1:方便解耦,簡(jiǎn)化開發(fā);
2:方便的對(duì)程序進(jìn)行攔截、運(yùn)行、監(jiān)控等功能;
3:提供聲明式事物;
4:屬于一個(gè)萬(wàn)能的框架,跟很多框架都是百搭;
三、什么是IOC?什么是AOP?
(1)IOC稱為控制反轉(zhuǎn)是指在程序運(yùn)行時(shí)自動(dòng)注入依賴對(duì)象;
底層實(shí)現(xiàn)原理:反射機(jī)制
(2)AOP稱為面向切面編程,就是程序中有很多各不想干的方法,在這些方法中加入
某種系統(tǒng)功能的代碼;例如加入日志、加入異常處理、加入事物管理
底層實(shí)現(xiàn)原理:動(dòng)態(tài)代理
四、反射機(jī)制:在程序運(yùn)行時(shí)根據(jù)指定的類名獲取類的信息;
主要作用:
1.在運(yùn)行時(shí)構(gòu)造一個(gè)類的對(duì)象;
2.判斷一個(gè)類所具有成員變量和方法;
3.調(diào)用一個(gè)對(duì)象的方法;
4.生成動(dòng)態(tài)代理;
五、動(dòng)態(tài)代理:利用Java反射技術(shù),在運(yùn)行時(shí)創(chuàng)建一個(gè)實(shí)現(xiàn)某些給定接口的新類(又分為JDK動(dòng)態(tài)代理和Cglib動(dòng)態(tài)代理)
主要作用:
1.可以隱藏委托類(就是被代理類)的具體實(shí)現(xiàn)
2.可以實(shí)現(xiàn)客戶與委托類間的解耦,再不修改委托類代碼的情況下能夠做一些額外的處理
JDK動(dòng)態(tài)代理和Cglib動(dòng)態(tài)代理的區(qū)別?
JDK動(dòng)態(tài)代理只能對(duì)實(shí)現(xiàn)了接口的類生成代理,為不能針對(duì)類
Cglib動(dòng)態(tài)代理是針對(duì)類實(shí)現(xiàn)代理,主要是對(duì)指定的類生成一個(gè)子類,覆蓋其中的方法(集成)
六、什么是DI機(jī)制?
依賴注入(Dependecy Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個(gè)概念,具體的講:當(dāng)某個(gè)角色需要另外一個(gè)角色協(xié)助的時(shí)候,在傳統(tǒng)的程序設(shè)計(jì)過(guò)程中,通常由調(diào)用者來(lái)創(chuàng)建被調(diào)用者的實(shí)例。但在spring中創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來(lái)完成,因此稱為控制反轉(zhuǎn)。創(chuàng)建被調(diào)用者的工作由spring來(lái)完成,然后注入調(diào)用者,因此稱為依賴注入。
七、Spring的Ioc注入方式有幾種?
一、Set注入
二、構(gòu)造器注入
三、接口注入
spring注入方便管理,依賴注入或者說(shuō)是控制反轉(zhuǎn),說(shuō)白了就是使用了配置文件,這種思想的唯一好處就是增加了模塊的重用性靈活性。
八、hibernate的工作原理
1.通過(guò)Configuration().configure();讀取并解析hibernate.cfg.xml配置文件
2.由hibernate.cfg.xml中的讀取并解析映射信息
3.通過(guò)config.buildSessionFactory();//創(chuàng)建SessionFactory
4.sessionFactory.openSession();//打開Sesssion
5.session.beginTransaction();//創(chuàng)建事務(wù)Transation
6.persistent operate持久化操作
7.session.getTransaction().commit();//提交事務(wù)
8.關(guān)閉Session
9.關(guān)閉SesstionFactory
九、hibernate優(yōu)點(diǎn):
1.對(duì)JDBC訪問(wèn)數(shù)據(jù)庫(kù)的代碼做了封裝,大大簡(jiǎn)化了數(shù)據(jù)訪問(wèn)層繁瑣的重復(fù)性代碼。
2.Hibernate是一個(gè)基于JDBC的主流持久化框架,是一個(gè)優(yōu)秀的ORM實(shí)現(xiàn)。他很大程度的簡(jiǎn)化DAO 層的編碼工作
3.hibernate使用Java反射機(jī)制,而不是字節(jié)碼增強(qiáng)程序來(lái)實(shí)現(xiàn)透明性。
4.hibernate的性能非常好,因?yàn)樗莻€(gè)輕量級(jí)框架。映射的靈活性很出色。它支持各種關(guān)系數(shù)據(jù)庫(kù), 從一對(duì)一到多對(duì)多的各種復(fù)雜關(guān)系。
十、SpringMvc運(yùn)行流程
1.用戶發(fā)送請(qǐng)求到DispatchServlet
2.DispatchServlet根據(jù)請(qǐng)求路徑查詢具體的Handler
3.DispatchServlet調(diào)用HandlerAdapter適配器,適配器再調(diào)用具體的Handler處理業(yè)務(wù)
4.Handler處理結(jié)束返回一個(gè)具體的ModelAndView給適配器,適配器將ModelAndView給 DispatchServlet
5.DispatchServlet把視圖名稱給ViewResolver視圖解析器
6.ViewResolver視圖解析器返回一個(gè)具體視圖給DispatchServlet
7.將渲染視圖的展示給用戶
十一、ssh和是ssm的區(qū)別
SSH 通常指的是 Struts2 做控制器(controller),spring管理各層的組件,hibernate 負(fù)責(zé)持久化層。
SSM 則指的是 SpringMVC 做控制器(controller),Spring 管理各層的組件,MyBatis 負(fù)責(zé)持久化 層。
共同點(diǎn):
1.Spring依賴注入DI來(lái)管理各層的組件。
2.使用面向切面編程AOP管理事物、日志、權(quán)限等。
不同點(diǎn):
1.struts2和springmvc的區(qū)別;
2.hibernate和mybatis的區(qū)別;
十二、struts2和SpringMvc的區(qū)別?
1.springmvc入口是一個(gè)servlet前段控制器,struts2入口是一個(gè)filter過(guò)濾器;
2.springmvc是基于方法開發(fā)的,傳遞參數(shù)通過(guò)方法的形參來(lái)傳遞;struts2是基于類開發(fā)的,傳遞參 數(shù)通過(guò)類的屬性來(lái)傳遞;
3.SpringMvc通過(guò)參數(shù)綁定期將request請(qǐng)求內(nèi)容解析,并給方法形參賦值;struts2采用值棧存儲(chǔ) 請(qǐng)求和響應(yīng)數(shù)據(jù),通過(guò)OGNL存儲(chǔ)數(shù)據(jù);
十三、hibernate和Mybatis的區(qū)別?
屏蔽jdbc的底層訪問(wèn)細(xì)節(jié),使我們不與jdbc api打交道,就可以訪問(wèn)數(shù)據(jù);jdbc api編程流程固定,還將sql語(yǔ)句與java代碼混雜在了一起,經(jīng)常需要拼湊sql語(yǔ)句,細(xì)節(jié)很繁 瑣;iBatis提供了自動(dòng)將結(jié)果集封裝成實(shí)體對(duì)象和對(duì)象集合的功能,queryForList返回對(duì)象集合,用queryForObject返回單個(gè)對(duì)象,提供了將實(shí)體對(duì)象的屬性傳遞給sql語(yǔ)句的參數(shù);Hibernate是一個(gè)全自動(dòng)的orm映射工具,他可以自動(dòng)生成sql語(yǔ)句,ibatis需要我們自己在xml配置文件中寫sql語(yǔ)句,hibernate要不ibatis負(fù)責(zé)功能強(qiáng)大很多。因?yàn)閔ibernate自動(dòng)生成sql語(yǔ)句,不能寫高效率的sql語(yǔ)句,對(duì)于一些不太復(fù)雜的sql查詢hibernate可以很好的幫我們完成,特別復(fù)雜查詢ibatis就比較合適了;
十四、Mybatis緩存機(jī)制?
緩存機(jī)制:Mybatis首先去緩存中查詢結(jié)果集,如果沒有則查詢數(shù)據(jù)庫(kù),如果有則從緩存中取出返回結(jié)果集就不走數(shù)據(jù)庫(kù);
Mybatis的一級(jí)緩存是SqlSession級(jí)別的緩存,在操作數(shù)據(jù)庫(kù)時(shí)需要?jiǎng)?chuàng)建SqlSession對(duì)象,在對(duì)象中有一個(gè)數(shù)據(jù)結(jié)構(gòu)用于存儲(chǔ)緩存的數(shù)據(jù),不同的SqlSession之間的緩存互不影響并且不能互相讀取;
Mybatis的二級(jí)緩存即查詢緩存,它的作用域是一個(gè)mapper的namespace,即在同一個(gè)namespace中查詢sql可以從緩存中獲取數(shù)據(jù),二級(jí)緩存是可以跨 SqlSession的;
MyBatis 默認(rèn)沒有開啟二級(jí)緩存,開啟只需在配置文件中寫入如下代碼:
Web部分
一、JSP九大內(nèi)置對(duì)象?作用分別是什么?分別有什么方法
request:用戶端請(qǐng)求,此請(qǐng)求會(huì)包含來(lái)自GET/POST請(qǐng)求的參數(shù)
response:網(wǎng)頁(yè)傳回用戶端的回應(yīng)
pageContext:網(wǎng)頁(yè)的屬性是在這里管理
session:與請(qǐng)求有關(guān)的回話期
application servlet:正在執(zhí)行的內(nèi)容
out:用來(lái)傳送回應(yīng)的輸出
page:JSP網(wǎng)頁(yè)本身
config:servlet的構(gòu)架部分
exception:針對(duì)錯(cuò)誤網(wǎng)頁(yè),未捕捉的例外
request表示HttpServletRequest對(duì)象;它包含了有關(guān)瀏覽器請(qǐng)求的信息,并且提供了幾個(gè)用于獲取cookie,header和session數(shù)據(jù)的方法
response表示HttpServletResponse對(duì)象,并且提供了幾個(gè)用于設(shè)置送回瀏覽器響應(yīng)的方法
二、forward()與redirect()的區(qū)別?
forward是容器中控制權(quán)的轉(zhuǎn)向,在客戶端瀏覽器不會(huì)顯示轉(zhuǎn)向后的地址;redirect則是完全的跳轉(zhuǎn),瀏覽器將會(huì)得到跳轉(zhuǎn)的地址,并重新發(fā)送請(qǐng)求鏈接,這樣瀏覽器地址欄中就可以看到跳轉(zhuǎn)后的鏈接地址。所以forward更加高效,在forward能滿足需要時(shí),盡量使用forward并且有助于隱藏實(shí)際的鏈接。如需要跳轉(zhuǎn)到一個(gè)其他服務(wù)器上的資源,則必須使用redirect;
線程部分
1. 程序,進(jìn)程,線程這三者之間的關(guān)系?
一個(gè)程序中可以調(diào)用多個(gè)進(jìn)程,一個(gè)進(jìn)程中可以有多個(gè)線程;比如一個(gè)視頻播放器,里面就有兩個(gè)進(jìn)程:一個(gè)是播放視頻的進(jìn)程,一個(gè)是下載上傳視頻的進(jìn)程;多個(gè)用戶看視頻就是多個(gè)線程訪問(wèn)一個(gè)進(jìn)程;
2.單線程與多線程區(qū)別,以及多線程意義?
如果程序只有一條執(zhí)行路徑,這就是單線程;相反如果有多條路徑,那就是多線程;
多線程的意義他可以讓程序在一個(gè)時(shí)間執(zhí)行多個(gè)事情,提高了應(yīng)用程序的使用率;
3.理解并發(fā)與并行
并發(fā):通過(guò)CPU調(diào)度算法,讓用戶看上去同時(shí)執(zhí)行,實(shí)際上,是通過(guò)CPU再高速切換,并不是真正的同時(shí),這就是并發(fā);
并行:多個(gè)CPU實(shí)例或者多臺(tái)機(jī)器同時(shí)執(zhí)行一段邏輯,這就是真正的同時(shí),這就是并行;
4.如何創(chuàng)建線程
方法一:
(1)類去繼承Thread類;
(2)該類重寫Thread類的run方法,并且將線程要執(zhí)行的代碼,存放到run方法中;
(3)線程對(duì)象調(diào)用start()方法,開啟線程,線程會(huì)自動(dòng)執(zhí)行run方法
方法二:
(1)類繼承Runnable接口
(2)重寫接口run方法,并將線程執(zhí)行代碼存放在run方法中
(3)創(chuàng)建Thread對(duì)象,也就是創(chuàng)建線程
(4)Thread線程對(duì)象調(diào)用start方法,啟動(dòng)線程
5.線程的幾種狀態(tài)?
初始化(new Thread()) --> 就緒(start()準(zhǔn)備執(zhí)行) --> 執(zhí)行(獲得CPU執(zhí)行權(quán))
執(zhí)行1 --> 等待(wait()):線程處于等待狀態(tài),自己醒不了,只能用notify()或notifyAll()喚醒,處于等待狀態(tài)的線程會(huì)釋放CPU執(zhí)行權(quán),同時(shí)釋放資源;
執(zhí)行2 --> 睡眠(sleep()):在指定毫秒數(shù)內(nèi)讓當(dāng)前正字執(zhí)行的線程休眠,只是暫停執(zhí)行,他會(huì)釋放CPU執(zhí)行權(quán),但不會(huì)釋放資源,設(shè)定時(shí)間到了,就會(huì)脫離睡眠狀態(tài),進(jìn)入執(zhí)行狀態(tài);
執(zhí)行3 --> 阻塞:當(dāng)多條線程存在輸入輸出時(shí),就會(huì)出現(xiàn)阻塞狀態(tài)
執(zhí)行4 --> 死亡:run方法執(zhí)行完畢,線程結(jié)束了也就是處于死亡狀態(tài)
6.多線程解決方法
(1)同步代碼塊:代碼塊放入同步鎖中
(2)同步方法:方法前加synchronized關(guān)鍵字
7.什么是死鎖(deadlock)?
兩個(gè)進(jìn)程都在等待對(duì)象執(zhí)行完后才繼續(xù)往下執(zhí)行的時(shí)候就發(fā)生了死鎖,兩個(gè)進(jìn)程都陷入了無(wú)限的等待中;
數(shù)據(jù)庫(kù)
一、你所了解的數(shù)據(jù)庫(kù)優(yōu)化方面有哪些?
1.Select語(yǔ)句必須指定字段名稱
2.當(dāng)只查詢結(jié)果為一條數(shù)據(jù)時(shí),使用limit 1
3.避免where子句對(duì)字段進(jìn)行null值判斷(對(duì)于null的判斷會(huì)導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描)
4.不建議使用%前綴模糊查詢,防止全表掃描
二、事務(wù)的四大特征
1.原子性(Atomicity)
原子性是指事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾;
2.一致性(Consistency)
也就是說(shuō)一個(gè)事物執(zhí)行之前和執(zhí)行之后都必須處于一致性狀態(tài);那轉(zhuǎn)賬來(lái)說(shuō),假設(shè)A和B兩者的 錢一共是5000,不管A和B之間如何轉(zhuǎn)賬,轉(zhuǎn)幾次賬,事務(wù)結(jié)束后兩人的錢加起來(lái)還是5000,這就 是事務(wù)的一致性;
3.隔離性
隔離性當(dāng)多個(gè)用戶并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)并操作同一張表時(shí),數(shù)據(jù)庫(kù)為每一個(gè)用戶開啟的事務(wù),不能被 其他事務(wù)操作所干擾,多個(gè)并發(fā)事務(wù)之間要相互隔離;比如兩個(gè)并發(fā)事務(wù)T1和T2,在事務(wù)T1看來(lái), T2要么在T1開始前結(jié)束事務(wù),要么在T1結(jié)束后開始事務(wù),這就是事務(wù)的隔離性;
4.持久性
執(zhí)行性是指一個(gè)事務(wù)一但被提交了,那么對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)的改變就是永久性的;
三、Spring隔離級(jí)別
如果多個(gè)事務(wù)同時(shí)訪問(wèn)相同數(shù)據(jù)時(shí),如果沒有采取必要的隔離級(jí)別,可能會(huì)發(fā)生什么問(wèn)題?
(1)臟讀:讀取過(guò)期的數(shù)據(jù),就是一個(gè)事物讀到另一個(gè)事務(wù)未提交的新數(shù)據(jù);
(2)幻讀:讀取臨時(shí)的數(shù)據(jù),就是一個(gè)事物在進(jìn)行修改全表的時(shí)候,另一個(gè)事務(wù)對(duì)數(shù)據(jù)進(jìn)行了新 增,從而第一個(gè)事務(wù)的執(zhí)行完后發(fā)現(xiàn)還有沒有修改的數(shù)據(jù),就好像發(fā)生了幻覺一樣;
(3)不可重復(fù)讀:就是在同一個(gè)事務(wù)中先后執(zhí)行兩條一樣的select語(yǔ)句,之間沒有執(zhí)行過(guò)Del 語(yǔ)句但先后結(jié)果不一樣,這就是不可重復(fù)讀;
Spring事務(wù)隔離級(jí)別
(1) Default:使用數(shù)據(jù)庫(kù)本身的隔離級(jí)別ORACLE(讀已提交)Mysql(可重復(fù)讀);
(2) Read_Uncomited:讀未提交(臟讀),最低隔離級(jí)別,一切皆有可能;
(3) Read_Commited:讀已提交,有幻讀以及不可重復(fù)讀的風(fēng)險(xiǎn);
(4) RepeaTable_Read:可重復(fù)讀,但還是有幻讀風(fēng)險(xiǎn);
(5) Serializable:串行化,最高隔離界別,杜絕一切隱患,但效率較低;
四、Spring怎么設(shè)置隔離級(jí)別?
用@Transactional注解聲明式事務(wù)的事務(wù)管理中來(lái)設(shè)置isolation屬性的隔離級(jí)別
在配置文件中設(shè)置事務(wù)tx:method元素
服務(wù)器
Nginx是一款輕量級(jí)的Web 服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,并在一個(gè)BSD-like 協(xié)議下發(fā)行。其特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng),
Keepalived的作用是檢測(cè)服務(wù)器的狀態(tài),如果有一臺(tái)web服務(wù)器宕機(jī),或工作出現(xiàn)故障,Keepalived將檢測(cè)到,并將有故障的服務(wù)器從系統(tǒng)中剔除,同時(shí)使用其他服務(wù)器代替該服務(wù)器的工作,當(dāng)服務(wù)器工作正常后Keepalived自動(dòng)將服務(wù)器加入到服務(wù)器群中,這些工作全部自動(dòng)完成,不需要人工干涉,需要人工做的只是修復(fù)故障的服務(wù)器。
Redis
- 設(shè)置緩存值的過(guò)期時(shí)間?
(1) 常用的方式:expire key time(以秒為單位)
(2) 字符串獨(dú)有方式:setex(String key,int seconds,String value)
如果沒有設(shè)置時(shí)間,那緩存就是永不過(guò)期; - Redis三種過(guò)期策略
(1)定時(shí)刪除:在設(shè)置key過(guò)期時(shí)間的同時(shí),為該key創(chuàng)建一個(gè)定時(shí)器,讓定時(shí)器在key過(guò)期的時(shí)候,對(duì)key進(jìn)行刪除;
(2)惰性刪除:key過(guò)期的時(shí)候不刪除,每次從數(shù)據(jù)庫(kù)獲取key的時(shí)候去檢查是否過(guò)期,若過(guò)期刪除,返回null;
(3)定期刪除:每隔一段時(shí)間執(zhí)行一次刪除過(guò)期key的操作
總結(jié):
針對(duì)于上面的面試題我總結(jié)出了互聯(lián)網(wǎng)公司java程序員面試涉及到的絕大部分面試題及答案做成了文檔和架構(gòu)視頻資料免費(fèi)分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并發(fā)等架構(gòu)技術(shù)資料),希望能幫助到您面試前的復(fù)習(xí)且找到一個(gè)好的工作,也節(jié)省大家在網(wǎng)上搜索資料的時(shí)間來(lái)學(xué)習(xí),也可以關(guān)注我以后會(huì)有更多干貨分享。
本文摘自 :https://blog.51cto.com/u