JAVA筆試題和麪試題



不同的階段的話會有不同的筆試和麪試問題。這是爲一年多的工作經驗的java開發人員準備。希望大家一起努力充實自己,查漏補缺。我在2017年的三月至四月份間面試了N家公司。根據他們的筆試和麪試問題,我總結下來的,希望對大家有用。

* 說出mybatis對jdbc的封裝,並且說出相互之間的映射關係。

    首先我們都知道jdbc是最原始對數據庫操作,他一般分爲7個步驟

(1)加載JDBC驅動

(2)建立並獲取數據庫連接

(3)創建JDBC Statements對象

(4)設置SQL語句的傳入參數

(5)執行SQL語句並獲得查詢結果

(6)對查詢結果進行轉換處理並將處理結果返回

(7)釋放相關資源(關閉Connection,關閉Statement,關閉ResultSet)

mybatis封裝連接數據庫和釋放數據庫:數據庫連接的獲取和關閉我們可以使用數據庫連接池來解決資源浪費的問題。通過連接池就可以反覆利用已 經建立的連接去訪問數據庫了。減少連接的開啓和關閉的時間。可以使用有可能採用DBCP的連接池,也有可能採用容器本身的JNDI數據庫連接池。

SQL統一存取:原來的sql語句在java代碼中,非常不方便,可讀性差。傳入參數映射和動態SQL和提取重複sql語句。我們寫SQL語句,是使用佔位符的形式必須按照順序一一匹配,使用mybatis可以使用動態sql語句。

結果映射和結果緩存:mybatis可以講sql結果映射到實體類中.

*spring的事物管理。其中要說出 4種隔離界別 ,7種傳播方式。

髒讀:事物讀到未提交的數據。

事務隔離級別定義的是事務在數據庫讀寫方面的控制範圍。

4種隔離級別。

seriallizable(TransactionDefinition.ISOLATION_SERIALIZABLE):表明事務被處理爲順序執行,這樣事務之間就完全不可能產生干擾,也就是說,該級別可以防止髒讀、不可重複讀以及幻讀。但是這將嚴重影響程序的性能。通常情況下也不會用到該級別。

read(TransactionDefinition.ISOLATION_REPEATABLE_READ):隔離級別表示一個事務在整個過程中可以多次重複執行某個查詢,並且每次返回的記錄都相同。即使在多次查詢之間有新增的數據滿足該查詢,這些新增的記錄也會被忽略。該級別可以防止髒讀和不可重複讀。

理解:當我在查詢數據時,不允許別的人來修改數據。

committed(TransactionDefinition.ISOLATION_READ_COMMITTED):該隔離級別表示一個事務只能讀取另一個事務已經提交的數據。該級別可以防止髒讀,這也是大多數情況下的推薦值

理解:當我在修改數據,不允許別人的讀取。

uncommitted(TransactionDefinition.ISOLATION_READ_UNCOMMITTED):該隔離界別表示一個事務可以讀取另一個事務修改但還沒有提交的數據。該級別不能防止髒讀和不可重複讀,因此很少使用該隔離級別。就是很少使用,

理解:我在查詢別人可以修改數據,髒讀,可重複讀

你需要知道一些數據庫的默認隔離級別(TransactionDefinition.ISOLATION_DEFAULT)

對大部分數據庫而言,通常這值就是TransactionDefinition.ISOLATION_READ_COMMITTED。

mysql默認隔離級別TransactionDefinition.ISOLATION_REPEATABLE_READ

InnoDB默認隔離級別TransactionDefinition.ISOLATION_REPEATABLE_READ

SQL Server的缺省隔離級別TransactionDefinition.ISOLATION_READ_COMMITTED。

Oracle缺省的設置是TransactionDefinition.ISOLATION_READ_COMMITTED。

spring的事物傳播行爲,當事務方法被另一個事務方法調用時,必須指定事務應該如何傳播。

傳播級別定義的是事務的控制範圍

(required)TransactionDefinition.PROPAGATION_REQUIRED:如果當前存在事務,則加入該事務;如果當前沒有事務,則創建一個新的事務。 這個是最常見的傳播行爲,所以這個級別通常能滿足處理大多數的業務場景。

