當(dāng)前位置:首頁 > IT技術(shù) > 編程語言 > 正文

2022年Java常見的一些經(jīng)典面試題(附答案解析)
2022-04-29 14:05:33


前言:


我想每個程序員比較頭疼的事情都是:工作擰螺絲,面試造火箭吧。但是又必須經(jīng)歷這個過程,尤其是弄不清面試官問的問題,如果你準(zhǔn)備的不是很充分,會導(dǎo)致面試的時候手足無措。今天這篇文章是從已工作5年的程序員面試幾十次中挑選的面試概率比較大的一些題目,都是大家被問到過的(就是這么自信),希望這篇文章能夠?qū)Υ蠹艺夜ぷ饔兴鶐椭?/p>


2022年Java常見的一些經(jīng)典面試題(附答案解析)_Java

基礎(chǔ)部分

一丶抽象類和接口的區(qū)別

1.語法區(qū)別

(1)抽象類可以有構(gòu)造方法,接口不能有構(gòu)造方法;

(2)抽象類中可以有普通成員變量,接口中沒有普通成員變量;

(3)抽象類中可以有非抽象的方法,接口中的方法都必須是抽象的;

(4)抽象類中的方法可以是public,protected類型,接口中的方法只能是public類型的,切 默認(rèn)為public abstract類型;

(5)抽象類中可以有靜態(tài)方法,接口中不能有靜態(tài)方法;

(6)抽象類中的靜態(tài)變量訪問類型可以是任意的,但接口中的靜態(tài)變量只能是public static final 類型。

(7).一個類可以實現(xiàn)多個接口,但一個類只能繼承一個抽象類;

2.應(yīng)用區(qū)別

接口更多是在系統(tǒng)架構(gòu)方面發(fā)揮作用,主要用于定義模塊之間的通信契約;而抽象類在代碼方法 發(fā)揮作用,可以使用代碼塊的重用;

二丶Java中接口可不可以繼承一般類,為什么?

不可以因為接口中只能出現(xiàn)3種成員:

1.公共的靜態(tài)常量(public static final )

2.公共的抽象方法(public abstract )
3.靜態(tài)內(nèi)部類(static class)

而一個類中,就算什么都不寫,也必須帶一個構(gòu)造方法,在extends時就會被子類繼承,如果是接口也會 繼承這個構(gòu)造方法,很明顯構(gòu)造方法不在上面三項之列

而如果類中有一般的方法和成員變量,也會被子類全部繼承,這些更不能出現(xiàn)在接口中了,所以接口是絕 對不可能繼承一個類的

三、基本數(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個字節(jié)

(2)short 2個字節(jié)

(3)char 2個字節(jié)

(4)int 4個字節(jié)

(5)long 8個字節(jié)

(6)float 4個字節(jié)

(7)double 8個字節(jié)

四丶String屬于那個類,以及常用的方法

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é)不同的通信功能,接下來針對這四層進(jìn)行詳細(xì)地講解。

鏈路層:用于定義物理傳輸通道,通常是對某些網(wǎng)絡(luò)連接設(shè)備的驅(qū)動協(xié)議,例如針對光纖、網(wǎng)線提供的驅(qū)動。

網(wǎng)絡(luò)層:網(wǎng)絡(luò)層是整個TCP/IP協(xié)議的核心,它主要用于將傳輸?shù)臄?shù)據(jù)進(jìn)行分組,將分組數(shù)據(jù)發(fā)送到目標(biāo)計算機(jī)或者網(wǎng)絡(luò)。

傳輸層:主要使網(wǎng)絡(luò)程序進(jìn)行通信,在進(jìn)行網(wǎng)絡(luò)通信時,可以采用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)致每次對String的操作都會生成新的String對象,不禁效率底下, 而且浪費大量的內(nèi)存空間;StringBuilder是可變類,任何對他指向的字符串的操作都不會產(chǎn)生新的對 象,但單線程不安全;StringBuffer底層方法使用了synchronized關(guān)鍵字,線程比較安全,但效率 較StringBuilder慢;

七、設(shè)計模式

單例模式:某個類只能有一個實例,提供一個全局的訪問點;

