2020金九銀十立刻結束,現爲你們整理了此次金九銀十面試阿里的面試題總結,都是我從朋友那拿到的面試真題,話很少說,滿滿的乾貨分享給你們!java
是的。
注意點:面試
mov eax, dword ptr [b] mov dword ptr [a], eax
既然是兩條指令,那麼多個線程在執行這兩條指令時,某個線程可能會在第一條指令執行完畢後被剝奪CPU時間片,切換到另一個線程而產生不肯定的狀況。算法
5.6版本以後InnoDB存儲引擎開始支持全文索引,5.7版本以後經過使用ngram插件開始支持中文。以前僅支持英文,由於是經過空格做爲分詞的分隔符,對於中文來講是不合適的。MySQL容許在char、varchar、text類型上創建全文索引。後端
支持,補充:普通的增刪改 是表鎖,加入索引的增刪改是行鎖,執行查詢時不加任何鎖的。數組
在header中加入 --Connection:keep-alive。安全
阻塞指的是暫停一個線程的執行以等待某個條件發生(如某資源就緒)。
yield() 方法:yield() 使得線程放棄當前分得的 CPU 時間,可是不使線程阻塞,即線程仍處於可執行狀態,隨時可能再次分得 CPU 時間。調用 yield() 的效果等價於調度程序認爲該線程已執行了足夠的時間從而轉到另外一個線程。yield()只是使當前線程從新回到可執行狀態,因此執行yield()的線程有可能在進入到可執行狀態後立刻又被執行。sleep()可以使優先級低的線程獲得執行的機會,固然也可讓同優先級和高優先級的線程有執行的機會;yield()只能使同優先級的線程有執行的機會。服務器
不是。
網絡
JVM初始運行的時候都會分配好 Method Area(方法區) 和Heap(堆) ,而JVM 每遇到一個線程,就爲其分配一個 Program Counter Register(程序計數器) , VM Stack(虛擬機棧)和Native Method Stack (本地方法棧), 當線程終止時,三者(虛擬機棧,本地方法棧和程序計數器)所佔用的內存空間也會被釋放掉。這也是爲何我把內存區域分爲線程共享和非線程共享的緣由,非線程共享的那三個區域的生命週期與所屬線程相同,而線程共享的區域與JAVA程序運行的生命週期相同,因此這也是系統垃圾回收的場所只發生在線程共享的區域(實際上對大部分虛擬機來講只發生在Heap上)的緣由。多線程
方法區: 又叫靜態區,跟堆同樣,被全部的線程共享。它用於存儲已經被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。架構
window.postMessage() 方法能夠安全地實現跨源通訊。一般,對於兩個不一樣頁面的腳本,只有當執行它們的頁面位於具備相同的協議(一般爲https),端口號(443爲https的默認值),以及主機 (兩個頁面的模數 Document.domain設置爲相同的值) 時,這兩個腳本才能相互通訊。window.postMessage() 方法提供了一種受控機制來規避此限制,只要正確的使用,這種方法就很安全。
答:不必定。
答:是的。
CopyOnWriteArrayList使用了一種叫寫時複製的方法,當有新元素添加到CopyOnWriteArrayList時,先從原有的數組中拷貝一份出來,而後在新的數組作寫操做,寫完以後,再將原來的數組引用指向到新數組。建立新數組,並往新數組中加入一個新元素,這個時候,array這個引用仍然是指向原數組的。當元素在新數組添加成功後,將array這個引用指向新數組。
CopyOnWriteArrayList的整個add操做都是在鎖的保護下進行的。這樣作是爲了不在多線程併發add的時候,複製出多個副本出來,把數據搞亂了,致使最終的數組數據不是咱們指望的。
public boolean add(E e) { //一、先加鎖 final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); int len = elements.length; //二、拷貝數組 Object[] newElements = Arrays.copyOf(elements, len + 1); //三、將元素加入到新數組中 newElements[len] = e; //四、將array引用指向到新數組 setArray(newElements); return true; } finally { //五、解鎖 lock.unlock(); } }
因爲全部的寫操做都是在新數組進行的,這個時候若是有線程併發的寫,則經過鎖來控制,若是有線程併發的讀,則分幾種狀況:
可見,CopyOnWriteArrayList的讀操做是能夠不用加鎖的。
CopyOnWriteArrayList 有幾個缺點:
因爲寫操做的時候,須要拷貝數組,會消耗內存,
若是原數組的內容比較多的狀況下,可能致使young gc或者full gc
不能用於實時讀的場景,像拷貝數組、新增元素都須要時間,
因此調用一個set操做後,讀取到數據可能仍是舊的,
雖然CopyOnWriteArrayList 能作到最終一致性,可是仍是無法知足實時性要求;
CopyOnWriteArrayList 合適讀多寫少的場景,不過這類慎用
由於誰也無法保證CopyOnWriteArrayList 到底要放置多少數據,
萬一數據稍微有點多,每次add/set都要從新複製數組,這個代價實在過高昂了。
在高性能的互聯網應用中,這種操做分分鐘引發故障。
CopyOnWriteArrayList透露的思想
通常來說咱們使用時,會用一個線程向容器中添加元素,一個線程來讀取元素,而讀取的操做每每更加頻繁。寫操做加鎖保證了線程安全,讀寫分離保證了讀操做的效率,簡直完美。
若是這時候有第三個線程進行刪除元素操做,讀線程去讀取容器中最後一個元素,讀以前的時候容器大小爲i,當去讀的時候刪除線程忽然刪除了一個元素,這個時候容器大小變爲了i-1,讀線程仍然去讀取第i個元素,這時候就會發生數組越界。
測試一下,首先向CopyOnWriteArrayList裏面塞10000個測試數據,啓動兩個線程,一個不斷的刪除元素,一個不斷的讀取容器中最後一個數據。
public void test(){ for(int i = 0; i<10000; i++){ list.add("string" + i); } new Thread(new Runnable() { @Override public void run() { while (true) { if (list.size() > 0) { String content = list.get(list.size() - 1); }else { break; } } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { if(list.size() <= 0){ break; } list.remove(0); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); }
java類是單繼承的。classB extends classA
java接口能夠多繼承。Interface3 extends Interface0, Interface1, interface……
不容許類多重繼承的主要緣由是,若是A同時繼承B和C,而B和C同時有一個D方法,A如何決定該繼承那一個呢?
但接口不存在這樣的問題,接口全都是抽象方法繼承誰都無所謂,因此接口能夠繼承多個接口。
答:false。
java中byte的取值範圍是-128~127,發生上溢下溢時要模256;130>127上溢,故模256得130,仍溢出,再減256得-126,因此s=-126。300>127上溢,故模256得44,44在byte取值範圍內,故s=44.
300 的 二進制是:100101100;byte強制轉換後從右往左取8位爲:00101100;由於第八位爲0因此爲正數,又知道正數的原反補碼都相同;因此00101100轉換爲十進制是:44(32+8+4)
(byte)100+(short)200,byte和short的結果會自動轉爲short不會溢出。因此(byte)100+(short)200=(short)300,而(byte)300的結果是44.即二者不相等。
A.進程管理主要是對程序進行管理
B.存儲管理主要管理內存資源
C.文件管理能夠有效的支持對文件的操做,解決文件共享、保密和保護問題
D. 設備管理是指計算機系統中除了CPU和內存之外的全部輸入輸出設備的管理
A、均可以用在main()方法中 B、都是指一個內存地址
C、不能用在main()方法中 D、意義相同
public static void main(String[] args),main方法是靜態方法,不可使用對象特有的this或super關鍵字。
答:是。
答:能。
Exception in thread 「main」 java.lang.Exception: 異常4
at com.test.FinallyTry.f(FinallyTry.java:16)
at com.test.FinallyTry.main(FinallyTry.java:5)
--------在finally中拋異常或者return 會掩蓋以前的異常
答:減小頭部的體積、添加請求優先級、服務器推送、多路複用。
答:對。
隨機IO:假設咱們所須要的數據是隨機分散在磁盤的不一樣頁的不一樣扇區中的,那麼找到相應的數據須要等到磁臂(尋址做用)旋轉到指定的頁,而後盤片尋找到對應的扇區,才能找到咱們所須要的一塊數據,依次進行此過程直到找完全部數據,這個就是隨機IO,讀取數據速度較慢。
順序IO:假設咱們已經找到了第一塊數據,而且其餘所需的數據就在這一塊數據後邊,那麼就不須要從新尋址,能夠依次拿到咱們所需的數據,這個就叫順序IO。
答:對。
高級調度:即做業調度,按照必定策略將選擇磁盤上的程序裝入內存,並創建進程。(存在與多道批處理系統中)
中級調度:即交換調度,按照必定策略在內外存之間進行數據交換。
低級調度:即CPU調度(進程調度),按照必定策略選擇就緒進程,佔用cpu執行。
其中低度調度是必須的。
weak_ptr也是一個引用計數型智能指針,可是它不增長對象的引用計數,即弱引用。與之相對,shared_ptr是強引用,只要有一個指向對象的shared_ptr存在,該對象就不會析構,直到指向對象的最後一個shared_ptr析構或reset()時纔會被銷燬。
利用weak_ptr,咱們能夠解決常見的空懸指針問題以及循環引用問題。
SPX(Sequenced Packet Exchange protocol,順序包交換)協議是Novell開發的用在NetWare中的協議,用來確保信息成功傳送。SPX使用NetWare的IPX協議做爲它的傳遞機制並在網絡結點間提供客戶服務器和層對層的交互通訊。它工做在傳輸層。
* 2.若是客戶端直接CLOSED,而後又再次向服務器發起一個新鏈接,誰也不能保證新發起的鏈接和剛關閉的鏈接的端口號是不一樣的,有可能新、老鏈接的端口號就是同樣的。假設新、老鏈接端口號一致,若老鏈接的一些數據仍滯留在網絡中,這些滯留數據在新鏈接創建後纔到達服務器,鑑於先後端口號一致,TCP協議就默認這些數據屬於新鏈接,因而數據就這樣亂成一鍋粥了。因此TCP鏈接還要在TIME_WAIT狀態下等待2MSL,確保全部老鏈接的數據都在網絡中消失!
3.首先說明什麼是MSL,MSL是Maximum Segment Lifetime的縮寫,譯爲報文最大生存時間,也就是任何報文在網絡上存活的最大時間,一旦超過該時間,報文就會被丟棄。2MSL也就是指的2倍MSL的時間。
爲何是2倍呢?
當B接收到此消息,即認爲雙方達成了同步:雙方都知道鏈接能夠釋放了,此時B能夠安全地釋放此TCP鏈接所佔用的內存資源、端口號。因此被動關閉的B無需任何wait time,直接釋放資源。但,A並不知道B是否接到本身的ACK,A是這麼想的:
1)若是B沒有收到本身的ACK,會超時重傳FiN那麼A再次接到重傳的FIN,會再次發送ACK
2)若是B收到本身的ACK,也不會再發任何消息,包括ACK
不管是1仍是2,A都須要等待,要取這兩種狀況等待時間的最大值,以應對最壞的狀況發生,這個最壞狀況是:
去向ACK消息最大存活時間(MSL) + 來向FIN消息的最大存活時間(MSL)。這偏偏就是2MSL( Maximum Segment Life)。等待2MSL時間,A就能夠放心地釋放TCP佔用的資源、端口號,此時可使用該端口號鏈接任何服務器。同時也能保證網絡中老的連接所有消失。
package com.cn.niochat; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; import java.util.Scanner; /** * 用Java實現nio的客戶端 */ public class NioClient { public void start() throws IOException { /** * 連接服務器端 */ SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8000)); //向服務器端發送數據 //從命令行獲取數據,獲取鍵盤的輸入 Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()){ //獲取這一行數據 String request = scanner.nextLine(); //若是有數據,則發送,且數據不爲空 if(request != null && request.length() > 0){ socketChannel.write(Charset.forName("UTF-8").encode(request)); } } } public static void main(String[] args) throws IOException { NioClient nioClient = new NioClient(); nioClient.start(); } }
(25+16+17)×2+12×3+(5+10)×4=212。
遊標。
Java的+表達式計算是從左往右的。如果兩個整形,會求值,若其中之一是String,會拼接,且結果爲String。1+1+「1」,先計算1+1,由於兩個都是整形,求值=2,而後2+「1」,拼接,因此是
21,而「1」+1+1,先計算「1」+1,由於有String,結果爲’11",再「11」+1就是「111」。
意思是:當父類變量引用子類對象時(Fu f = new Zi();
),在這個引用變量f指向的對象中,他的成員變量和靜態方法與父類是一致的,他的非靜態方法,在編譯時是與父類一致的,運行時卻與子類一致(發生了複寫)。
class Fu { intnum = 5; static void method4() { System.out.println("fu method_4"); } void method3() { System.out.println("fu method_3"); } } class Zi extends Fu { intnum = 8; static void method4() {//注意點:靜態方法不能重寫 System.out.println("zi method_4"); } void method3() { System.out.println("zi method_3"); } } class DuoTaiDemo4 { public static void main(String[] args) { Fu f = new Zi(); System.out.println(f.num);//與父類一致 f.method4();//與父類一致 f.method3();//編譯時與父類一致,運行時與子類一致 Zi z = new Zi(); System.out.println(z.num); z.method4(); z.method3(); } }