(requires_new)TransactionDefinition.PROPAGATION_REQUIRES_NEW:創建一個新的事務,如果當前存在事務,則把當前事務掛起。,執行新事務完成以後,當前事務恢復再執行。這是一個很有用的傳播級別,舉一個應用場景:現在有一個發送100個紅包的操作,在發送之前,要做一些系統的初始化、驗證、數據記錄操作,然後發送100封紅包,然後再記錄發送日誌,發送日誌要求100%的準確,如果日誌不準確,那麼整個父事務邏輯需要回滾。怎麼處理整個業務需求呢?就是通過這個PROPAGATION_REQUIRES_NEW 級別的事務傳播控制就可以完成。發送紅包的子事務不會直接影響到父事務的提交和回滾。

(supports)TransactionDefinition.PROPAGATION_SUPPORTS:如果當前存在事務,則加入該事務;如果當前沒有事務,則以非事務的方式繼續運行。應用場景較少。

(not_supported)TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事務方式運行,如果當前存在事務,則把當前事務掛起。非事務執行後在執行當前事務。

(propagation_never)TransactionDefinition.PROPAGATION_NEVER:以非事務方式運行,如果當前存在事務,則拋出異常。不能存在上下文事物

(propagation_mandatory)TransactionDefinition.PROPAGATION_MANDATORY:如果當前存在事務,則加入該事務;如果當前沒有事務,則拋出異常。(上下文必須有事物)

(propagation_nested)TransactionDefinition.PROPAGATION_NESTED:如果當前存在事務,則創建一個事務作爲當前事務的嵌套事務來運行;如果當前沒有事務,則該取值等價於TransactionDefinition.PROPAGATION_REQUIRED。
可以加羣找我要課堂鏈接 注意:是免費的 沒有開發經驗誤入哦)
1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的。
2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的。
3、如果沒有工作經驗,但基礎非常紮實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的。
4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的。
5. 羣號:689024304   備註好信息!
6.阿里Java高級大牛直播講解知識點,分享知識,多年工作經驗的梳理和總結,帶着大家全面、科學地建立自己的技術體系和技術認知!


* 雙向鏈表的描述-單雙鏈表的反序操作

鏈表和數組優缺點:數組查詢比較簡單,因爲有下標值,根據下標值可以快速查詢到相應的值,但是刪除就比較麻煩,這一點連接比較方便,只需要將上一個指針不在指向要刪除的數據,而是指向下一個數據。

數據塊,first的指針,last的指針,一般數據時first的指針連接上一個數據的last指針,last的指針連接下一個數據的first指針。第一個數據沒有first的指針,最後一個元素沒有last指針。

* 線程的加鎖機制,一共有幾種加鎖機制。

synchronized(互斥鎖)代碼加上這個關鍵字後以爲者這段代碼具有了原子性和可見性。原子性說明一個線程只能執行這段代碼,可見性指它必須確保釋放鎖之前對共享數據做出的更改對於隨後獲得該鎖的另一個線程是可見的 。

作用:如果沒有同步機制提供的這種可見性保證,線程看到的共享變量可能是修改前的值或不一致的值,這將引發許多嚴重問題。

synchronized缺點:1它無法中斷一個正在等候獲得鎖的線程;2也無法通過投票得到鎖,如果不想等下去,也就沒法得到鎖;3同步還要求鎖的釋放只能在與獲得鎖所在的堆棧幀相同的堆棧幀中進行,

lock(鎖抽象):1NSLock 2ReentrantLock(鎖對象):具有synchronized的相同功能,但是還有鎖投票、定時鎖等候和可中斷鎖等候的一些特性。此外,它還提供了在激烈爭用情況下更佳的性能。3讀寫鎖ReadWriteLock:讀取線程不應該互斥!

* 線程的順序問題

* spring的重定向和轉發問題

轉發:forward  轉發到某個視圖,就是頁面跳轉,實例springmvc可以使用viewResolver設置轉發具體的view,本來我們發送到hello中,通過viewResolver設置前綴和後綴,我們可以轉發到/springmvc/hello.jsp頁面中。

重定向:重定向之後地址欄上的地址會發生變化,重定向是二次請求,轉發是一次請求,轉發快於重定向。redirect:/index.action";redirect 重定向到內部的某個controller中,定向內部某個資源

個人使用:頁面跳轉建議使用重定向,有內部Servlet跳轉建議使用轉發。轉發只能在站內跳轉,重定向可以跳轉到任意想要的地址----只要這個地址存在,所以請求頁面的時候轉發相比重定向也有侷限性。如果代碼邏輯是ServletA->ServletB->*.jsp,使用轉發,那麼這三次操作都在一次請求中,而如果使用重定向,那麼客戶端將發起三次請求,這真的毫無必要。因此,如果代碼邏輯中含有內部的Servlet跳轉,使用轉發會使一個好的選擇。