工廠模式:定義一個創(chuàng)建對象的接口,讓子類決定實例化那個類;

代理模式:為其他對象提供一個代理以便控制這個對象的訪問;

八、高并發(fā)如何處理?

1.從最基礎(chǔ)的地方做起,優(yōu)化我們寫的代碼,減少必要的資源浪費。

a.避免頻繁的new對象,對于整個程序只需要一個實例的類,我們可以使用單例模式;對于String 鏈接操作,使用StringBuffer或StringBuilder,對于工具類可以通過靜態(tài)方法來訪問;

b.避免使用錯誤的方式,使用java中高效率的類,比如ArrayList比Vector性能好;

2.html靜態(tài)化

把一些經(jīng)常不改變的內(nèi)容靜態(tài)化,高并發(fā)時減少服務(wù)器的壓力;

3.圖片服務(wù)器分離

對于web服務(wù)器來說,圖片是最消耗資源的,于是我們把圖片放到獨立的服務(wù)器,這樣可以降低 頁面請求服務(wù)器的系統(tǒng)壓力;

4.緩存

避免每一次都去數(shù)據(jù)庫中去查詢,減少數(shù)據(jù)庫的訪問量;并且使用redis數(shù)據(jù)庫來做緩存,它的 讀寫速度是非??斓?;

5.數(shù)據(jù)庫優(yōu)化

(1)優(yōu)化sql語句

a.Select語句必須指定列名

b.當(dāng)查詢結(jié)果為一條時,使用limit 1

c.避免使用%前綴搜索,避免全表掃描

九、get與post的區(qū)別

GET在瀏覽器回退時是無害的,而POST會再次提交請求。 GET產(chǎn)生的URL地址可以被Bookmark,而POST不可以。 GET請求會被瀏覽器主動cache,而POST不會,除非手動設(shè)GET請求只能進(jìn)行url編碼,而POST支持多種編碼方式。 GET請求參數(shù)會被完整保留在瀏覽器歷史記錄里,而POST中的參數(shù)不會被保留。 GET請求在URL中傳送的參數(shù)是有長度限制的,而POST么有。 對參數(shù)的數(shù)據(jù)類型,GET只接受ASCII字符,而POST沒有限制。 GET比POST更不安全,因為參數(shù)直接暴露在URL上,所以不能用來傳遞敏感信息。 GET參數(shù)通過URL傳遞,POST放在Request body中。

十、JDK1.8新特性

提供lambda表達(dá)式極大地減少了代碼的冗余;

在接口中可以使用default和static關(guān)鍵字來修飾接口中的普通方法;

提供新的API LocalDate | LocalTime | LocalDateTime

(1)Java.util.Date和SimpleDateFormatter線程上都不安全,而LocalDate和LocalTime和 String一樣都是不可改變類,線程上比較安全,還不能修改;

(2)Java.util.Date月份從0開始,12月是11,而java.time.LocalDate月份和星期都改成了 enum, 就不可能出錯了;

集合部分

一、List、Map、Set三個接口,存取元素時,各有什么特點

(1)Set集合的add有一個boolean類型的返回值,當(dāng)集合中沒有某個元素時,則可以成功加入該 元素,返回結(jié)果為true;當(dāng)集合中存在與某個元素equals方法相等 的元素時,則無法加入該元素, 取元素時只能用Iterator接口取得所有元素,在逐一遍歷各個元素;

(2)List表示有先后順序的集合,調(diào)用add()方法,指定當(dāng)前對象在集合中的存放位置;一個對象可 以被反復(fù)存進(jìn)集合中;每調(diào)用一次add()方法,該對象就會被插入集合中一次,其實,并不是把對 象本身存進(jìn)了集合中,而是在集合中使用一個索引變量指向了該對象,當(dāng)一個對象被add多次時, 即有多個索引指向了這個對象。List去元素時可以使用Iterator取出所有元素,在逐一遍歷,還可 以使用get(int index)獲取指定下表的元素;

(3)Map是雙列元素的集合,調(diào)用put(key,value),要存儲一對key/value,不能存儲重復(fù)的key, 這個是根據(jù)eauals來判斷;取元素時用get(key)來獲取key所對 應(yīng)的value,另外還可以獲取 全部key,全部value

