日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

2019java 开发工程师 最新面试官 问的问题

發(fā)布時(shí)間:2023/12/14 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2019java 开发工程师 最新面试官 问的问题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.Java中的io流面試題

  • 什么是流?流分為哪幾種?
  • 答案:我給你打個(gè)比方你就明白了;比如你家的水龍頭的管道就是一個(gè)流:流又分為輸入輸出流,輸入流就是你家水龍頭抽水庫(kù)水的那頭,輸出流就是你家水龍頭流到你家大水缸的那頭。現(xiàn)在有個(gè)A.txt文件,你要讀取里面的信息,就相當(dāng)于水龍頭抽水庫(kù)水,然后讀取完后寫(xiě)入到另一個(gè)文件里面,就是相當(dāng)于水龍頭抽到水后流到大水缸。很簡(jiǎn)單吧,就是一進(jìn)一出的事,沒(méi)這么復(fù)雜

    1.1: 以流向來(lái)劃分(針對(duì)內(nèi)存):A.輸入流:文件—>內(nèi)存??? 讀文件B.輸出流:內(nèi)存—>文件??? 寫(xiě)文件2)從內(nèi)容劃分A.字節(jié)流:以8位的形式來(lái)處理,不能輸出漢字B.字符流:在字節(jié)流上進(jìn)行包裝得到的,可以處理字節(jié)流,也可以處理漢字??? 注:在最底層,所有的I/O操作都是字節(jié)流的形式,字符流是為了處理漢字方便,字節(jié)流的處理速度快

    ?

  • 字節(jié)流和字符流的區(qū)別?
  • 答: 字節(jié)流是按字節(jié)讀取或?qū)懭朐O(shè)備,但字符流是以字符為單位讀取或?qū)懭朐O(shè)備。

    如果是二進(jìn)制文件,需要用字節(jié)流讀取。一般來(lái)說(shuō),字符流只處理文本文件。在設(shè)備中,大多數(shù)情況是以字節(jié)形式存儲(chǔ)數(shù)據(jù)的,因此字符流通過(guò)需要傳入字節(jié)流當(dāng)參數(shù)。

  • 什么是緩存流?
  • 原文是這樣的意思,用BufferedReader封裝一個(gè)InputStream,再用DataInputStream封裝這個(gè)InputStream,這樣做之后,先用BufferedReader從流中讀取一行,然后分別用這個(gè)InputStream讀取一個(gè)字符和DataInputStream讀取一行,再用BufferedReader讀取一行,結(jié)果BufferedReader均能讀到數(shù)據(jù),而InputStream和DataInputStream均讀不到數(shù)據(jù).數(shù)據(jù)流中只有40多個(gè)字符。這說(shuō)明了,BufferedReader第一次讀取時(shí),就把這40多個(gè)字符都讀取出來(lái),緩沖起來(lái)了,后面每次讀的時(shí)候,都只是從緩沖里拿出來(lái)。40多個(gè)字符就一次被BufferedReader讀進(jìn)去緩存起來(lái)了,所以InputStream和DataInputStream就都讀不到字符了。?
    原文并猜想,如果流中的數(shù)據(jù)夠多到BufferedReader緩存不下來(lái)的時(shí)候,InputStream和DataInputStream就能讀到數(shù)據(jù)了。?

    注解:緩沖流分為字節(jié)和字符緩沖流

    字節(jié)緩沖流為:

    BufferedInputStream—字節(jié)輸入緩沖流

    BufferedOutputStream—字節(jié)輸出緩沖流

    字符緩沖流為:

    BufferedReader—字符輸入緩沖流

    BufferedWriter—字符輸出緩沖流

    下面主要介紹這四種緩沖流的使用。

    ?

    2.多線程面試問(wèn)題

  • 你所理解的多線程?
  • 多線程的概念:多線程是一種機(jī)制,它允許在程序中并發(fā)的執(zhí)行多個(gè)線程,且每個(gè)線程間相互獨(dú)立。
  • 實(shí)現(xiàn)多線程的兩種方式:
  • 1、繼承java.lang.Thread類(lèi),并且重寫(xiě)它的run方法,將線程的執(zhí)行主體放在其中;
  • 2、實(shí)現(xiàn)java.lang.Runnable接口,實(shí)現(xiàn)它的run方法,并將線程的執(zhí)行主體放在其中;
  • 線程有五大狀態(tài):
  • 1、新建狀態(tài)(New):使用new操作符創(chuàng)建一個(gè)線程的時(shí)候,線程還沒(méi)有開(kāi)始執(zhí)行;
  • 2、就緒狀態(tài)(Runnable):當(dāng)線程調(diào)用了start方法之后,線程就進(jìn)入就緒狀態(tài);處于就緒狀態(tài)的線程不一定立即運(yùn)行run方法,只有獲取到cpu時(shí)間才可以執(zhí)行run方法;
  • 3、運(yùn)行狀態(tài)(running):當(dāng)線程獲取到了cpu運(yùn)行時(shí)間之后,就進(jìn)入到運(yùn)行狀態(tài)了,調(diào)用run方法;
  • 4、阻塞狀態(tài)(blocked):正在運(yùn)行的線程還沒(méi)有結(jié)束,暫時(shí)讓出cpu,這時(shí)其他就緒線程就有機(jī)會(huì)獲得cpu時(shí)間;
  • 以下原因會(huì)導(dǎo)致線程進(jìn)入阻塞狀態(tài):
  • 1、線程調(diào)用sleep方法進(jìn)入睡眠狀態(tài);
  • 2、線程在調(diào)用一個(gè)在i/o上被阻塞的操作
  • 3、線程試圖去獲得一個(gè)鎖,但是這個(gè)鎖被其他線程持有;
  • 。。。。。。
  • 5、死亡狀態(tài)(Dead):
  • 有以下的原因可導(dǎo)致線程死亡:
  • 1run方法正常退出而正常死亡;
  • 2、一個(gè)未捕獲的異常導(dǎo)致線程意外退出而死亡;
  • 可以用isAlive方法來(lái)判斷線程是否還活著,只要是線程處于運(yùn)行或者阻塞狀態(tài),就返回true;如果線程狀態(tài)是New且不是可運(yùn)行的狀態(tài)或者線程死亡了,則返回false
  • ?
  • 線程同步(synchronized):
  • 可以同步方法,也可以同步代碼塊;對(duì)于同步方法來(lái)說(shuō),每個(gè)方法只有獲取到所屬類(lèi)實(shí)例的鎖才可以被執(zhí)行,一旦該方法被執(zhí)行,則獨(dú)占鎖,知道方法返回時(shí)或者異常退出時(shí)才會(huì)釋放掉鎖;
  • 同步代碼塊也是一樣,當(dāng)兩個(gè)并發(fā)線程訪問(wèn)同一個(gè)對(duì)象中的這個(gè)synchronizedthis)代碼塊的時(shí)候,一個(gè)時(shí)間內(nèi)只有一個(gè)線程得到執(zhí)行,另一個(gè)線程只有在這個(gè)線程執(zhí)行完成之后才可以執(zhí)行;
  • 線程同步之Lock
  • Lock是一個(gè)接口,它位于java 5.0新增的java.utils.concurrent包的子包locks中,實(shí)現(xiàn)Lock接口類(lèi)具有與synchronized關(guān)鍵字相同的功能,但是它的功能強(qiáng)大一些,java.utils.concurrent.locks.ReentrantLock是比較常用的;注意需要在finallyunlock釋放鎖;
  • 線程阻塞:
  • sleep()方法、suspendresume方法、yield方法、waitnotify方法都可以使線程進(jìn)入阻塞狀態(tài);但是yield方法和wait方法都會(huì)釋放cpu時(shí)間,而sleep方法和suspend不會(huì)釋放cpu時(shí)間;
  • 終止線程的方法:
  • 1、當(dāng)run方法執(zhí)行完畢,自動(dòng)終止;
  • 2、使用stop方法,不過(guò)這個(gè)方法不推薦使用,會(huì)有意料不到的后果;
  • 3、使用interrupt方法
  • 多個(gè)客戶端一個(gè)服務(wù)器的實(shí)現(xiàn)方法:
  • 利用多線程技術(shù),服務(wù)器socket負(fù)責(zé)監(jiān)聽(tīng)端口,設(shè)置一個(gè)無(wú)限循環(huán),在其中實(shí)現(xiàn):將監(jiān)聽(tīng)到的socket實(shí)例賦值 給線程并且啟動(dòng)線程,由線程來(lái)完成業(yè)務(wù)邏輯;
  • ?

  • 進(jìn)程與線程的區(qū)別?
  • ?

    答:程序的一次執(zhí)行就可以看作是一個(gè)進(jìn)程。進(jìn)程中又包含了許多的線程,進(jìn)程之間的內(nèi)存不可以共享,線程之間共享進(jìn)程的內(nèi)存。

  • 創(chuàng)建多線程的方式?
  • 一、繼承Thread類(lèi)創(chuàng)建線程類(lèi)

    1)定義Thread類(lèi)的子類(lèi),并重寫(xiě)該類(lèi)的run方法,該run方法的方法體就代表了線程要完成的任務(wù)。因此把run()方法稱(chēng)為執(zhí)行體。

    2)創(chuàng)建Thread子類(lèi)的實(shí)例,即創(chuàng)建了線程對(duì)象。

    3)調(diào)用線程對(duì)象的start()方法來(lái)啟動(dòng)該線程。

    二、通過(guò)Runnable接口創(chuàng)建線程類(lèi)

    1)定義runnable接口的實(shí)現(xiàn)類(lèi),并重寫(xiě)該接口的run()方法,該run()方法的方法體同樣是該線程的線程執(zhí)行體。

    2)創(chuàng)建 Runnable實(shí)現(xiàn)類(lèi)的實(shí)例,并依此實(shí)例作為Threadtarget來(lái)創(chuàng)建Thread對(duì)象,該Thread對(duì)象才是真正的線程對(duì)象。

    3)調(diào)用線程對(duì)象的start()方法來(lái)啟動(dòng)該線程。

    三、通過(guò)CallableFuture創(chuàng)建線程

    1)創(chuàng)建Callable接口的實(shí)現(xiàn)類(lèi),并實(shí)現(xiàn)call()方法,該call()方法將作為線程執(zhí)行體,并且有返回值。

    2)創(chuàng)建Callable實(shí)現(xiàn)類(lèi)的實(shí)例,使用FutureTask類(lèi)來(lái)包裝Callable對(duì)象,該FutureTask對(duì)象封裝了該Callable對(duì)象的call()方法的返回值。

    3)使用FutureTask對(duì)象作為Thread對(duì)象的target創(chuàng)建并啟動(dòng)新線程。

    4)調(diào)用FutureTask對(duì)象的get()方法來(lái)獲得子線程執(zhí)行結(jié)束后的返回值

    二、創(chuàng)建線程的三種方式的對(duì)比

    采用實(shí)現(xiàn)RunnableCallable接口的方式創(chuàng)見(jiàn)多線程時(shí),優(yōu)勢(shì)是:

    線程類(lèi)只是實(shí)現(xiàn)了Runnable接口或Callable接口,還可以繼承其他類(lèi)

    在這種方式下,多個(gè)線程可以共享同一個(gè)target對(duì)象,所以非常適合多個(gè)相同線程來(lái)處理同一份資源的情況,從而可以將CPU、代碼和數(shù)據(jù)分開(kāi),形成清晰的模型,較好地體現(xiàn)了面向?qū)ο蟮乃枷搿?/span>

    劣勢(shì)是

    編程稍微復(fù)雜,如果要訪問(wèn)當(dāng)前線程,則必須使用Thread.currentThread()方法。

    使用繼承Thread類(lèi)的方式創(chuàng)建多線程時(shí)優(yōu)勢(shì)是

    編寫(xiě)簡(jiǎn)單,如果需要訪問(wèn)當(dāng)前線程,則無(wú)需使用Thread.currentThread()方法,直接使用this即可獲得當(dāng)前線程。

    劣勢(shì)是

    線程類(lèi)已經(jīng)繼承了Thread類(lèi),所以不能再繼承其他父類(lèi)。

    ?

  • 悲觀鎖與樂(lè)觀鎖的區(qū)別?
  • 答:樂(lè)觀鎖適用于多讀的應(yīng)用類(lèi)型,這樣可以提高吞吐量,像數(shù)據(jù)庫(kù)如果提供類(lèi)似于write_condition機(jī)智的其實(shí)都是提供的樂(lè)觀鎖。 相反,如果經(jīng)常發(fā)生沖突,上層應(yīng)用會(huì)不斷進(jìn)行 retry,這樣反而降低了性能,所以這種情況下用悲觀鎖比較合適

  • 請(qǐng)說(shuō)出常見(jiàn)的線程方法以及作用?比如sleep()是用來(lái)使當(dāng)前線程暫停的等。
  • 1.start() 啟動(dòng)線程并執(zhí)行相應(yīng)的run()方法 ---run() 子線程要執(zhí)行的代碼放入run()方法。

    2.getName() 獲取此線程的名字?setName() 設(shè)置

    此線程的名字。

    3.join() 執(zhí)行調(diào)用join()方法線程),阻斷其他線程。

    4.sleep(毫秒)休眠。

    ?

    線程安全的理解?

    答 :線程安全就是多線程訪問(wèn)時(shí),采用了加鎖機(jī)制,當(dāng)一個(gè)線程訪問(wèn)該類(lèi)的某個(gè)數(shù)據(jù)時(shí),進(jìn)行保護(hù),其他線程不能進(jìn)行訪問(wèn)直到該線程讀取完,其他線程才可使用

  • sleep()方法與wait()方法的區(qū)別?
  • 答:對(duì)于sleep()方法,我們首先要知道該方法是屬于Thread類(lèi)中的。而wait()方法,則是屬于Object類(lèi)中的。

    sleep()方法導(dǎo)致了程序暫停執(zhí)行指定的時(shí)間,讓出cpu該其他線程,但是他的監(jiān)控狀態(tài)依然保持者,當(dāng)指定的時(shí)間到了又會(huì)自動(dòng)恢復(fù)運(yùn)行狀態(tài)。

    在調(diào)用sleep()方法的過(guò)程中,線程不會(huì)釋放對(duì)象鎖。

    而當(dāng)調(diào)用wait()方法的時(shí)候,線程會(huì)放棄對(duì)象鎖,進(jìn)入等待此對(duì)象的等待鎖定池,只有針對(duì)此對(duì)象調(diào)用notify()方法后本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備

    ?

  • 你所理解的程序優(yōu)先級(jí)是怎么樣的?
  • 3.集合面試問(wèn)題(HashMap居多,問(wèn)的也有上機(jī)也有

  • HashMap和HashTable的區(qū)別?
  • ??1、繼承的父類(lèi)不同

    ? ? ??Hashtable繼承自Dictionary類(lèi),而HashMap繼承自AbstractMap類(lèi)。但二者都實(shí)現(xiàn)了Map接口。

    ?2、線程安全性不同

    ? ? ??javadoc中關(guān)于hashmap的一段描述如下:此實(shí)現(xiàn)不是同步的。如果多個(gè)線程同時(shí)訪問(wèn)一個(gè)哈希映射,而其中至少一個(gè)線程從結(jié)構(gòu)上修改了該映射,則它必須保持外部同步。

    ?

    ? ? ??Hashtable 中的方法是Synchronize的,而HashMap中的方法在缺省情況下是非Synchronize的。在多線程并發(fā)的環(huán)境下,可以直接使用Hashtable,不需要自己為它的方法實(shí)現(xiàn)同步,但使用HashMap時(shí)就必須要自己增加同步處理。(結(jié)構(gòu)上的修改是指添加或刪除一個(gè)或多個(gè)映射關(guān)系的任何操作;僅改變與實(shí)例已經(jīng)包含的鍵關(guān)聯(lián)的值不是結(jié)構(gòu)上的修改。)這一般通過(guò)對(duì)自然封裝該映射的對(duì)象進(jìn)行同步操作來(lái)完成。如果不存在這樣的對(duì)象,則應(yīng)該使用?Collections.synchronizedMap?方法來(lái)包裝該映射。最好在創(chuàng)建時(shí)完成這一操作,以防止對(duì)映射進(jìn)行意外的非同步訪問(wèn),如下所示:

    ? ? ??Map m = Collections.synchronizedMap(new HashMap(...));

    ? ? ??Hashtable 線程安全很好理解,因?yàn)樗總€(gè)方法中都加入了Synchronize。這里我們分析一下HashMap為什么是線程不安全的:

    ?

    ? ? ??HashMap底層是一個(gè)Entry數(shù)組,當(dāng)發(fā)生hash沖突的時(shí)候,hashmap是采用鏈表的方式來(lái)解決的,在對(duì)應(yīng)的數(shù)組位置存放鏈表的頭結(jié)點(diǎn)。對(duì)鏈表而言,新加入的節(jié)點(diǎn)會(huì)從頭結(jié)點(diǎn)加入。

    我們來(lái)分析一下多線程訪問(wèn):

    ?

    ? ? ??1)在hashmapput操作的時(shí)候會(huì)調(diào)用下面方法:

    ?

    [java]?view plain?copy

    ?

  • //?新增Entry。將“key-value”插入指定位置,bucketIndex是位置索引。??????
  • ????void?addEntry(int?hash,?K?key,?V?value,?int?bucketIndex)?{??????
  • ????????//?保存“bucketIndex”位置的值到“e”??????
  • ????????Entry<K,V>?e?=?table[bucketIndex];??????
  • ????????//?設(shè)置“bucketIndex”位置的元素為Entry”??????
  • ????????//?設(shè)置“e”Entry的下一個(gè)節(jié)點(diǎn)”??????
  • ????????table[bucketIndex]?=?new?Entry<K,V>(hash,?key,?value,?e);??????
  • ????????//?HashMap的實(shí)際大小?不小于?“閾值,則調(diào)整HashMap的大小??????
  • ????????if?(size++?>=?threshold)??????
  • ????????????resize(2?*?table.length);??????
  • ????}??
  • ?

    ? ? ??hashmapput操作的時(shí)候會(huì)調(diào)用到以上的方法。現(xiàn)在假如A線程和B線程同時(shí)對(duì)同一個(gè)數(shù)組位置調(diào)用addEntry,兩個(gè)線程會(huì)同時(shí)得到現(xiàn)在的頭結(jié)點(diǎn),然后A寫(xiě)入新的頭結(jié)點(diǎn)之后,B也寫(xiě)入新的頭結(jié)點(diǎn),那B的寫(xiě)入操作就會(huì)覆蓋A的寫(xiě)入操作造成A的寫(xiě)入操作丟失

    ? ? ??2)刪除鍵值對(duì)的代碼

    ?

    [java]?view plain?copy

    ?

  • <span?style="font-size:?18px;">??????</span>//?刪除鍵為key”的元素??????
  • ????final?Entry<K,V>?removeEntryForKey(Object?key)?{??????
  • ????????//?獲取哈希值。若keynull,則哈希值為0;否則調(diào)用hash()進(jìn)行計(jì)算??????
  • ????????int?hash?=?(key?==?null)???0?:?hash(key.hashCode());??????
  • ????????int?i?=?indexFor(hash,?table.length);??????
  • ????????Entry<K,V>?prev?=?table[i];??????
  • ????????Entry<K,V>?e?=?prev;??????
  • ?????
  • ????????//?刪除鏈表中鍵為key”的元素??????
  • ????????//?本質(zhì)是刪除單向鏈表中的節(jié)點(diǎn)”??????
  • ????????while?(e?!=?null)?{??????
  • ????????????Entry<K,V>?next?=?e.next;??????
  • ????????????Object?k;??????
  • ????????????if?(e.hash?==?hash?&&??????
  • ????????????????((k?=?e.key)?==?key?||?(key?!=?null?&&?key.equals(k))))?{??????
  • ????????????????modCount++;??????
  • ????????????????size--;??????
  • ????????????????if?(prev?==?e)??????
  • ????????????????????table[i]?=?next;??????
  • ????????????????else?????
  • ????????????????????prev.next?=?next;??????
  • ????????????????e.recordRemoval(this);??????
  • ????????????????return?e;??????
  • ????????????}??????
  • ????????????prev?=?e;??????
  • ????????????e?=?next;??????
  • ????????}??????
  • ?????
  • ????????return?e;??????
  • ????}??
  • ?

    ? ? ??當(dāng)多個(gè)線程同時(shí)操作同一個(gè)數(shù)組位置的時(shí)候,也都會(huì)先取得現(xiàn)在狀態(tài)下該位置存儲(chǔ)的頭結(jié)點(diǎn),然后各自去進(jìn)行計(jì)算操作,之后再把結(jié)果寫(xiě)會(huì)到該數(shù)組位置去,其實(shí)寫(xiě)回的時(shí)候可能其他的線程已經(jīng)就把這個(gè)位置給修改過(guò)了,就會(huì)覆蓋其他線程的修改

    ? ? ??3addEntry中當(dāng)加入新的鍵值對(duì)后鍵值對(duì)總數(shù)量超過(guò)門(mén)限值的時(shí)候會(huì)調(diào)用一個(gè)resize操作,代碼如下:

    [java]?view plain?copy

    ?

  • //?重新調(diào)整HashMap的大小,newCapacity是調(diào)整后的容量??????
  • ????void?resize(int?newCapacity)?{??????
  • ????????Entry[]?oldTable?=?table;??????
  • ????????int?oldCapacity?=?oldTable.length;?????
  • ????????//如果就容量已經(jīng)達(dá)到了最大值,則不能再擴(kuò)容,直接返回????
  • ????????if?(oldCapacity?==?MAXIMUM_CAPACITY)?{??????
  • ????????????threshold?=?Integer.MAX_VALUE;??????
  • ????????????return;??????
  • ????????}??????
  • ?????
  • ????????//?新建一個(gè)HashMap,將HashMap”的全部元素添加到HashMap”中,??????
  • ????????//?然后,將HashMap”賦值給HashMap”??????
  • ????????Entry[]?newTable?=?new?Entry[newCapacity];??????
  • ????????transfer(newTable);??????
  • ????????table?=?newTable;??????
  • ????????threshold?=?(int)(newCapacity?*?loadFactor);??????
  • ????}??
  • ? ? ??這個(gè)操作會(huì)新生成一個(gè)新的容量的數(shù)組,然后對(duì)原數(shù)組的所有鍵值對(duì)重新進(jìn)行計(jì)算和寫(xiě)入新的數(shù)組,之后指向新生成的數(shù)組。

    ?

    ? ? ??當(dāng)多個(gè)線程同時(shí)檢測(cè)到總數(shù)量超過(guò)門(mén)限值的時(shí)候就會(huì)同時(shí)調(diào)用resize操作,各自生成新的數(shù)組并rehash后賦給該map底層的數(shù)組table,結(jié)果最終只有最后一個(gè)線程生成的新數(shù)組被賦給table變量,其他線程的均會(huì)丟失。而且當(dāng)某些線程已經(jīng)完成賦值而其他線程剛開(kāi)始的時(shí)候,就會(huì)用已經(jīng)被賦值的table作為原始數(shù)組,這樣也會(huì)有問(wèn)題。

    ? ? ??3、是否提供contains方法

    ?

    ? ? ??HashMapHashtablecontains方法去掉了,改成containsValuecontainsKey,因?yàn)?/span>contains方法容易讓人引起誤解。

    ? ? ??Hashtable則保留了containscontainsValuecontainsKey三個(gè)方法,其中containscontainsValue功能相同。

    我們看一下HashtableContainsKey方法和ContainsValue的源碼:

    [java]?view plain?copy

    ?

  • public?boolean?containsValue(Object?value)?{??????
  • ?????return?contains(value);??????
  • ?}??
  • ?

    [java]?view plain?copy

    ?

  • //?判斷Hashtable是否包含(value)”??????
  • ?public?synchronized?boolean?contains(Object?value)?{??????
  • ?????//注意,Hashtable中的value不能是null??????
  • ?????//?若是null的話,拋出異常!??????
  • ?????if?(value?==?null)?{??????
  • ?????????throw?new?NullPointerException();??????
  • ?????}??????
  • ????
  • ?????//?從后向前遍歷table數(shù)組中的元素(Entry)??????
  • ?????//?對(duì)于每個(gè)Entry(單向鏈表),逐個(gè)遍歷,判斷節(jié)點(diǎn)的值是否等于value??????
  • ?????Entry?tab[]?=?table;??????
  • ?????for?(int?i?=?tab.length?;?i--?>?0?;)?{??????
  • ?????????for?(Entry<K,V>?e?=?tab[i]?;?e?!=?null?;?e?=?e.next)?{??????
  • ?????????????if?(e.value.equals(value))?{??????
  • ?????????????????return?true;??????
  • ?????????????}??????
  • ?????????}??????
  • ?????}??????
  • ?????return?false;??????
  • ?}??
  • ?

    [java]?view plain?copy

    ?

  • //?判斷Hashtable是否包含key??????
  • ?public?synchronized?boolean?containsKey(Object?key)?{??????
  • ?????Entry?tab[]?=?table;??????
  • /計(jì)算hash值,直接用keyhashCode代替????
  • ?????int?hash?=?key.hashCode();????????
  • ?????//?計(jì)算在數(shù)組中的索引值?????
  • ?????int?index?=?(hash?&?0x7FFFFFFF)?%?tab.length;??????
  • ?????//?找到“key對(duì)應(yīng)的Entry(鏈表)”,然后在鏈表中找出哈希值鍵值key都相等的元素??????
  • ?????for?(Entry<K,V>?e?=?tab[index]?;?e?!=?null?;?e?=?e.next)?{??????
  • ?????????if?((e.hash?==?hash)?&&?e.key.equals(key))?{??????
  • ?????????????return?true;??????
  • ?????????}??????
  • ?????}??????
  • ?????return?false;??????
  • ?}??
  • ? ? ??下面我們看一下HashMapContainsKey方法和ContainsValue的源碼:

    [java]?view plain?copy

    ?

  • //?HashMap是否包含key??????
  • ????public?boolean?containsKey(Object?key)?{??????
  • ????????return?getEntry(key)?!=?null;??????
  • ????}??
  • ?

    [java]?view plain?copy

    ?

  • //?返回鍵為key”的鍵值對(duì)??????
  • ????final?Entry<K,V>?getEntry(Object?key)?{??????
  • ????????//?獲取哈希值??????
  • ????????//?HashMap“keynull”的元素存儲(chǔ)在table[0]位置,“key不為null”的則調(diào)用hash()計(jì)算哈希值??????
  • ????????int?hash?=?(key?==?null)???0?:?hash(key.hashCode());??????
  • ????????//?hash值對(duì)應(yīng)的鏈表上查找鍵值等于key”的元素??????
  • ????????for?(Entry<K,V>?e?=?table[indexFor(hash,?table.length)];??????
  • ?????????????e?!=?null;??????
  • ?????????????e?=?e.next)?{??????
  • ????????????Object?k;??????
  • ????????????if?(e.hash?==?hash?&&??????
  • ????????????????((k?=?e.key)?==?key?||?(key?!=?null?&&?key.equals(k))))??????
  • ????????????????return?e;??????
  • ????????}??????
  • ????????return?null;??????
  • ????}??
  • ?

    [java]?view plain?copy

    ?

  • //?是否包含值為value”的元素??????
  • ????public?boolean?containsValue(Object?value)?{??????
  • ????//?“valuenull”,則調(diào)用containsNullValue()查找??????
  • ????if?(value?==?null)??????
  • ????????????return?containsNullValue();??????
  • ?????
  • ????//?“value不為null”,則查找HashMap中是否有值為value的節(jié)點(diǎn)。??????
  • ????Entry[]?tab?=?table;??????
  • ????????for?(int?i?=?0;?i?<?tab.length?;?i++)??????
  • ????????????for?(Entry?e?=?tab[i]?;?e?!=?null?;?e?=?e.next)??????
  • ????????????????if?(value.equals(e.value))??????
  • ????????????????????return?true;??????
  • ????return?false;??????
  • ????}??
  • 通過(guò)上面源碼的比較,我們可以得到第四個(gè)不同的地方

    ?

    ? ? ??4keyvalue是否允許null

    ? ? ??其中keyvalue都是對(duì)象,并且不能包含重復(fù)key,但可以包含重復(fù)的value

    ? ? ??通過(guò)上面的ContainsKey方法和ContainsValue的源碼我們可以很明顯的看出:

    ? ? ??Hashtable中,keyvalue都不允許出現(xiàn)null。但是如果在Hashtable中有類(lèi)似put(null,null)的操作,編譯同樣可以通過(guò),因?yàn)?/span>keyvalue都是Object類(lèi)型,但運(yùn)行時(shí)會(huì)拋出NullPointerException異常,這是JDK的規(guī)范規(guī)定的。
    HashMap中,null可以作為鍵這樣的鍵只有一個(gè);可以有一個(gè)或多個(gè)鍵所對(duì)應(yīng)的值為null。當(dāng)get()方法返回null值時(shí),可能是 HashMap中沒(méi)有該鍵,也可能使該鍵所對(duì)應(yīng)的值為null。因此,在HashMap中不能由get()方法來(lái)判斷HashMap中是否存在某個(gè)鍵, 而應(yīng)該用containsKey()方法來(lái)判斷。
    ?

    ? ? ??5、兩個(gè)遍歷方式的內(nèi)部實(shí)現(xiàn)上不同

    ? ? ??HashtableHashMap都使用了 Iterator。而由于歷史原因,Hashtable還使用了Enumeration的方式

    6hash值不同

    ? ? ??哈希值的使用不同,HashTable直接使用對(duì)象的hashCode。而HashMap重新計(jì)算hash值。

    ? ? ??hashCodejdk根據(jù)對(duì)象的地址或者字符串或者數(shù)字算出來(lái)的int類(lèi)型的數(shù)值。

    ? ? ??Hashtable計(jì)算hash值,直接用keyhashCode(),而HashMap重新計(jì)算了keyhash值,Hashtable在求hash值對(duì)應(yīng)的位置索引時(shí),用取模運(yùn)算,而HashMap在求位置索引時(shí),則用與運(yùn)算,且這里一般先用hash&0x7FFFFFFF后,再對(duì)length取模,&0x7FFFFFFF的目的是為了將負(fù)的hash值轉(zhuǎn)化為正值,因?yàn)?/span>hash值有可能為負(fù)數(shù),而&0x7FFFFFFF后,只有符號(hào)外改變,而后面的位都不變。

    7、內(nèi)部實(shí)現(xiàn)使用的數(shù)組初始化和擴(kuò)容方式不同

    HashTable在不指定容量的情況下的默認(rèn)容量為11,而HashMap16Hashtable不要求底層數(shù)組的容量一定要為2的整數(shù)次冪,而HashMap則要求一定為2的整數(shù)次冪。
    ? ? ??Hashtable擴(kuò)容時(shí),將容量變?yōu)樵瓉?lái)的2倍加1,而HashMap擴(kuò)容時(shí),將容量變?yōu)樵瓉?lái)的2倍。

    ? ? ??HashtableHashMap它們兩個(gè)內(nèi)部實(shí)現(xiàn)方式的數(shù)組的初始大小和擴(kuò)容的方式。HashTablehash數(shù)組默認(rèn)大小是11,增加的方式是 old*2+1

    注解詳細(xì):https://blog.csdn.net/wangxing233/article/details/79452946

  • HashMap的數(shù)據(jù)結(jié)構(gòu)?
  • 答:底層數(shù)組+鏈表實(shí)現(xiàn)。

  • HashMap的擴(kuò)容問(wèn)題?(這個(gè)應(yīng)該不常問(wèn))
  • 答:初始size為16,擴(kuò)容:newsize = oldsize*2,size一定為2的n次冪

    擴(kuò)容針對(duì)整個(gè)Map,每次擴(kuò)容時(shí),原來(lái)數(shù)組中的元素依次重新計(jì)算存放位置,并重新插入。

    插入元素后才判斷該不該擴(kuò)容,有可能無(wú)效擴(kuò)容(插入后如果擴(kuò)容,如果沒(méi)有再次插入,就會(huì)產(chǎn)生無(wú)效擴(kuò)容)

    當(dāng)Map中元素總數(shù)超過(guò)Entry數(shù)組的75%,觸發(fā)擴(kuò)容操作,為了減少鏈表長(zhǎng)度,元素分配更均勻。

    ?

  • 如何解決HashMap鍵重復(fù)的問(wèn)題?
  • 答:對(duì)于HashMap而言,key是唯一的,不可以重復(fù)的。?所以,以相同的key 把不同的value插入到 Map中會(huì)導(dǎo)致舊元素被覆蓋,只留下最后插入的元素。?? 不過(guò),同一個(gè)對(duì)象可以作為值插入到map中,只要對(duì)應(yīng)的key不一樣。

  • ArrayList與LinkList的區(qū)別?
  • ArrayList和Vector使用了數(shù)組的實(shí)現(xiàn),可以認(rèn)為ArrayList或者Vector封裝了對(duì)內(nèi)部數(shù)組的操作,比如向數(shù)組中添加,刪除,插入新的元素或者數(shù)據(jù)的擴(kuò)展和重定向。

    LinkedList使用了循環(huán)雙向鏈表數(shù)據(jù)結(jié)構(gòu)。與基于數(shù)組ArrayList相比,這是兩種截然不同的實(shí)現(xiàn)技術(shù),這也決定了它們將適用于完全不同的工作場(chǎng)景。

    詳細(xì):https://www.cnblogs.com/wwwcnblogscom/p/8036411.html

  • 其他集合也要看看(list和set)
  • 7.arrayListvector的區(qū)別

    1. Vector & ArrayList?
    1? Vector的方法都是同步的(Synchronized),是線程安全的(thread-safe),而ArrayList的方法不是,由于線程的同步必然要影響性能,因此,ArrayList的性能比Vector好。?
    2
    當(dāng)VectorArrayList中的元素超過(guò)它的初始大小時(shí),Vector會(huì)將它的容量翻倍,ArrayList只增加50%的大小,這樣,ArrayList就有利于節(jié)約內(nèi)存空間。

    2. Hashtable & HashMap?
    HashtableHashMap它們的性能方面的比較類(lèi)似 VectorArrayList,比如Hashtable的方法是同步的,HashMap的不是。
    3. ArrayList & LinkedList

    ArrayList的內(nèi)部實(shí)現(xiàn)是基于內(nèi)部數(shù)組Object[],所以從概念上講,它更象數(shù)組,但LinkedList的內(nèi)部實(shí)現(xiàn)是基于一組連接的記錄,所以,它更象一個(gè)鏈表結(jié)構(gòu),所以,它們?cè)谛阅苌嫌泻艽蟮牟顒e:?
    ??????
    從上面的分析可知,ArrayList的前面或中間插入數(shù)據(jù)時(shí),你必須將其后的所有數(shù)據(jù)相應(yīng)的后移,這樣必然要花費(fèi)較多時(shí)間,所以,當(dāng)你的操作是在一列 數(shù)據(jù)的后面添加數(shù)據(jù)而不是在前面或中間,并且需要隨機(jī)地訪問(wèn)其中的元素時(shí),使用ArrayList會(huì)提供比較好的性能; 而訪問(wèn)鏈表中的某個(gè)元素時(shí),就必須從鏈表的一端開(kāi)始沿著連接方向一個(gè)一個(gè)元素地去查找,直到找到所需的元素為止,所以,當(dāng)你的操作是在一列數(shù)據(jù)的前面或中 間添加或刪除數(shù)據(jù),并且按照順序訪問(wèn)其中的元素時(shí),就應(yīng)該使用LinkedList了。?
    ?

    如果在編程中,12兩種情形交替出現(xiàn),這時(shí),你可以考慮使用List這樣的通用接口,而不用關(guān)心具體的實(shí)現(xiàn),在具體的情形下,它的性能由具體的實(shí)現(xiàn)來(lái)保證。
    4. 配置集合類(lèi)的初始大小?
    ???
    Java集合框架中的大部分類(lèi)的大小是可以隨著元素個(gè)數(shù)的增加而相應(yīng)的增加的,我們似乎不用關(guān)心它的初始大小,但如果我們考慮類(lèi)的性能問(wèn)題時(shí),就一定要考慮盡可能地設(shè)置好集合對(duì)象的初始大小,這將大大提高代碼的性能。?
    ???
    比如,Hashtable缺省的初始大小為101,載入因子為0.75,即如果其中的元素個(gè)數(shù)超過(guò)75個(gè),它就必須增加大小并重新組織元素,所以,如果你 知道在創(chuàng)建一個(gè)新的Hashtable對(duì)象時(shí)就知道元素的確切數(shù)目如為110,那么,就應(yīng)將其初始大小設(shè)為110/0.75=148,這樣,就可以避免重 新組織內(nèi)存并增加大小。

    4.其他面試問(wèn)題(可能會(huì)有上機(jī)題需要手寫(xiě)的)

  • 手寫(xiě)單例模式(安全的或不安全的,多數(shù)寫(xiě)安全的
  • //不安全的單例模式

  • public?class?Singleton {
  • ????private?static?Singleton singleton = null;
  • ????private?Singleton(){}
  • ????public?static?Singleton getSingleton() {
  • ????????if(singleton == null) singleton = new?Singleton();
  • ????????return?singleton;
  • ????}
  • }
  • //安全的單例模式

    public?class?Singleton {

    ????private?static?volatile?Singleton singleton = null;

    ??

    ????private?Singleton(){}

    ??

    ????public?static?Singleton getSingleton(){

    ????????synchronized?(Singleton.class){

    ????????????if(singleton == null){

    ????????????????singleton = new?Singleton();

    ????????????}

    ????????}

    ????????return?singleton;

    ????}???

    }

    詳細(xì):https://www.cnblogs.com/shan1393/p/8992288.html

    ?

    5.手寫(xiě)冒泡排序 選擇排序? Arrays工具類(lèi)排序:

    package com.bdqn.test;

    ?

    import java.util.Arrays;

    import java.util.Comparator;

    ?

    public class SelectSortTest {

    ?? public static void main(String[] args) {

    ????? //定義一個(gè)選擇排序的方法

    ????? int[] arr= {2,-1,3,4,-9,2,3,5,8};

    ????? Integer[] arrInteger= {2,-1,3,4,-9,2,3,5,8};

    ????? System.out.println("選擇排序:");

    ????? selectSort(arr);

    ????? System.out.println("冒泡排序:");

    ????? puppleSort(arr);

    ????? System.out.println("使用Arrays工具類(lèi)排排序:");

    ????? arraysSort(arrInteger);

    ?? }

    ?? private static void selectSort(int[] arr) {

    ????????? for(int i=0;i<arr.length-1;i++) {

    ???????????? for(int j=i+1;j<arr.length;j++) {

    ??????????????? if(arr[i]>arr[j]) {

    ?????????????????? int temp=arr[i];

    ?????????????????? arr[i]=arr[j];

    ?????????????????? arr[j]=temp;

    ??????????????? }

    ???????????? }

    ????????? }

    ????????? //輸出排序后的集合

    ????????? System.out.println(Arrays.toString(arr));

    ?? }

    ?? private static void puppleSort(int[] arr) {

    ????? for(int i=0;i<arr.length-1;i++) {

    ????????? for(int j=0;j<arr.length-1-i;j++) {

    ???????????? if(arr[j]>arr[j+1]) {

    ??????????????? int temp=arr[j];

    ??????????????? arr[j]=arr[j+1];

    ??????????????? arr[j+1]=temp;?

    ???????????? }

    ????????? }

    ????? }

    ????? //輸出冒泡排序后的集合

    ????? System.out.println(Arrays.toString(arr));

    ?? }

    ?? //使用Arrays類(lèi)實(shí)現(xiàn)排序

    ?? public static void arraysSort(Integer[] arr) {

    ????? Arrays.sort(arr,new Comparator<Integer>() {

    ????????? @Override

    ????????? public int compare(Integer o1, Integer o2) {

    ???????????? return o1-o2;

    ????????? }

    ????? });

    ????? System.out.println(Arrays.toString(arr));

    ?? }

    }?

    ?

  • 抽象類(lèi)與接口的區(qū)別?
  • 答:1.抽象類(lèi)中可以有一個(gè)或多個(gè)抽象方法,而接口中的方法必須都是抽象方法

    2.接口中定義方法和成員變量和抽象類(lèi)中定義方法和成員變量接口中成員變量默認(rèn)被修飾為public static final常量

    3. 接口最大的一個(gè)特點(diǎn)就是可以實(shí)現(xiàn)多繼承,而抽象類(lèi)智能繼承一個(gè)(應(yīng)該說(shuō)java中只要是類(lèi)就只能單繼承)

    4. 4.抽象類(lèi)和方法必須使用abstract關(guān)鍵聲明為抽象,而接口中的方法默認(rèn)被修飾為public abstract類(lèi)型(默認(rèn)為公開(kāi)抽象的方法)

    詳細(xì):https://baijiahao.baidu.com/s?id=1568702144789321&wfr=spider&for=pc

  • Java面向?qū)ο蟮奶卣?#xff08;繼承與多態(tài)居多)?你是怎么理解的?
  • 答:1.封裝、繼承、多態(tài)

    理解:

    封裝把一類(lèi)對(duì)象,相似的屬性匯總到一起,組成一類(lèi),這個(gè)類(lèi)把該隱藏的隱藏,該暴露的暴露。

    繼承:涉及到父子類(lèi)的關(guān)系,自然可以得到父類(lèi)的特征,相對(duì)是父類(lèi)的擴(kuò)展,達(dá)到代碼重用的效果。

    例如:Java中用extends關(guān)鍵字,實(shí)現(xiàn)繼承類(lèi)被稱(chēng)為子類(lèi),被繼承類(lèi)被稱(chēng)為父類(lèi)。例如:水果和蘋(píng)果的關(guān)系,蘋(píng)果繼承了水果,蘋(píng)果是水果的子類(lèi),水果是蘋(píng)果的父類(lèi)。

    詳細(xì):https://blog.csdn.net/kisscatforever/article/details/79721937

  • String、StringBuffer和StringBuilder的區(qū)別?
  • 首先說(shuō)運(yùn)行速度,執(zhí)行速度,在這方面運(yùn)行速度快慢為:StringBuilder > StringBuffer > String
  • ?
  • String最慢的原因:

    String為字符串常量,而StringBuilderStringBuffer均為字符串變量,即String對(duì)象一旦創(chuàng)建之后該對(duì)象是不可更改的,但后兩者的對(duì)象是變量,是可以更改的。

    2. 再來(lái)說(shuō)線程安全

      在線程安全上,StringBuilder是線程不安全的,而StringBuffer是線程安全的

      如果一個(gè)StringBuffer對(duì)象在字符串緩沖區(qū)被多個(gè)線程使用時(shí),StringBuffer中很多方法可以帶有synchronized關(guān)鍵字,所以可以保證線程是安全的,但StringBuilder的方法則沒(méi)有該關(guān)鍵字,所以不能保證線程安全,有可能會(huì)出現(xiàn)一些錯(cuò)誤的操作。所以如果要進(jìn)行的操作是多線程的,那么就要使用StringBuffer,但是在單線程的情況下,還是建議使用速度比較快的StringBuilder

    ?總結(jié)一下
      String:適用于少量的字符串操作的情況

      StringBuilder:適用于單線程下在字符緩沖區(qū)進(jìn)行大量操作的情況

      StringBuffer:適用多線程下在字符緩沖區(qū)進(jìn)行大量操作的情況

    ?? 詳細(xì):https://www.cnblogs.com/su-feng/p/6659064.html

  • 數(shù)據(jù)庫(kù)SQL語(yǔ)句的編寫(xiě)能力(自己多練練)
  • :insert [into] <表名> (列名) values (列值)
  • 例:insert into Strdents (姓名,性別,出生日期) values ('開(kāi)心朋朋','','1980/6/15')

  • delete from <表名> [where <刪除條件>]
  • ?delete from a where name='開(kāi)心朋朋'(刪除表a中列值為開(kāi)心朋朋的行)

  • update <表名> set <列名=更新值> [where <更新條件>]
    例:update tongxunlu set 年齡=18 where 姓名='藍(lán)色小名'
  • select <列名> from <表名> [where <查詢條件表達(dá)試>] [order by <排序的列名>[ascdesc]] 升序? 倒序
  • 詳細(xì)https://www.cnblogs.com/daxueshan/p/6687521.html

  • 數(shù)據(jù)庫(kù)中有哪些函數(shù)?比如COUNT(),ORDER BY 的作用啊,放在SQL語(yǔ)句中的哪個(gè)位置等。
  • 1.去重 DISTINCT?

  • ASCII:返回與指定的字符對(duì)應(yīng)的十進(jìn)制數(shù)
  • CHR:給出整數(shù),返回對(duì)應(yīng)的字符
  • CONCAT:連接兩個(gè)字符串
  • INITCAP:返回字符串并將字符串的第一個(gè)字母變?yōu)榇髮?xiě)
  • INSTR(C1,C2,I,J):在一個(gè)字符串中搜索指定的字符,返回發(fā)現(xiàn)指定的字符的位置
  • LENGTH:返回字符串的長(zhǎng)度
  • LOWER:大寫(xiě)
  • UPPER:小寫(xiě)
  • TRIM(文字列 )? 文字列去空格
  • LTRIM(文字列 ) 文字列左側(cè)去空格
  • RTRIM(文字列 ) 文字列右側(cè)去空格
  • SOUNDEX:返回一個(gè)與給定的字符串讀音相同的字符串
  • ABS:返回指定值的絕對(duì)值
  • ACOS:給出反正弦的值
  • ATAN:返回一個(gè)數(shù)字的反正切值
  • CEIL:返回大于或等于給出數(shù)字的最小整數(shù)
  • COS:返回一個(gè)給定數(shù)字的余弦
  • COSH:返回一個(gè)數(shù)字反余弦值
  • EXP:返回一個(gè)數(shù)字e的n次方根
  • FLOOR:對(duì)給定的數(shù)字取整數(shù)
  • LN:返回一個(gè)數(shù)字的對(duì)數(shù)值
  • LOG(n1,n2):返回一個(gè)以n1為底n2的對(duì)數(shù)
  • MOD(n1,n2):返回一個(gè)n1除以n2的余數(shù)
  • POWER:返回n1的n2次方根
  • ROUND:四舍五入
  • SIGN:取數(shù)字n的符號(hào),大于0返回1,小于0返回-1,等于0返回0
  • SIN:返回一個(gè)數(shù)字的正弦值
  • SIGH:返回雙曲正弦的值
  • SQRT:返回?cái)?shù)字n的根
  • TAN:回?cái)?shù)字的正切值
  • TANH:返回?cái)?shù)字n的雙曲正切值
  • ADD_MONTHS:增加或減去月份
  • LAST_DAY:返回日期的最后一天
  • MONTHS_BETWEEN(date2,date1):給出date2-date1的月份
  • NEW_TIME(date,'this','that'):給出在this時(shí)區(qū)=other時(shí)區(qū)的日期和時(shí)間
  • NEXT_DAY(date,'day'):給出日期date和星期x之后計(jì)算下一個(gè)星期的日期
  • CHARTOROWID:將字符數(shù)據(jù)類(lèi)型轉(zhuǎn)換為ROWID類(lèi)型
  • CONVERT:將一種數(shù)據(jù)類(lèi)型轉(zhuǎn)換為另一種數(shù)據(jù)類(lèi)型
  • HEXTORAW:將一個(gè)十六進(jìn)制構(gòu)成的字符串轉(zhuǎn)換為二進(jìn)制
  • RAWTOHEXT:將一個(gè)二進(jìn)制構(gòu)成的字符串轉(zhuǎn)換為十六進(jìn)制
  • ROWIDTOCHAR:將ROWID數(shù)據(jù)類(lèi)型轉(zhuǎn)換為字符類(lèi)型
  • TO_CHAR(date,'format')
  • TO_DATE(string,'format'):將字符串轉(zhuǎn)化為ORACLE中的一個(gè)日期
  • TO_MULTI_BYTE:將字符串中的單字節(jié)字符轉(zhuǎn)化為多字節(jié)字符
  • TO_NUMBER:將給出的字符轉(zhuǎn)換為數(shù)字
  • CONVERT('x','desc','source'):將x字段或變量的源source轉(zhuǎn)換為desc
  • DUMP(s,fmt,start,length):DUMP函數(shù)以fmt指定的內(nèi)部數(shù)字格式返回一個(gè)VARCHAR2類(lèi)型的值
  • GREATEST:返回一組表達(dá)式中的最大值,即比較字符的編碼大小
  • LEAST:返回一組表達(dá)式中的最小值
  • UID:返回標(biāo)識(shí)當(dāng)前用戶的唯一整數(shù)
  • USER:返回當(dāng)前用戶的名字
  • USEREVN:返回當(dāng)前用戶環(huán)境的信息
  • AVG(DISTINCT|ALL):all表示對(duì)所有的值求平均值,distinct只對(duì)不同的值求平均值
  • .MAX(DISTINCT|ALL):求最大值,ALL表示對(duì)所有的值求最大值,DISTINCT表示對(duì)不同的值求最大值,相同的只取一次
  • MIN(DISTINCT|ALL):求最小值,ALL表示對(duì)所有的值求最小值,DISTINCT表示對(duì)不同的值求最小值,相同的只取一次
  • STDDEV(distinct|all):求標(biāo)準(zhǔn)差,ALL表示對(duì)所有的值求標(biāo)準(zhǔn)差,DISTINCT表示只對(duì)不同的值求標(biāo)準(zhǔn)差
  • GROUP BY:主要用來(lái)對(duì)一組數(shù)進(jìn)行統(tǒng)計(jì)
  • HAVING:對(duì)分組統(tǒng)計(jì)再加限制條件
  • ORDER BY:用于對(duì)查詢到的結(jié)果進(jìn)行排序輸出
  • 兩個(gè)不同的項(xiàng)目是如何進(jìn)行通信的?
  • 不同項(xiàng)目之間的通信方式分為,http、socket、webservice;其中socket通信的效率最高,youtube就采用的是原始的socket通信,他們信奉的原則是簡(jiǎn)單有效。

    一、http通信:

    ????Http通信主要有兩種方式POST方式和GET方式。前者通過(guò)Http消息實(shí)體發(fā)送數(shù)據(jù)給服務(wù)器,安全性高,數(shù)據(jù)傳輸大小沒(méi)有限制,后者通過(guò)URL的查詢字符串傳遞給服務(wù)器參數(shù),以明文顯示在瀏覽器地址欄,保密性差,最多傳輸2048個(gè)字符。但是GET請(qǐng)求并不是一無(wú)是處——GET請(qǐng)求大多用于查詢(讀取資源),效率高。POST請(qǐng)求用于注冊(cè)、登錄等安全性較高且向數(shù)據(jù)庫(kù)中寫(xiě)入數(shù)據(jù)的操作。除了POST和GET,http通信還有其他方式!請(qǐng)參見(jiàn)http請(qǐng)求的方法

    二、webservice

    應(yīng)用場(chǎng)景:跨防火墻的通信、應(yīng)用程序集成、B2B的集成、軟件和數(shù)據(jù)重用

    三、socket

    socket“open—write/read—close”模式的一種實(shí)現(xiàn)

    java socket通信已經(jīng)被封裝好了主要使用兩個(gè)類(lèi)ServerSocket Socket

    詳細(xì):https://blog.csdn.net/sunshine_silence/article/details/78771198

  • 你從上家公司離職的原因?
  • 說(shuō)說(shuō)你在上家公司做的最有難度和最有挑戰(zhàn)的功能模塊?
  • ?

    框架面試問(wèn)題(簡(jiǎn)歷上有寫(xiě)的就會(huì)問(wèn)到,沒(méi)寫(xiě)的他們公司要求用到的也可能會(huì)問(wèn))

    5.Spring面試問(wèn)題

  • Spring框架的兩大核心?
  • Spring的三大核心思想:IOC(控制反轉(zhuǎn)),DI(依賴(lài)注入),AOP(面向切面編程)。

    ?

    (1)IOC(控制反轉(zhuǎn))

    實(shí)現(xiàn)將組件間的關(guān)系從程序內(nèi)部提到外部容器(spring的xml)來(lái)管理首先外部容器(spring.xml)中會(huì)動(dòng)態(tài)的注冊(cè)業(yè)務(wù)所需的對(duì)象(接口/類(lèi))

    2)DI(依賴(lài)注入)

    組件之間的依賴(lài)關(guān)系由容器在應(yīng)用系統(tǒng)運(yùn)行期來(lái)決定, 也就是由容器動(dòng)態(tài)地將某種依賴(lài)關(guān)系的目標(biāo)對(duì)象實(shí)例注入到應(yīng)用系統(tǒng)中的各個(gè)關(guān)聯(lián)的組件之中

    (3)?AOP(面向切面編程)?

    ??利用一種稱(chēng)為"橫切"的技術(shù),剖解開(kāi)封裝的對(duì)象內(nèi)部,并將那些影響了多個(gè)類(lèi)的公共行為封裝到一個(gè)可重用模塊,并將其命名為"Aspect",即切面。所謂"切面",簡(jiǎn)單說(shuō)就是那些與業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼,降低模塊之間的耦合度,并有利于未來(lái)的可操作性和可維護(hù)性。

    詳細(xì)https://blog.csdn.net/u010688011/article/details/79431778

  • Spring框架的原理?
  • 就是讓對(duì)象與對(duì)象(模塊與模塊)之間的關(guān)系沒(méi)有通過(guò)代碼來(lái)關(guān)聯(lián),都是通過(guò)配置類(lèi)說(shuō)明管理的(Spring根據(jù)這些配置 內(nèi)部通過(guò)反射去動(dòng)態(tài)的組裝對(duì)象)?

    ?

    詳細(xì):https://www.cnblogs.com/zhoudi/p/5820513.html?

  • 說(shuō)一下SSM或SSH三大框架的整合思路?
  • struts2 與 Spring整合要解決的核心問(wèn)題是,如何在action中獲得被spring管理的service
  • 解決思路:
  • ??1: 想辦法讓action具有 自動(dòng)注入的功能;

    ??2: 讓action納入spring管理;

    ? ?????spring與hibernate整合兩種方式:

    1. 零障礙整合;

    2. Spring管理hibernate配置;

    ?1.零障礙整合:

    ?在spring的配置文件applicationContext.xml中配置bean: 并引入hibernate的核心配置文件;

    2.spring管理hibernate配置:將hibernate的核心配置文件 hibernate.cfg.xml中的內(nèi)容遷移到 applicationContext.xml中;

    SSM:

    1、dao層

      1.1、必須數(shù)據(jù):

           pojo(java實(shí)體)、mapper接口(dao接口)、sql映射文件(翻譯為jdbc中的statement)

      1.2、配置文件:

       mybatis核心配置文件:SqlMapConfig.xml

    自定義別名

      spring整合mybatis配置文件:applicationContext-dao.xml

             數(shù)據(jù)源

             會(huì)化工廠

             mapper掃描(加載dao)

           其他配置:

             數(shù)據(jù)庫(kù)信息:db.properties

             日志信息:log4j.properties

    2、service層

      2.1、配置文件:

           注解掃描:@service(加載service)applicationContext-service.xml

           事務(wù)配置: ApplicationContext-trans.xml

    3、controller層

      3.1、配置文件: springMVC.xml

           注解掃描:@controller(加載controller)

           注解驅(qū)動(dòng):自動(dòng)加載最新的處理器映射器、處理器適配器

           視圖解析器:

           自定義類(lèi)型轉(zhuǎn)化器:(掛載于注解驅(qū)動(dòng))

           文件上傳解析器:

           json格式數(shù)據(jù)解析器:(若沒(méi)有配置注解驅(qū)動(dòng),則需要顯示的在處理器適配器掛載)

           全局異常處理器:

           自定義攔截器:

           靜態(tài)資源放行:

           

    4、web.xml web.xml

      4.1、spring監(jiān)聽(tīng)器

      4.2、springMVC前端控制器

      4.3、post中文亂碼請(qǐng)求

    原文:https://blog.csdn.net/u010758410/article/details/80145521

  • Spring框架中AOP的實(shí)現(xiàn)原理是什么?
  • 4.1先以靜態(tài)代理實(shí)現(xiàn),靜態(tài)代理關(guān)鍵是在代理對(duì)象和目標(biāo)對(duì)象實(shí)現(xiàn)共同的接口,并且代理對(duì)象持有目標(biāo)對(duì)象的引用。

    4.2:動(dòng)態(tài)代理實(shí)現(xiàn)主要是實(shí)現(xiàn)InvocationHandler,并且將目標(biāo)對(duì)象注入到代理對(duì)象中,利用反射機(jī)制來(lái)執(zhí)行目標(biāo)對(duì)象的方法。

    6.SpingMVC面試問(wèn)題

  • SpringMVC框架與Struts2框架的區(qū)別?
  • ?一、框架機(jī)制

    spring mvc 和 struts2的加載機(jī)制不同:spring mvc的入口是servlet,而struts2是filter(servlet和filter區(qū)別見(jiàn)本文最后)

    1、Struts2采用Filter(StrutsPrepareAndExecuteFilter)實(shí)現(xiàn),SpringMVC(DispatcherServlet)則采用Servlet實(shí)現(xiàn)。

    2、Filter在容器啟動(dòng)之后即初始化;服務(wù)停止以后墜毀,晚于Servlet。Servlet在是在調(diào)用時(shí)初始化,先于Filter調(diào)用,服務(wù)停止后銷(xiāo)毀。

    二、攔截機(jī)制

    1、Struts2

    a、Struts2框架是類(lèi)級(jí)別的攔截,每次請(qǐng)求就會(huì)創(chuàng)建一個(gè)Action,和Spring整合時(shí)Struts2的ActionBean注入作用域是原型模式prototype(否則會(huì)出現(xiàn)線程并發(fā)問(wèn)題),然后通過(guò)setter,getter吧request數(shù)據(jù)注入到屬性。
    b、Struts2中,一個(gè)Action對(duì)應(yīng)一個(gè)request,response上下文,在接收參數(shù)時(shí),可以通過(guò)屬性接收,這說(shuō)明屬性參數(shù)是讓多個(gè)方法共享的。
    c、Struts2中Action的一個(gè)方法可以對(duì)應(yīng)一個(gè)url,而其類(lèi)屬性卻被所有方法共享,這也就無(wú)法用注解或其他方式標(biāo)識(shí)其所屬方法了
    ?
    2、SpringMVC
    a、SpringMVC是方法級(jí)別的攔截,一個(gè)方法對(duì)應(yīng)一個(gè)Request上下文,所以方法直接基本上是獨(dú)立的,獨(dú)享request,response數(shù)據(jù)。而每個(gè)方法同時(shí)又何一個(gè)url對(duì)應(yīng),參數(shù)的傳遞是直接注入到方法中的,是方法所獨(dú)有的。處理結(jié)果通過(guò)ModeMap返回給框架。
    b、在Spring整合時(shí),SpringMVC的Controller Bean默認(rèn)單例模式Singleton,所以默認(rèn)對(duì)所有的請(qǐng)求,只會(huì)創(chuàng)建一個(gè)Controller,有應(yīng)為沒(méi)有共享的屬性,所以是線程安全的,如果要改變默認(rèn)的作用域,需要添加@Scope注解修改。

    三、性能方面
    SpringMVC實(shí)現(xiàn)了零配置,由于SpringMVC基于方法的攔截,有加載一次單例模式bean注入。而Struts2是類(lèi)級(jí)別的攔截,每次請(qǐng)求對(duì)應(yīng)實(shí)例一個(gè)新的Action,需要加載所有的屬性值注入,所以,SpringMVC開(kāi)發(fā)效率和性能高于Struts2。
    四、攔截機(jī)制
    Struts2有自己的攔截Interceptor機(jī)制,SpringMVC這是用的是獨(dú)立的Aop方式,這樣導(dǎo)致Struts2的配置文件量還是比SpringMVC大。
    五、配置方面
    spring MVC和Spring是無(wú)縫的。從這個(gè)項(xiàng)目的管理和安全上也比Struts2高(當(dāng)然Struts2也可以通過(guò)不同的目錄結(jié)構(gòu)和相關(guān)配置做到SpringMVC一樣的效果,但是需要xml配置的地方不少)。
    SpringMVC可以認(rèn)為已經(jīng)100%零配置。

    六、設(shè)計(jì)思想
    Struts2更加符合OOP的編程思想, SpringMVC就比較謹(jǐn)慎,在servlet上擴(kuò)展。
    七、集成方面

    SpringMVC集成了Ajax,使用非常方便,只需一個(gè)注解@ResponseBody就可以實(shí)現(xiàn),然后直接返回響應(yīng)文本即可,而Struts2攔截器集成了Ajax,在Action中處理時(shí)一般必須安裝插件或者自己寫(xiě)代碼集成進(jìn)去,使用起來(lái)也相對(duì)不方便。

  • SpringMVC框架的特征?
  • 1.適配器? 試圖解析器? 映射器

  • 你對(duì)MVC模式的理解?
  • MVCModel—View—Controler的簡(jiǎn)稱(chēng)。即模型視圖控制器。MVC是一種設(shè)計(jì)模式,它強(qiáng)制性的把應(yīng)用程序的輸入、處理和輸出分開(kāi)。

    MVC中的模型、視圖、控制器它們分別擔(dān)負(fù)著不同的任務(wù)。

    視圖: 視圖是用戶看到并與之交互的界面。視圖向用戶顯示相關(guān)的數(shù)據(jù),并接受用戶的輸入。視圖不進(jìn)行任何業(yè)務(wù)邏輯處理。

    模型: 模型表示業(yè)務(wù)數(shù)據(jù)和業(yè)務(wù)處理。相當(dāng)于JavaBean。一個(gè)模型能為多個(gè)視圖提供數(shù)據(jù)。這提高了應(yīng)用程序的重用性

    控制器: 當(dāng)用戶單擊Web頁(yè)面中的提交按鈕時(shí),控制器接受請(qǐng)求并調(diào)用相應(yīng)的模型去處理請(qǐng)求。

    然后根據(jù)處理的結(jié)果調(diào)用相應(yīng)的視圖來(lái)顯示處理的結(jié)果。

    MVC的處理過(guò)程:首先控制器接受用戶的請(qǐng)求,調(diào)用相應(yīng)的模型來(lái)進(jìn)行業(yè)務(wù)處理,并返回?cái)?shù)據(jù)給控制器。控制器調(diào)用相應(yīng)的視圖來(lái)顯示處理的結(jié)果。并通過(guò)視圖呈現(xiàn)給用戶。

    詳細(xì):https://www.cnblogs.com/Alexander11/p/5621560.html

    7.Struts2面試題

  • Struts2框架中Action分為幾種,作用是什么?
  • 1普通的POJO類(lèi),該類(lèi)通常包含一個(gè)無(wú)參數(shù)的execute()方法,返回值為字符串類(lèi)型。

    2實(shí)現(xiàn)Action接口

    3繼承ActionSupport類(lèi)

  • 說(shuō)一下Struts2的執(zhí)行流程?
  • ? 首先運(yùn)行項(xiàng)目 所有請(qǐng)求被攔截器 攔截 然后交給Action 把數(shù)據(jù)返回給jsp頁(yè)面

    8.MyBatis和Hibernate

  • MyBatis框架和Hibernate框架兩者的區(qū)別?
  • 答:1:hibernate是全自動(dòng),而mybatis是半自動(dòng)。

    2.Hibernate數(shù)據(jù)庫(kù)移植性遠(yuǎn)大于mybatis

    3.hibernate擁有完整的日志系統(tǒng),mybatis則欠缺些

    4.mybatis相比hibernate需要關(guān)系很多細(xì)節(jié)

    5.sql直接優(yōu)化上,mybatis要比hibernate方便很多
    ? ??總結(jié):

    Mybatis:小巧、方便、高效、簡(jiǎn)單、直接、半自動(dòng)

    Hibernate:強(qiáng)大、方便、高效、復(fù)雜、繞彎子、全自動(dòng)

    詳細(xì):https://blog.csdn.net/w_q_q_/article/details/79032062

  • MyBatis框架的核心對(duì)象是什么?
  • 9.Dubbo面試問(wèn)題

  • dubbo是什么?
  • Dobbo是一個(gè)分布式框架,致力提供高性能和透明化的 PRC遠(yuǎn)程服務(wù)調(diào)用方案。簡(jiǎn)單說(shuō):,dobbo就是個(gè)服務(wù)框架,如果沒(méi)有分布式需求,其實(shí)不需要要用的,只要在分布式的時(shí)候,才有dubbo這樣的分布式服務(wù)框架的需求,并且本質(zhì)是個(gè)服務(wù)調(diào)用的東東,說(shuō)白了就是個(gè)遠(yuǎn)程調(diào)用分布式框架。

    其核心部分包含:
    1. 遠(yuǎn)程通訊: 提供對(duì)多種基于長(zhǎng)連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請(qǐng)求-響應(yīng)”模式的信息交換方式。
    2. 集群容錯(cuò): 提供基于接口方法的透明遠(yuǎn)程過(guò)程調(diào)用,包括多協(xié)議支持,以及軟負(fù)載均衡,失敗容錯(cuò),地址路由,動(dòng)態(tài)配置等集群支持。
    3. 自動(dòng)發(fā)現(xiàn): 基于注冊(cè)中心目錄服務(wù),使服務(wù)消費(fèi)方能動(dòng)態(tài)的查找服務(wù)提供方,使地址透明,使服務(wù)提供方可以平滑增加或減少機(jī)器。

    詳細(xì):https://blog.csdn.net/houshaolin/article/details/76408399

  • dubbo默認(rèn)使用的是什么通信框架?
  • 默認(rèn)調(diào)用netty框架,還有mian以及基于servlet等方式。

    詳細(xì):https://www.cnblogs.com/yang-lq/p/9168216.html

  • 服務(wù)調(diào)用是阻塞的嗎?
  • 默認(rèn)是阻塞的,可以異步調(diào)用,沒(méi)有返回值的可以這么做。

  • 一般使用什么注冊(cè)中心?還有別的選擇嗎?
  • 推薦使用zookeeper注冊(cè)中心,還有MulticastRedisSimple等。

  • 服務(wù)提供者能實(shí)現(xiàn)失效踢出是什么原理?
  • 服務(wù)失效踢出基于zookeeper的臨時(shí)節(jié)點(diǎn)原理。
  • 2. zookeeper中有兩種類(lèi)型的節(jié)點(diǎn):

    1.持久節(jié)點(diǎn)(PERSISENT):一旦創(chuàng)建,除非主動(dòng)調(diào)用刪除操作,否則一直存儲(chǔ)在zk上;

    2.臨時(shí)節(jié)點(diǎn)(EPHEMERAL):與客戶端會(huì)話綁定,一旦客戶端會(huì)話失效,這個(gè)客戶端所創(chuàng)建的所有臨時(shí)節(jié)點(diǎn)都會(huì)被移除;

    ??詳細(xì):https://www.jianshu.com/p/f42c69e4bd3e?fromApp=1

  • 同一個(gè)服務(wù)多個(gè)注冊(cè)的情況下可以直接連某一個(gè)服務(wù)嗎?
  • 可以直連,修改配置即可,也可以通過(guò)telnet直接某個(gè)服務(wù)。

  • 集群容錯(cuò)怎么做?
  • 讀操作建議使用Failover失敗自動(dòng)切換,默認(rèn)重試兩次其他服務(wù)器。寫(xiě)操作建議使用Failfast快速失敗,發(fā)一次調(diào)用失敗就立即報(bào)錯(cuò)。
  • 10.SpringBoot面試問(wèn)題

  • 你了解過(guò)SpringBoot框架嗎?講講你對(duì)它的理解?
  • SpringBoot+maven? 簡(jiǎn)化搭建以及開(kāi)發(fā)過(guò)程 是一個(gè)非常好的微服務(wù)開(kāi)發(fā)框架 可以快速搭建一個(gè)系統(tǒng)

  • 使用SpringBoot框架的好處?
  • 配置少 開(kāi)發(fā)和部署效率快?

  • SpringBoot框架中的監(jiān)聽(tīng)器是什么?
  • 監(jiān)聽(tīng)器是一個(gè)專(zhuān)門(mén)用于對(duì)其他對(duì)象身上發(fā)生的事件或狀態(tài)改變進(jìn)行監(jiān)聽(tīng)和相應(yīng)處理的對(duì)象,當(dāng)被監(jiān)視的對(duì)象發(fā)生情況時(shí),立即采取相應(yīng)的行動(dòng)。
  • 此處我們以ServletRequestListener來(lái)舉例,先說(shuō)明一下,ServletRequestListener是一個(gè)接口,這個(gè)接口是用來(lái)監(jiān)聽(tīng)請(qǐng)求的,里面有兩個(gè)方法,分別是請(qǐng)求創(chuàng)建和請(qǐng)求銷(xiāo)毀。
  • 詳細(xì):https://blog.csdn.net/m0_38075425/article/details/81164501

    ?

    總結(jié)

    以上是生活随笔為你收集整理的2019java 开发工程师 最新面试官 问的问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。