* 內存區塊問題

內存分配及其實現

    棧:線程單獨享有,每個線程對應着一個虛擬機棧,因此虛擬機棧也是線程私有的

        1 虛擬機棧,在虛擬棧中存放  a 局部變量表 b 操作站 c 動態鏈接 d 方法出口

                    a 局部變量表 存儲着方法的相關局部變量.包括各種基本數據類型,對象的引用,返回地址等

                      只有long和double類型會佔用2個局部變量空間(Slot,對於32位機器,一個Slot就是32個bit),

                      其它都是1個Slot,局部變量表是在編譯時就已經確定好的,方法運行所需要分配的空間在棧幀中是完全確定的,

                      在方法的生命週期內都不會改變。

                    d 方法出口(當方法被調用時,棧幀在JVM棧中入棧,當方法執行完成時,棧幀出棧)

        2 本地方法棧 :虛擬機棧是執行Java方法的,而本地方法棧是用來執行native方法的,

                      在很多虛擬機中(如Sun的JDK默認的HotSpot虛擬機),會將本地方法棧與虛擬機棧放在一起使用。

                      線程私有。

    堆:

    年輕代 對象創建時,停止-複製清理法,Minor GC

        (8)Eden: (Eden滿的時候出發minor GC)絕大多數剛創建的對象會被分配在Eden區,其中的大多數對象很快就會消亡。

            Eden區是連續的內存空間,因此在其上分配內存極快

            最初一次,當Eden區滿的時候,執行Minor GC,將消亡的對象清理掉,

            並將剩餘的對象複製到一個存活區Survivor0(此時,Survivor1是空白的,兩個Survivor總有一個是空白的)

            下次Eden區滿了,再執行一次Minor GC,將消亡的對象清理掉,將存活的對象複製到Survivor1中,然後清空Eden區

        (1)Survivor0: 來記錄對象的清理數次。在HotSpot切換15次,就可以進去老年代。

        (1)Survivor1:

    年老代 Major GC,也叫 Full GC。標記-整理算法。升到老年代的對象大於老年代剩餘空間full gc,(年輕代升到年老代對象大於

        老年代剩餘空間)

        或者小於時被HandlePromotionFailure參數強制full gc,(當空間小於指定的設置的空間)

        標記出仍然存活的對象(存在引用的),將所有存活的對象向一端移動,

        以保證內存的連續。在發生Minor GC時,虛擬機會檢查每次晉升進入老年代的大小是否大於老年代的剩餘空間大小,如果大於,

        則直接觸發一次Full GC,

        如果對象比較大(比如長字符串或大數組),Young空間不足,則大對象會直接分配到老年代上

        (大對象可能觸發提前GC,應少用,更應避免使用短命的大對象)。

        可能存在年老代對象引用新生代對象的情況,如果需要執行Young GC,則可能需要查詢整個老年代以確定是否可以清理回收,

        這顯然是低效的。解決的方法是,年老代中維護一個512 byte的塊——”card table“,所有老年代對象引用新生代對象的記

        錄都記錄在這裏。Young GC時,只要查這裏即可,不用再去查全部老年代,因此性能大大提高。

    永久代(方法區)常量池中的常量,無用的類信息,

        類的所有實例都已經被回收

        加載類的ClassLoader已經被回收

        類對象的Class對象沒有被引用(即沒有通過反射引用該類的地方)

        則將類信息進行回收。

* 線程生產者消費者問題以及多線程和線程池問題

* 設計模式-工廠模式 觀察者模式 適配器等常用模式

工廠模式是創建型的設計模式,通過這個可以瞭解如何創建對象,適配器模式是結構型模式,通過了解他來了解所有的結構型設計模式的方法,觀察者模式是行爲型模式,瞭解它知道行爲型的模式的作用。

工廠模式:平時我們新建一個類都是在需要的代碼中new一個,現在我們通過一個工程類來幫我們new一個我們需要的類返回給我們。

觀察者模式:類似於郵件訂閱和RSS訂閱,當一個對象變化時,其它依賴該對象的對象都會收到通知,並且隨着變化!對象之間是一種一對多的關係。

適配器模式:跟代理模式一樣,不是直接對得到這個類,而是同一個另一個類去得到這個類,並且加強了這個類的方法。跟代理模式一樣,等其他的結構型設計模式差不多。

* linux 常用命令寫出5到10個。