二、ArrayList和LinkedList的底層實現(xiàn)原理?他們?yōu)槭裁淳€程不安全?在多線程并發(fā)操作下,我們應(yīng)該用什么替代?

1.ArrayList底層通過數(shù)組實現(xiàn),ArrayList允許按序號索引元素,而插入元素需要對數(shù)組進(jìn)行移位等內(nèi)存操作,所以索引快插入較慢;(擴(kuò)容方式)一旦我們實例化了ArrayList 無參構(gòu)造函數(shù)默認(rèn)數(shù)組長度為10。add方法底層如 果增加的元素超過了10個,那么ArrayList底層會生成一個新的數(shù)組,長度為原來數(shù)組長度的1.5倍+1,然后將原數(shù)組內(nèi)容復(fù)制到新數(shù)組中,并且后續(xù)加的內(nèi)容都會放到新數(shù)組中。當(dāng)新數(shù)組無法容納增加元素時,重復(fù)該過程;

2.LinkedList底層通過雙向鏈表實現(xiàn),取元素時需要進(jìn)行前項或后項的遍歷,插入元素時只需要記錄本項的前后 項即可,所以插入快查詢慢;

3.ArrayList和LinkedList底層方法都沒有加synchronized關(guān)鍵詞,多線程訪問時會出現(xiàn)多個線程先后更改數(shù)據(jù)造成得到的數(shù)據(jù)是臟數(shù)據(jù);多線程并發(fā)操作下使用Vector來代替,Vector底層也是數(shù)組,但底層方法都加synchronized關(guān)鍵字使線程安全,效率較ArrayList差;

三、HashMap和HashTable有什么區(qū)別?其底層實現(xiàn)是什么?CurrentHashMap的鎖機(jī)制又是如何?如果想將一個Map變?yōu)橛行虻?該如何實現(xiàn)?

1.區(qū)別:

(1)HashMap沒有實現(xiàn)synchronized線程非安全,HashTable實現(xiàn)了synchronized線程安全;

(2)HashMap允許key和value為null,而HashTable不允許

2.底層原理:數(shù)組+鏈表實現(xiàn)

3.ConcurrentHashMap鎖分段技術(shù):HashTable效率低下的原因,是因為所訪問HashTable的線程都必須競爭同一把鎖,那假如容器中有多把鎖,每一把鎖用于鎖住容器中的一部分?jǐn)?shù)據(jù),那么當(dāng)多線程訪問容器中不同的數(shù)據(jù)時,線程間就不會存在鎖競爭,從而提高并發(fā)訪問率;ConcurrentHashMap使用的就是鎖分段技術(shù),首先將數(shù)據(jù)分成一段一段的存儲,然后給每一段數(shù)據(jù)配一把鎖,當(dāng)一個線程占用鎖訪問其中一個數(shù)據(jù)時,其他段的數(shù)據(jù)也能被其他線程訪問;

4.實現(xiàn)TreeMap

2022年Java常見的一些經(jīng)典面試題(附答案解析)_Java崗位_02

框架部分

一、什么是Spring

Spring是一個輕量級的開源框架,是為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的;提供IOC來幫住我們創(chuàng)建對象及管理對象之間的依賴關(guān)系,提供AOP來幫我們完成日志的打印、異常的處理、事物的管理等操作,提供JDBC、ORM來完成持久層的操作,內(nèi)置SpringMvc控制層框架

二、spring優(yōu)點

1:方便解耦,簡化開發(fā);

2:方便的對程序進(jìn)行攔截、運行、監(jiān)控等功能;

3:提供聲明式事物;

4:屬于一個萬能的框架,跟很多框架都是百搭;

三、什么是IOC?什么是AOP?

(1)IOC稱為控制反轉(zhuǎn)是指在程序運行時自動注入依賴對象;

底層實現(xiàn)原理:反射機(jī)制

(2)AOP稱為面向切面編程,就是程序中有很多各不想干的方法,在這些方法中加入

某種系統(tǒng)功能的代碼;例如加入日志、加入異常處理、加入事物管理

底層實現(xiàn)原理:動態(tài)代理

四、反射機(jī)制:在程序運行時根據(jù)指定的類名獲取類的信息;

主要作用:

1.在運行時構(gòu)造一個類的對象;

2.判斷一個類所具有成員變量和方法;

3.調(diào)用一個對象的方法;

4.生成動態(tài)代理;

五、動態(tài)代理:利用Java反射技術(shù),在運行時創(chuàng)建一個實現(xiàn)某些給定接口的新類(又分為JDK動態(tài)代理和Cglib動態(tài)代理)

主要作用:

1.可以隱藏委托類(就是被代理類)的具體實現(xiàn)

2.可以實現(xiàn)客戶與委托類間的解耦,再不修改委托類代碼的情況下能夠做一些額外的處理

JDK動態(tài)代理和Cglib動態(tài)代理的區(qū)別?

JDK動態(tài)代理只能對實現(xiàn)了接口的類生成代理,為不能針對類

Cglib動態(tài)代理是針對類實現(xiàn)代理,主要是對指定的類生成一個子類,覆蓋其中的方法(集成)

六、什么是DI機(jī)制?

依賴注入(Dependecy Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個概念,具體的講:當(dāng)某個角色需要另外一個角色協(xié)助的時候,在傳統(tǒng)的程序設(shè)計過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實例。但在spring中創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來完成,因此稱為控制反轉(zhuǎn)。創(chuàng)建被調(diào)用者的工作由spring來完成,然后注入調(diào)用者,因此稱為依賴注入。

七、Spring的Ioc注入方式有幾種?

一、Set注入

二、構(gòu)造器注入

三、接口注入

spring注入方便管理,依賴注入或者說是控制反轉(zhuǎn),說白了就是使用了配置文件,這種思想的唯一好處就是增加了模塊的重用性靈活性。

八、hibernate的工作原理

1.通過Configuration().configure();讀取并解析hibernate.cfg.xml配置文件

2.由hibernate.cfg.xml中的讀取并解析映射信息

3.通過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)點:

1.對JDBC訪問數(shù)據(jù)庫的代碼做了封裝,大大簡化了數(shù)據(jù)訪問層繁瑣的重復(fù)性代碼。

2.Hibernate是一個基于JDBC的主流持久化框架,是一個優(yōu)秀的ORM實現(xiàn)。他很大程度的簡化DAO 層的編碼工作

3.hibernate使用Java反射機(jī)制,而不是字節(jié)碼增強(qiáng)程序來實現(xiàn)透明性。

4.hibernate的性能非常好,因為它是個輕量級框架。映射的靈活性很出色。它支持各種關(guān)系數(shù)據(jù)庫, 從一對一到多對多的各種復(fù)雜關(guān)系。

十、SpringMvc運行流程

1.用戶發(fā)送請求到DispatchServlet

2.DispatchServlet根據(jù)請求路徑查詢具體的Handler

3.DispatchServlet調(diào)用HandlerAdapter適配器,適配器再調(diào)用具體的Handler處理業(yè)務(wù)

4.Handler處理結(jié)束返回一個具體的ModelAndView給適配器,適配器將ModelAndView給 DispatchServlet

5.DispatchServlet把視圖名稱給ViewResolver視圖解析器

6.ViewResolver視圖解析器返回一個具體視圖給DispatchServlet

7.將渲染視圖的展示給用戶

十一、ssh和是ssm的區(qū)別

SSH 通常指的是 Struts2 做控制器(controller),spring管理各層的組件,hibernate 負(fù)責(zé)持久化層。

SSM 則指的是 SpringMVC 做控制器(controller),Spring 管理各層的組件,MyBatis 負(fù)責(zé)持久化 層。

共同點:

1.Spring依賴注入DI來管理各層的組件。

2.使用面向切面編程AOP管理事物、日志、權(quán)限等。

不同點:

1.struts2和springmvc的區(qū)別;

2.hibernate和mybatis的區(qū)別;

十二、struts2和SpringMvc的區(qū)別?

1.springmvc入口是一個servlet前段控制器,struts2入口是一個filter過濾器;

2.springmvc是基于方法開發(fā)的,傳遞參數(shù)通過方法的形參來傳遞;struts2是基于類開發(fā)的,傳遞參 數(shù)通過類的屬性來傳遞;