1ifconfig 2 systemctl start mariadb 3 ip addr 4reboot 0 5 mysql -uroot -ppassword 6 cd 7vi 8vim 9 cat 10 ls

* 鏈表的反向修改。

* String 爲什麼不可變,考察你的源碼分析

string是不可變的,他的內部有value hash二個成員變量都沒有set方法,所以外部都無法修改它。一般使用string池來銷燬和生成string。

* int 等一些基本數據類型的長度及所佔字節

    byte 8位 -128-127

    short 16位

    int  32

    long 64

    float 32位  0.0f

    double 0.0d

    boolean false

    char 16 位 Unicode 字符;最小值是 \u0000(即爲0); 最大值是 \uffff(即爲65,535);

* spring  ioc的實現原理

IoC理論:藉助於“第三方”實現具有依賴關係的對象之間的解耦,

        1) 軟件系統在沒有引入IoC容器之前,對象A依賴對象B,那麼A對象在實例化或者運行到某一點的時候,自己必須主動創建對象

          B或者使用已經創建好的對象B,其中不管是創建還是使用已創建的對象B,控制權都在我們自己手上。

        2)如果軟件系統引入了Ioc容器之後,對象A和對象B之間失去了直接聯繫,所以,當對象A實例化和運行時,如果需要對象B的

          話,IoC容器會主動創建一個對象B注入到對象A所需要的地方。

        3)通過前面的對比,可以看到對象A獲得依賴對象B的過程,由主動行爲變成了被動行爲,即把創建對象交給了IoC容器處理,控

          制權顛倒過來了,這就是控制反轉的由來!

        IOC原理 這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,即所謂反轉。

    Bean的生命週期:

        spring bean的完整生命週期從創建Spring容器開始,知道spring容器銷燬bean.

        bean自身的方法,Bean本身調用的方法和通過配置文件中的init-method和destroy-method指定的方法

        Bean級生命週期接口方法  BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean這些接口的方法

        容器級生命週期接口方法  InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 這兩個接口實現,

        一般稱它們的實現類爲“後處理器”。

        工廠後處理器接口方法    AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等

        非常有用的工廠後處理器  接口的方法。工廠後處理器也是容器級的。在應用上下文裝配配置文件之後立即調用

            實例BeanFactoryPostProcessor實例化出

                容器級別生命週期接口 BeanPostProcessor ,InstantiationAwareBeanPostProcessor 。

                InstantiationAwareBeanPostProcessor 執行before方法對對象屬性進行修改

                在執行Bean構造器

                InstantiationAwareBeanPostProcessor 執行Property方法

                爲bean注入屬性

                調用Bean級生命週期接口方法

                BeanNameAware  BeanFactoryAware

                調用容器級生命週期接口方法

                    BeanPostProcessor

                調用Bean級生命週期接口方法

                InitializingBean

                調用Bean自身的方法

                nit-method

                調用容器級生命週期接口方法

                BeanPostProcessor  after方法 修改對象屬性

                InstantiationAwareBeanPostProcessor  after方法 修改對象屬性

                ....初始化成功後正常使用......

                調用Bean級生命週期接口方法

                DiposableBean

                調用Bean自身的方法

                destroy-method

                銷燬

* springmvc流程

1.用戶向服務器發送請求,請求被Spring 前端控制Servelt DispatcherServlet捕獲;

    2.DispatcherServlet對請求URL進行解析,得到請求資源標識符(URI)。然後根據該URI,調用HandlerMapping獲得

            該Handler配置的所有相關的對象(包括Handler對象以及Handler對象對應的攔截器),最後以HandlerExecutionChain

            對象的形式返回;

    3.DispatcherServlet 根據獲得的Handler,選擇一個合適的HandlerAdapter。(附註:如果成功獲得HandlerAdapter後,

            此時將開始執行攔截器的preHandler(...)方法)

            4.提取Request中的模型數據,填充Handler入參,開始執行Handler(Controller)。 在填充Handler的入參過程中,

            根據你的配置,

            Spring將幫你做一些額外的工作:

            HttpMessageConveter:將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換爲指定的響應信息

            數據轉換:對請求消息進行數據轉換。如String轉換成Integer、Double等

            數據根式化:對請求消息進行數據格式化。 如將字符串轉換成格式化數字或格式化日期等

            數據驗證: 驗證數據的有效性(長度、格式等),驗證結果存儲到BindingResult或Error中

    5.Handler執行完成後,向DispatcherServlet 返回一個ModelAndView對象;

    6.根據返回的ModelAndView,選擇一個適合的ViewResolver(必須是已經註冊到Spring容器中的ViewResolver)

        返回給DispatcherServlet ;

    7.ViewResolver 結合Model和View,來渲染視圖

    8.將渲染結果返回給客戶端

* java 三大特性講解一二。多態講解

封裝,繼承,多態

封裝:封裝隱藏了類的內部實現機制,可以在不影響使用的情況下改變類的內部結構,同時也保護了數據。對外界而已它的內部細節是隱藏的,暴露給外界的只是它的訪問方法。

繼承:繼承是爲了重用父類代碼。

多態:Java實現多態有三個必要條件:繼承、重寫、向上轉型。實現方式:繼承和接口

多態就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在編程時並不確定,而是在程序運行期間才確定,即一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。因爲在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態,這就是多態性。

酒 a = 劍南春

酒 b = 五糧液

酒 c = 酒鬼酒

指向子類的父類引用由於向上轉型了,它只能訪問父類中擁有的方法和屬性,而對於子類中存在而父類中不存在的方法,該引用是不能使用的,儘管是重載該方法。若子類重寫了父類中的某些方法,在調用該些方法的時候,必定是使用子類中定義的這些方法(動態連接、動態調用)。

* javaIO的使用,NIO的使用。

輸入輸出流:inputstream  outputstream 字節流字符流:“InputStraem,OutputStrem”,“Reader,Writer”,節點流和處理流:“直接連接io設備”,“將流包裝一下,”

NIO是基於緩衝的io讀寫,非阻塞IO,

IO是基於流的讀寫,阻塞IO。

* servlet的生命週期

1,初始化階段  調用init()方法

2,響應客戶請求階段  調用service()方法 調用doget方法或者dopost方法

3,終止階段  調用destroy()方法

* 內部類 等幾種內部類

簡單理解:一個類中定義了另加一個類,

好處:最大的好處就是可以多重繼承,加入你需要繼承二個實體類怎麼辦?一個子類只能繼承一個實現類或者抽象類,所以要使用內部類,因爲內部類可以獨立繼承其他類。

內部類分類:

1成員內部類:它是外圍類的一個成員。a 他可以隨意訪問所有外圍類的變量方法,但是外圍類只能實例化他來訪問它。b 成員內部類是依附於外圍類的,所以只有先創建了外圍類才能夠創建內部類。

2 局部內部類:他是方法內的內部類。對於這個類的使用主要是應用與解決比較複雜的問題,想創建一個類來輔助我們的解決方案,到那時又不希望這個類是公共可用的,所以就產生了局部內部類,局部內部類和成員內部類一樣被編譯,只是它的作用域發生了改變,它只能在該方法和屬性中被使用,出了該方法和屬性就會失效。

3 匿名內部類:匿名內部類是沒有訪問修飾符的

4 靜態內部類:關鍵字static中內部類,a 它的創建是不需要依賴於外圍類的。b 它不能使用任何外圍類的非static成員變量和方法。

* java 反射

java反射:是指在編譯期間不知道是哪個類別加載,只有在運行期間才被加載探知,自省,這種使用編譯期不知道的類,這種編譯特點就是反射。

在我們eclipse或者intellij打出某個類的點時會出現這個類方法和屬性,這就是利用了反射。我們在代碼中使用log4j時,使用這個反射機制,得到log的所有方法屬性。

* spring的線程池

線程池的使用情況,

* redis的使用,使用什麼api使用什麼jar,假如redis的連接數不夠怎麼辦

* 多線程問題

* equals() 與 hashcode()或 “==”

* final, finally, finalize的區別

* spring將傳遞的數據過來的數據封裝爲對象,並且做校驗

* 除了設計模式做單例模式其他的方法中如何做單例模式
可以加羣找我要課堂鏈接 注意:是免費的 沒有開發經驗誤入哦
1、具有1-5工作經驗的,面對目前流行的技術不知從何下手,需要突破技術瓶頸的。
2、在公司待久了,過得很安逸,但跳槽時面試碰壁。需要在短時間內進修、跳槽拿高薪的。
3、如果沒有工作經驗,但基礎非常紮實,對java工作機制,常用設計思想,常用java開發框架掌握熟練的。
4、覺得自己很牛B,一般需求都能搞定。但是所學的知識點沒有系統化,很難在技術領域繼續突破的。
5. 羣號:689024304備註好信息!
6.阿里Java高級大牛直播講解知識點,分享知識,多年工作經驗的梳理和總結,帶着大家全面、科學地建立自己的技術體系和技術認知!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章