3.SpringMvc通過參數(shù)綁定期將request請求內(nèi)容解析,并給方法形參賦值;struts2采用值棧存儲 請求和響應(yīng)數(shù)據(jù),通過OGNL存儲數(shù)據(jù);

十三、hibernate和Mybatis的區(qū)別?

屏蔽jdbc的底層訪問細(xì)節(jié),使我們不與jdbc api打交道,就可以訪問數(shù)據(jù);jdbc api編程流程固定,還將sql語句與java代碼混雜在了一起,經(jīng)常需要拼湊sql語句,細(xì)節(jié)很繁 瑣;iBatis提供了自動將結(jié)果集封裝成實體對象和對象集合的功能,queryForList返回對象集合,用queryForObject返回單個對象,提供了將實體對象的屬性傳遞給sql語句的參數(shù);Hibernate是一個全自動的orm映射工具,他可以自動生成sql語句,ibatis需要我們自己在xml配置文件中寫sql語句,hibernate要不ibatis負(fù)責(zé)功能強(qiáng)大很多。因為hibernate自動生成sql語句,不能寫高效率的sql語句,對于一些不太復(fù)雜的sql查詢hibernate可以很好的幫我們完成,特別復(fù)雜查詢ibatis就比較合適了;

十四、Mybatis緩存機(jī)制?

緩存機(jī)制:Mybatis首先去緩存中查詢結(jié)果集,如果沒有則查詢數(shù)據(jù)庫,如果有則從緩存中取出返回結(jié)果集就不走數(shù)據(jù)庫;

Mybatis的一級緩存是SqlSession級別的緩存,在操作數(shù)據(jù)庫時需要創(chuàng)建SqlSession對象,在對象中有一個數(shù)據(jù)結(jié)構(gòu)用于存儲緩存的數(shù)據(jù),不同的SqlSession之間的緩存互不影響并且不能互相讀??;

Mybatis的二級緩存即查詢緩存,它的作用域是一個mapper的namespace,即在同一個namespace中查詢sql可以從緩存中獲取數(shù)據(jù),二級緩存是可以跨 SqlSession的;

MyBatis 默認(rèn)沒有開啟二級緩存,開啟只需在配置文件中寫入如下代碼:

Web部分

一、JSP九大內(nèi)置對象?作用分別是什么?分別有什么方法

request:用戶端請求,此請求會包含來自GET/POST請求的參數(shù)

response:網(wǎng)頁傳回用戶端的回應(yīng)

pageContext:網(wǎng)頁的屬性是在這里管理

session:與請求有關(guān)的回話期

application servlet:正在執(zhí)行的內(nèi)容

out:用來傳送回應(yīng)的輸出

page:JSP網(wǎng)頁本身

config:servlet的構(gòu)架部分

exception:針對錯誤網(wǎng)頁,未捕捉的例外

request表示HttpServletRequest對象;它包含了有關(guān)瀏覽器請求的信息,并且提供了幾個用于獲取cookie,header和session數(shù)據(jù)的方法

response表示HttpServletResponse對象,并且提供了幾個用于設(shè)置送回瀏覽器響應(yīng)的方法

二、forward()與redirect()的區(qū)別?

forward是容器中控制權(quán)的轉(zhuǎn)向,在客戶端瀏覽器不會顯示轉(zhuǎn)向后的地址;redirect則是完全的跳轉(zhuǎn),瀏覽器將會得到跳轉(zhuǎn)的地址,并重新發(fā)送請求鏈接,這樣瀏覽器地址欄中就可以看到跳轉(zhuǎn)后的鏈接地址。所以forward更加高效,在forward能滿足需要時,盡量使用forward并且有助于隱藏實際的鏈接。如需要跳轉(zhuǎn)到一個其他服務(wù)器上的資源,則必須使用redirect;

線程部分

1. 程序,進(jìn)程,線程這三者之間的關(guān)系?

一個程序中可以調(diào)用多個進(jìn)程,一個進(jìn)程中可以有多個線程;比如一個視頻播放器,里面就有兩個進(jìn)程:一個是播放視頻的進(jìn)程,一個是下載上傳視頻的進(jìn)程;多個用戶看視頻就是多個線程訪問一個進(jìn)程;

2.單線程與多線程區(qū)別,以及多線程意義?

如果程序只有一條執(zhí)行路徑,這就是單線程;相反如果有多條路徑,那就是多線程;

多線程的意義他可以讓程序在一個時間執(zhí)行多個事情,提高了應(yīng)用程序的使用率;

3.理解并發(fā)與并行

并發(fā):通過CPU調(diào)度算法,讓用戶看上去同時執(zhí)行,實際上,是通過CPU再高速切換,并不是真正的同時,這就是并發(fā);

并行:多個CPU實例或者多臺機(jī)器同時執(zhí)行一段邏輯,這就是真正的同時,這就是并行;

4.如何創(chuàng)建線程

方法一:

(1)類去繼承Thread類;

(2)該類重寫Thread類的run方法,并且將線程要執(zhí)行的代碼,存放到run方法中;

(3)線程對象調(diào)用start()方法,開啟線程,線程會自動執(zhí)行run方法

方法二

(1)類繼承Runnable接口

(2)重寫接口run方法,并將線程執(zhí)行代碼存放在run方法中

(3)創(chuàng)建Thread對象,也就是創(chuàng)建線程

(4)Thread線程對象調(diào)用start方法,啟動線程

5.線程的幾種狀態(tài)?

初始化(new Thread()) --> 就緒(start()準(zhǔn)備執(zhí)行) --> 執(zhí)行(獲得CPU執(zhí)行權(quán))

執(zhí)行1 --> 等待(wait()):線程處于等待狀態(tài),自己醒不了,只能用notify()或notifyAll()喚醒,處于等待狀態(tài)的線程會釋放CPU執(zhí)行權(quán),同時釋放資源;

執(zhí)行2 --> 睡眠(sleep()):在指定毫秒數(shù)內(nèi)讓當(dāng)前正字執(zhí)行的線程休眠,只是暫停執(zhí)行,他會釋放CPU執(zhí)行權(quán),但不會釋放資源,設(shè)定時間到了,就會脫離睡眠狀態(tài),進(jìn)入執(zhí)行狀態(tài);

執(zhí)行3 --> 阻塞:當(dāng)多條線程存在輸入輸出時,就會出現(xiàn)阻塞狀態(tài)

執(zhí)行4 --> 死亡:run方法執(zhí)行完畢,線程結(jié)束了也就是處于死亡狀態(tài)

6.多線程解決方法

(1)同步代碼塊:代碼塊放入同步鎖中

(2)同步方法:方法前加synchronized關(guān)鍵字

7.什么是死鎖(deadlock)?

兩個進(jìn)程都在等待對象執(zhí)行完后才繼續(xù)往下執(zhí)行的時候就發(fā)生了死鎖,兩個進(jìn)程都陷入了無限的等待中;

數(shù)據(jù)庫

一、你所了解的數(shù)據(jù)庫優(yōu)化方面有哪些?

1.Select語句必須指定字段名稱

2.當(dāng)只查詢結(jié)果為一條數(shù)據(jù)時,使用limit 1

3.避免where子句對字段進(jìn)行null值判斷(對于null的判斷會導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描)

4.不建議使用%前綴模糊查詢,防止全表掃描

二、事務(wù)的四大特征

1.原子性(Atomicity)

原子性是指事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾;

2.一致性(Consistency)

也就是說一個事物執(zhí)行之前和執(zhí)行之后都必須處于一致性狀態(tài);那轉(zhuǎn)賬來說,假設(shè)A和B兩者的 錢一共是5000,不管A和B之間如何轉(zhuǎn)賬,轉(zhuǎn)幾次賬,事務(wù)結(jié)束后兩人的錢加起來還是5000,這就 是事務(wù)的一致性;

3.隔離性

隔離性當(dāng)多個用戶并發(fā)訪問數(shù)據(jù)庫并操作同一張表時,數(shù)據(jù)庫為每一個用戶開啟的事務(wù),不能被 其他事務(wù)操作所干擾,多個并發(fā)事務(wù)之間要相互隔離;比如兩個并發(fā)事務(wù)T1和T2,在事務(wù)T1看來, T2要么在T1開始前結(jié)束事務(wù),要么在T1結(jié)束后開始事務(wù),這就是事務(wù)的隔離性;

4.持久性

執(zhí)行性是指一個事務(wù)一但被提交了,那么對數(shù)據(jù)庫中的數(shù)據(jù)的改變就是永久性的;

三、Spring隔離級別

如果多個事務(wù)同時訪問相同數(shù)據(jù)時,如果沒有采取必要的隔離級別,可能會發(fā)生什么問題?

(1)臟讀:讀取過期的數(shù)據(jù),就是一個事物讀到另一個事務(wù)未提交的新數(shù)據(jù);

(2)幻讀:讀取臨時的數(shù)據(jù),就是一個事物在進(jìn)行修改全表的時候,另一個事務(wù)對數(shù)據(jù)進(jìn)行了新 增,從而第一個事務(wù)的執(zhí)行完后發(fā)現(xiàn)還有沒有修改的數(shù)據(jù),就好像發(fā)生了幻覺一樣;

(3)不可重復(fù)讀:就是在同一個事務(wù)中先后執(zhí)行兩條一樣的select語句,之間沒有執(zhí)行過Del 語句但先后結(jié)果不一樣,這就是不可重復(fù)讀;

Spring事務(wù)隔離級別

(1) Default:使用數(shù)據(jù)庫本身的隔離級別ORACLE(讀已提交)Mysql(可重復(fù)讀);

(2) Read_Uncomited:讀未提交(臟讀),最低隔離級別,一切皆有可能;

(3) Read_Commited:讀已提交,有幻讀以及不可重復(fù)讀的風(fēng)險;

(4) RepeaTable_Read:可重復(fù)讀,但還是有幻讀風(fēng)險;

(5) Serializable:串行化,最高隔離界別,杜絕一切隱患,但效率較低;

四、Spring怎么設(shè)置隔離級別?

用@Transactional注解聲明式事務(wù)的事務(wù)管理中來設(shè)置isolation屬性的隔離級別

在配置文件中設(shè)置事務(wù)tx:method元素

服務(wù)器

Nginx是一款輕量級的Web 服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,并在一個BSD-like 協(xié)議下發(fā)行。其特點是占有內(nèi)存少,并發(fā)能力強(qiáng),

Keepalived的作用是檢測服務(wù)器的狀態(tài),如果有一臺web服務(wù)器宕機(jī),或工作出現(xiàn)故障,Keepalived將檢測到,并將有故障的服務(wù)器從系統(tǒng)中剔除,同時使用其他服務(wù)器代替該服務(wù)器的工作,當(dāng)服務(wù)器工作正常后Keepalived自動將服務(wù)器加入到服務(wù)器群中,這些工作全部自動完成,不需要人工干涉,需要人工做的只是修復(fù)故障的服務(wù)器。

Redis

  1. 設(shè)置緩存值的過期時間?
    (1) 常用的方式:expire key time(以秒為單位)
    (2) 字符串獨有方式:setex(String key,int seconds,String value)
    如果沒有設(shè)置時間,那緩存就是永不過期;
  2. Redis三種過期策略
    (1)定時刪除:在設(shè)置key過期時間的同時,為該key創(chuàng)建一個定時器,讓定時器在key過期的時候,對key進(jìn)行刪除;
    (2)惰性刪除:key過期的時候不刪除,每次從數(shù)據(jù)庫獲取key的時候去檢查是否過期,若過期刪除,返回null;
    (3)定期刪除:每隔一段時間執(zhí)行一次刪除過期key的操作

總結(jié):

針對于上面的面試題我總結(jié)出了互聯(lián)網(wǎng)公司java程序員面試涉及到的絕大部分面試題及答案做成了文檔和架構(gòu)視頻資料免費分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并發(fā)等架構(gòu)技術(shù)資料),希望能幫助到您面試前的復(fù)習(xí)且找到一個好的工作,也節(jié)省大家在網(wǎng)上搜索資料的時間來學(xué)習(xí),也可以關(guān)注我以后會有更多干貨分享。

本文摘自 :https://blog.51cto.com/u

開通會員,享受整站包年服務(wù)立即開通 >