前言
2021馬上金九銀十進入招聘旺季了,現為大家整理了這次金九銀十面試阿里的面試題總結,都是我從朋友那拿到的面試真題,話不多說,滿滿的干貨分享給大家!
int a=10是原子操作嗎?
是的。
注意點:
-
i++(或++i)是非原子操作,i++是一個多步操作,而且是可以被中斷的。i++可以被分割成3步,第一步讀取i的值,第二步計算i+1;第三部將最終值賦值給i。
-
int a = b;不是原子操作。從語法的級別來看,這是也是一條語句,是原子的;但是從實際執行的二進制指令來看,由於現代計算機CPU架構體系的限制,數據不可以直接從內存搬運到另外一塊內存,必須借助寄存器中斷,這條語句一般對應兩條計算機指令,即將變量b的值搬運到某個寄存器(如eax)中,再從該寄存器搬運到變量a的內存地址:
mov eax, dword ptr [b]
mov dword ptr [a], eax
既然是兩條指令,那么多個線程在執行這兩條指令時,某個線程可能會在第一條指令執行完畢后被剝奪CPU時間片,切換到另外一個線程而產生不確定的情況。
innodb支持全文索引嗎?
5.6版本之后InnoDB存儲引擎開始支持全文索引,5.7版本之后通過使用ngram插件開始支持中文。之前僅支持英文,因為是通過空格作為分詞的分隔符,對於中文來說是不合適的。MySQL允許在char、varchar、text類型上建立全文索引。
innodb支持表鎖嗎?
支持,補充:普通的增刪改 是表鎖,加入索引的增刪改是行鎖,執行查詢時不加任何鎖的。
HTTP短連接怎么變成長連接。
在header中加入 --Connection:keep-alive。
調用yeild()會阻塞嗎?
阻塞指的是暫停一個線程的執行以等待某個條件發生(如某資源就緒)。
yield() 方法:yield() 使得線程放棄當前分得的 CPU 時間,但是不使線程阻塞,即線程仍處於可執行狀態,隨時可能再次分得 CPU 時間。調用 yield() 的效果等價於調度程序認為該線程已執行了足夠的時間從而轉到另一個線程。yield()只是使當前線程重新回到可執行狀態,所以執行yield()的線程有可能在進入到可執行狀態后馬上又被執行。sleep()可使優先級低的線程得到執行的機會,當然也可以讓同優先級和高優先級的線程有執行的機會;yield()只能使同優先級的線程有執行的機會。
虛擬機棧是線程共享的嗎?
不是。
JVM初始運行的時候都會分配好 Method Area(方法區) 和Heap(堆) ,而JVM 每遇到一個線程,就為其分配一個 Program Counter Register(程序計數器) , VM Stack(虛擬機棧)和Native Method Stack (本地方法棧), 當線程終止時,三者(虛擬機棧,本地方法棧和程序計數器)所占用的內存空間也會被釋放掉。這也是為什么我把內存區域分為線程共享和非線程共享的原因,非線程共享的那三個區域的生命周期與所屬線程相同,而線程共享的區域與JAVA程序運行的生命周期相同,所以這也是系統垃圾回收的場所只發生在線程共享的區域(實際上對大部分虛擬機來說只發生在Heap上)的原因。
####### 棧區:
- 每個線程包含一個棧區,棧中只保存基礎數據類型的值(比如int i=1中1就是基礎類型的對象)和對象的引用以及基礎數據的引用
- 每個棧中的數據(基礎數據類型和對象引用)都是私有的,其他棧不能訪問。
- 棧分為3個部分:基本類型變量區、執行環境上下文、操作指令區(存放操作指令)。
####### 堆區:
- 存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令)
- jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身 。
####### 方法區:
- 又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量。
- 方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。(兩者區別為堆區存放new出來的對象信息,方法區存放本身就具有的類信息)
常量存放在JVM的那個區域?
方法區: 又叫靜態區,跟堆一樣,被所有的線程共享。它用於存儲已經被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。
window.postMessage() 方法可以安全地實現跨源通信。通常,對於兩個不同頁面的腳本,只有當執行它們的頁面位於具有相同的協議(通常為https),端口號(443為https的默認值),以及主機 (兩個頁面的模數 Document.domain設置為相同的值) 時,這兩個腳本才能相互通信。window.postMessage() 方法提供了一種受控機制來規避此限制,只要正確的使用,這種方法就很安全。
所有的對象都分配到堆中嗎?
答:不一定。
CopyOnWriteArrayList是線程安全的嗎?
答:是的。
CopyOnWriteArrayList使用了一種叫寫時復制的方法,當有新元素添加到CopyOnWriteArrayList時,先從原有的數組中拷貝一份出來,然后在新的數組做寫操作,寫完之后,再將原來的數組引用指向到新數組。創建新數組,並往新數組中加入一個新元素,這個時候,array這個引用仍然是指向原數組的。當元素在新數組添加成功后,將array這個引用指向新數組。
CopyOnWriteArrayList的整個add操作都是在鎖的保護下進行的。這樣做是為了避免在多線程並發add的時候,復制出多個副本出來,把數據搞亂了,導致最終的數組數據不是我們期望的。
public boolean add(E e) {
//1、先加鎖
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
//2、拷貝數組
Object[] newElements = Arrays.copyOf(elements, len + 1);
//3、將元素加入到新數組中
newElements[len] = e;
//4、將array引用指向到新數組
setArray(newElements);
return true;
} finally {
//5、解鎖
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接口可以多繼承嗎?
java類是單繼承的。classB extends classA
java接口可以多繼承。Interface3 extends Interface0, Interface1, interface……
不允許類多重繼承的主要原因是,如果A同時繼承B和C,而B和C同時有一個D方法,A如何決定該繼承那一個呢?
但接口不存在這樣的問題,接口全都是抽象方法繼承誰都無所謂,所以接口可以繼承多個接口。
(byte)300==(byte)100+(short)200?
答: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)
A.進程管理主要是對程序進行管理
B.存儲管理主要管理內存資源
C.文件管理可以有效的支持對文件的操作,解決文件共享、保密和保護問題
D. 設備管理是指計算機系統中除了CPU和內存以外的所有輸入輸出設備的管理
this和super正確的是(C):
A、都可以用在main()方法中 B、都是指一個內存地址
C、不能用在main()方法中 D、意義相同
public static void main(String[] args),main方法是靜態方法,不可以使用對象特有的this或super關鍵字。
引用計數法是JVM GC算法嗎?
答:是。
能在try{}catch(){}finally{}結構的finally{}中再次拋出異常嗎?
答:能。
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 會掩蓋之前的異常
HTTP2新特性?
答:減少頭部的體積、添加請求優先級、服務器推送、多路復用。
索引可以將隨機IO變成順序IO嗎?
答:對。
隨機IO:假設我們所需要的數據是隨機分散在磁盤的不同頁的不同扇區中的,那么找到相應的數據需要等到磁臂(尋址作用)旋轉到指定的頁,然后盤片尋找到對應的扇區,才能找到我們所需要的一塊數據,依次進行此過程直到找完所有數據,這個就是隨機IO,讀取數據速度較慢。
順序IO:假設我們已經找到了第一塊數據,並且其他所需的數據就在這一塊數據后邊,那么就不需要重新尋址,可以依次拿到我們所需的數據,這個就叫順序IO。
transient修飾的變量是臨時變量嗎?
答:對。
- 一旦變量被transient修飾,變量將不再是對象持久化的一部分,該變量內容在序列化后無法獲得訪問。
- transient關鍵字只能修飾變量,而不能修飾方法和類。注意,本地變量是不能被transient關鍵字修飾的。變量如果是用戶自定義類變量,則該類需要實現SERIALIZABLE接口。
- 被transient關鍵字修飾的變量不再能被序列化,一個靜態變量不管是否被transient修飾,均不能被序列化。
注意點:在Java中,對象的序列化可以通過實現兩種接口來實現,若實現的是SERIALIZABLE接口,則所有的序列化將會自動進行,若實現的是Externalizable接口,則沒有任何東西可以自動序列化,需要在writeExternal方法中進行手工指定所要序列化的變量,這與是否被transient修飾無關。
高、中、低三級調度。
高級調度:即作業調度,按照一定策略將選擇磁盤上的程序裝入內存,並建立進程。(存在與多道批處理系統中)
中級調度:即交換調度,按照一定策略在內外存之間進行數據交換。
低級調度:即CPU調度(進程調度),按照一定策略選擇就緒進程,占用cpu執行。
其中低度調度是必須的。
下面那個查看80端口是否被占用?
- 方式一:ps -ef |grep 80
- 方式二:netstat -anp |grep :80
- 方式三:lsof -i:80
- 方式四:netstat -tunlp |grep :80
- 方式五:netstat -an |grep :80
C++弱引用指針是那個?
weak_ptr也是一個引用計數型智能指針,但是它不增加對象的引用計數,即弱引用。與之相對,shared_ptr是強引用,只要有一個指向對象的shared_ptr存在,該對象就不會析構,直到指向對象的最后一個shared_ptr析構或reset()時才會被銷毀。
利用weak_ptr,我們可以解決常見的空懸指針問題以及循環引用問題。
下面不屬於類的構造方法具備的特點是( )。
- A.沒有返回值
- B.用戶可以通過new自動調用。
- C.構造方法名必須和類名相同
- D.用戶可以直接調用
- D [解析] 構造方法是類中的一種特殊方法,是為對象初始化操作編寫的方法,用它來定義對象的初始狀態。在Java語言中的每個類都有構造方法,它也是由方法名、參數和方法體組成。構造方法名必須與類名相同,它沒有返回值,用戶不能直接調用它,只能通過new自動調用。
spx協議工作在哪一層?
SPX(Sequenced Packet Exchange protocol,順序包交換)協議是Novell開發的用在NetWare中的協議,用來確保信息成功傳送。SPX使用NetWare的IPX協議作為它的傳遞機制並在網絡結點間提供客戶服務器和層對層的交互通信。它工作在傳輸層。
TCP第四次揮手后為什么要等待2MSL后才斷開鏈接?等待時間為什么是2MSL?
-
答:1.為了保證客戶端最后一次揮手的報文能夠到達服務器,若第4次揮手的報文段丟失了,服務器就會超時重傳第3次揮手的報文段,所以客戶端此時不是直接進入CLOSED,而是保持TIME_WAIT(等待2MSL就是TIME_WAIT)。當客戶端再次收到服務器因為超時重傳而發送的第3次揮手的請求時,客戶端就會重新給服務器發送第4次揮手的報文(保證服務器能夠收到客戶端的回應報文)。最后,客戶端、服務器才真正斷開連接。說白了,等待2MSL就是為了確保服務器能夠受到客戶端最后的回應。
-
2.如果客戶端直接CLOSED,然后又再次向服務器發起一個新連接,誰也不能保證新發起的連接和剛關閉的連接的端口號是不同的,有可能新、老連接的端口號就是一樣的。假設新、老連接端口號一致,若老連接的一些數據仍滯留在網絡中,這些滯留數據在新連接建立后才到達服務器,鑒於前后端口號一致,TCP協議就默認這些數據屬於新連接,於是數據就這樣亂成一鍋粥了。所以TCP連接還要在TIME_WAIT狀態下等待2MSL,確保所有老連接的數據都在網絡中消失!
-
3.首先說明什么是MSL,MSL是Maximum Segment Lifetime的縮寫,譯為報文最大生存時間,也就是任何報文在網絡上存活的最大時間,一旦超過該時間,報文就會被丟棄。2MSL也就是指的2倍MSL的時間。
為什么是2倍呢? -
主動斷開的一側為A,被動斷開的一側為B。
-
第一個消息:A發FIN
-
第二個消息:B回復ACK
-
第三個消息:B發出FIN此時此刻:B單方面認為自己與A達成了共識,即雙方都同意關閉連接。此時,B能釋放這個TCP連接占用的內存資源嗎?不能,B一定要確保A收到自己的ACK、FIN。所以B需要靜靜地等待A的第四個消息的到來:
-
第四個消息:A發出ACK,用於確認收到B的FIN
當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占用的資源、端口號,此時可以使用該端口號連接任何服務器。同時也能保證網絡中老的鏈接全部消失。
進程有那些狀態,並簡單描述一下?
- 進程其基本狀態有5種,即創建狀態、就緒狀態、運行狀態、阻塞狀態、終止狀態。
- 創建狀態:進程在創建時需要申請一個空白PCB,向其中填寫控制和管理進程的信息,完成資源分配。
- 就緒狀態:進程已經准備好,已分配到所需資源,只要分配到CPU就能夠立即運行。
- 執行狀態:進程處於就緒狀態被調度后,進程進入執行狀態。
- 阻塞狀態:正在執行的進程由於某些事件而暫時無法運行,進程受到阻塞。
- 終止狀態:進程結束,或出現錯誤,或被系統終止,進入終止狀態,無法再執行。
- 進程是指計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位。
- 進程狀態是指一個進程的生命周期可以划分為一組狀態,這些狀態刻畫了整個進程,進程狀態即體現一個進程的生命狀態。
創建NIO客戶端代碼。
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();
}
}
獲取一個類的class實例的方法有那些?
- (1).調用運行時類本身的.class屬性
Class clazz = String.class; - (2),通過運行時類的對象獲取
public final Class<?> getClass()是非靜態方法.
Person p = new Person();
Class clazz = p.getClass(); - (3)通過Class的靜態方法獲取:體現反射的動態性
String className = “java.util.commons”;
Class clazz = Class.forName(className); - (4)通過類的加載器
String className = “java.util.commons”;
ClassLoader classLoader = this.getClass().getClassLoader();
Class claz = classLoader.loadClass(className);
a、b、c、d、e、f字符出現的次數分別為16、5、12、17、10、25。編碼的最少字節是多少?
(25+16+17)×2+12×3+(5+10)×4=212。
MySQL中獲得結果集的記錄並在此記錄上做特殊的操作的最佳對象是?
游標。
System.out.println(1+1+“1”)輸出21。System.out.println(“1”+1+1);輸出111。
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();
}
}
1開頭的http狀態碼
- 表示臨時響應並需要請求者繼續執行操作的狀態代碼。
- 100 (繼續) 請求者應當繼續提出請求。 服務器返回此代碼表示已收到請求的第一部分,正在等待其余部分。
- 101 (切換協議) 請求者已要求服務器切換協議,服務器已確認並准備切換。
2開頭的http狀態碼
- 表示請求成功
- 200 成功處理了請求,一般情況下都是返回此狀態碼;
- 201 請求成功並且服務器創建了新的資源。
- 202 接受請求但沒創建資源;
- 203 返回另一資源的請求;
- 204 服務器成功處理了請求,但沒有返回任何內容;
- 205 服務器成功處理了請求,但沒有返回任何內容;
- 206 處理部分請求;
3xx (重定向)
- 重定向代碼,也是常見的代碼
- 300 (多種選擇) 針對請求,服務器可執行多種操作。 服務器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。
- 301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
- 302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求。
- 303 (查看其他位置) 請求者應當對不同的位置使用單獨的 GET 請求來檢索響應時,服務器返回此代碼。
- 304 (未修改) 自從上次請求后,請求的網頁未修改過。 服務器返回此響應時,不會返回網頁內容。
- 305 (使用代理) 請求者只能使用代理訪問請求的網頁。 如果服務器返回此響應,還表示請求者應使用代理。
- 307 (臨時重定向) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求。
4開頭的http狀態碼表示請求出錯
- 400 服務器不理解請求的語法。
- 401 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。
- 403 服務器拒絕請求。
- 404 服務器找不到請求的網頁。
- 405 禁用請求中指定的方法。
- 406 無法使用請求的內容特性響應請求的網頁。
- 407 此狀態代碼與 401類似,但指定請求者應當授權使用代理。
- 408 服務器等候請求時發生超時。
- 409 服務器在完成請求時發生沖突。 服務器必須在響應中包含有關沖突的信息。
- 410 如果請求的資源已永久刪除,服務器就會返回此響應。
- 411 服務器不接受不含有效內容長度標頭字段的請求。
- 412 服務器未滿足請求者在請求中設置的其中一個前提條件。
- 413 服務器無法處理請求,因為請求實體過大,超出服務器的處理能力。
- 414 請求的 URI(通常為網址)過長,服務器無法處理。
- 415 請求的格式不受請求頁面的支持。
- 416 如果頁面無法提供請求的范圍,則服務器會返回此狀態代碼。
- 417 服務器未滿足”期望”請求標頭字段的要求。
5開頭狀態碼並不常見,但是我們應該知道
- 500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。
- 501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。
- 502 (錯誤網關) 服務器作為網關或代理,從上游服務器收到無效響應。
- 503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。
- 504 (網關超時) 服務器作為網關或代理,但是沒有及時從上游服務器收到請求。
- 505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。
- 記憶口訣:1臨(臨時響應)2成(請求成功)3定向(重定向)4請(請求出錯)5服(服務器錯誤)
筆試題
一、選擇題
1.Java語言中,只限子類或者同一包中的類的方法能訪問的訪問權限是( C )
A、public
B、private
C、protected
D、無修飾
分析
private:Java語言中對訪問權限限制的最窄的修飾符,一般稱之為“私有的”。被其修飾的屬性以及方法只能被該類的對象訪問,其子類不能訪問,更不能允許跨包訪問。
default:即不加任何訪問修飾符,通常稱為“默認訪問權限“或者“包訪問權限”。該模式下,只允許在同一個包中進行訪問。
protected:介於public 和 private 之間的一種訪問修飾符,一般稱之為“保護訪問權限”。被其修飾的屬性以及方法只能被類本身的方法及子類訪問,即使子類在不同的包中也可以訪問。
public:Java語言中訪問限制最寬的修飾符,一般稱之為“公共的”。被其修飾的類、屬性以及方法不僅可以跨類訪問,而且 允許跨包訪問。
2.在以下供選擇的方法中,屬於接口MouseMotionListener的方法是( D )
A、mouseReleased()
B、mouseEntered()
C、mouseExited()
D、mouseMoved()
3.以下是關於線程的敘述,正確的是( C )
A、多線程的使用可以提高設備的平行工作能力,但是使系統管理變得復雜
B、同一個進程下的線程都有自己的狀態、專用數據段和獨立的內存資源
C、線程是能獨立運行的程序
D、進程的執行效率比線程的執行效率高
4.在編寫訪問數據庫的Java程序時,ResultSet對象的作用是( D )
A、建立新數據庫連接
B、用來表示與數據庫的連接C、在指定的連接中處理SQL語句
D、存儲查詢結果
5.關於方法main()的說法哪個正確?( C )
A.方法main()只能放在公共類中
B.main()的頭定義可以根據情況任意更改
C.一個類中可以沒有main()方法
D.所有對象的創建都必須放在main()方法中
6. 抽象方法: ( C )
A.可以有方法體(錯)
B.可以出現在非抽象類中C.是沒有方法體的方法
D.抽象類中的方法都是抽象方法
7. this和super: ( C )
A.都可以用在main()方法中
B.都是指一個內存地址
C.不能用在main()方法中
D.意義相同
8.字符流與字節流的區別在於( D )
A.前者帶有緩沖,后者沒有
B.前者是塊讀寫,后者是字節讀寫
C.二者沒有區別,可以互換使用
D.每次讀寫的字節數不同
**9.類B是一個抽象類,類C是類B的非抽象子類,下列創建對象x1的語句中正確的是( C )。(抽象類不能被實例化,即不能創建對象) **
A.B x1= new B( );
B.B x1= C( );
C.C x1=new C( );
D.C x1= new B( );
10.線程對象的生命周期中,哪個不是其經歷的狀態( A )。
(五種基本狀態:新建;就緒;運行;阻塞;死亡)
A.中斷
B.運行
C.就緒
D.死亡
11.對於可以隨着窗口的寬度變化而改變相應的控件的位置的布局對象是哪一種( A )
A、FlowLayout
B、GridLayout
C、BordyLayout
D、CardLayout
12、對於import java.awt.Button;以下那種說法錯誤( D )
A、Button屬於java.awt包
B、Button在java.awt目錄下C、Button在java.awt文件中
D、Button屬於Sun的類
13、用abstract定義的類( D )
A、可以被實例化
B、不能派生子類
C、不能被繼承
D、只能被繼承
14、continue語句( C )
A、只中斷最內層的循環
B、只中斷最外層的循環
C、只中斷所在層循環中的當次循環
D、只中斷某一層的循環
15、每個使用組件的程序必須有一個( B )
A 、按鈕
B 、容器
C 、菜單
D 、標簽
16、在Java Applet程序用戶自定義的Applet子類中,一般需要重載父類的( D )方法來完成一些畫圖操作。
A. start( )
B. stop( )
C. init( )
D. paint( )
二、判斷題
1.對於容器javax.swing.JPanel,它的默認布局是BorderLayout。( × )JPanel中的默認布局是FlowLayout
2.Socket通常也稱為套接字,用於描述IP地址和端口。 ( √ )
3.線程的優先級在1 至10之間,數值越小任務越緊急。( × )
線程的優先級用1-10之間的整數表示,數值越大優先級越高,即越高執行越快,默認的優先級為5。
4.Java語言的類只允許單繼承。( √ )
5.Java源程序的擴展名是.java,經過編譯后的程序的擴展名是.class。( √ )
6.在一個時間只能由一個線程訪問的資源稱為臨界資源。訪問臨界資源的代碼稱為臨界代碼。( × )
多個線程間共享的數據稱為臨界資源
7.並發就是事件、任務在同一時刻開始。( × ) (並行才是同一時刻開始)
8.URL在網絡中是唯一的。( √ )(一個 URL 必須唯一地,永久地代表一個在線對象)
三、填空題
1.Java語言采用多種機制來保證可移植性,其中最主要的是___java虛擬機___。
2.程序包聲明的格式是__package 包名.包名.包名…;。
3.當聯編推遲至運行時間實現時,該聯編過程稱為_動態聯編_____。
4.使用默認字節字符對應表,將字符串轉化為字節數組的方法是___getBytes();。
5.在Swing中,帶有滾動條的面板的類名是__JScrollPanel____。
6.組合框(JComboBox)是____文本框和列表_____的組合。
7.在Java語言中,文件隨機訪問可以利用___RandomAccessFile___類實現。
8.Java程序可以用純Java的___JDBC_____驅動程序,實現與數據庫連接。
9.下列哪個敘述是不正確的?( B )
A.JButton在javax.Swing包中
B.ActionEvcent在java.awt包中(其實在javax.Swing包中)
C.ActionListener在java.awt.event包中
D.Font類在java.awt包中
10.下列流中哪些不屬於字節流(D)(菜鳥教程IO流講解里面有詳細介紹)
A.FileInputStream B.BufferedInputStream C.FileInputStream D.InputStreamReader
四、簡答題
1.請寫出Applet類中init()方法的功能。
init()方法:主要是為了Applet的正常運行做一些初始化的工作。
2.請寫出空布局安置組件的兩個步驟。
首先利用setLayout(null)語句將容器的布局設置為null布局(空布局)。
再調用組件的setBounds(int x, int y, int width,int height)方法設置組件在容器中的大小和位置,單位均為像素。
3.在Swing中,對話框有幾種?並請寫出它們的主要區別。
五種:文件對話框、消息對話框、輸入對話框、確認對話框、顏色對話框
實現功能不同,調用的函數也不同
4.請寫出用Runnable接口實現多線程的主要工作。(注意大小寫類名以及變量的名稱)
public class MyRunnable implements Runnable{
public void run(){
for(int i = 0;i<10000;i++){
System.out.println("aaaaaaaaaaaaa");
}
}
public class TestDemo {
public static void main(
String[] args)
{
MyRunnable mr = new MyRunnable();
Thread t = new Thread(mr);
T.start();//線程啟動
}
}
}
5.編寫一個程序,創建一個文本文件,從鍵盤輸入字符到這個文本文件中,以END結束。
注意大括號不要漏了
public class Demo4 {
public static void main(String[] args) {
System.out.println("請輸入字符:");
Scanner scanner = new Scanner(System.in);
String str = scanner.next();
File f=new File("d:\\ss.txt");
//字節流輸出
FileOutputStream fos=null;
try {
fos=new FileOutputStream(f);
//定義一個數組
byte []bytes=new byte[1024];
//如何把String轉換成byte數組
fos.write(str.getBytes());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
6.Java語言的特點。
Java語言的特點:
(1) 簡單的
(2) 面向對象的
(3) 分布式的
(4)健壯性的
(5)安全的
(6)體系結構中立的
(7)可移植的
(8)解釋型的
7.在Java中,怎樣創建一個線程?
(1)通過繼承Thread類創建線程
(2)通過實現Runnable接口創建線程
(3)通過Callable和Future創建線程
8.事件處理的三要素是什么?
事件源(Event Source):即事件發生的場所,就是指各個組件,如按鈕等,點擊按鈕其實就是組件上發生的一個事件;
事件(Event):事件封裝了組件上發生的事情,比如按鈕單擊、按鈕松開等等;
事件監聽器(Event Listener):負責監聽事件源上發生的特定類型的事件,當事件到來時還必須負責處理相應的事件;
9.抽象類與接口有何不同?
(1)抽象類中可以存在非抽象的方法, 接口中的方法被默認的變成抽象方法;
(2) 實現抽象類的方法時, 如果方法是抽象的,子類必須重寫抽象的方法. 如果方法不是抽象的, 子類可以選擇繼承,實現了接口就必須實現接口中的所有方法, 因為接口中的方法默認的全部都是抽象的方法 ;
(3)抽象類可以有私有的成員變量和成員方法,接口中的方法全都被默認的修飾為: public abstract 類型的方法;
(4)一個類只能繼承一個抽象類,一個類可以實現多個接口 ,接口可以實現多繼承
(5)抽象類中的非抽象的方法可以選擇繼承,接口中的方法必須全部被重寫 ,並且全部是公有的public 方法.
作者:蘇緒
原文鏈接:https://blog.csdn.net/weixin_41719737/article/details/86490339
來源Lcsdn
補充java技術棧
Java並發編程、JVM、數據結構與算法、網絡協議、數據庫、MySQL、52條SQL性能優化策略、一千行SQL命令、Redis、MongoDB、Spring、MyBatis、SpringBoot、Spring & SpringBoot常用注解、微服務、Dubbo、Nginx、Zookeeper、MQ、kafka、Elasticsearch
算法
- 10億個數字里里面找最小的10個。
- 有1億個數字,其中有2個是重復的,快速找到它,時間和空間要最優。
- 2億個隨機生成的無序整數,找出中間大小的值。
- 給一個不知道長度的(可能很大)輸入字符串,設計一種方案,將重復的字符排重。
- 遍歷二叉樹。
- 有3n+1個數字,其中3n個中是重復的,只有1個是不重復的,怎么找出來。
- 寫一個字符串(如:http://www.javastack.cn)反轉函數。
- 常用的排序算法,快排,歸並、冒泡。 快排的最優時間復雜度,最差復雜度。冒泡排序的優化方案。
- 二分查找的時間復雜度,優勢。
- 一個已經構建好的TreeSet,怎么完成倒排序。
- 什么是B+樹,B-樹,列出實際的使用場景。
- 一個單向鏈表,刪除倒數第N個數據。
- 200個有序的數組,每個數組里面100個元素,找出top20的元素。
- 單向鏈表,查找中間的那個元素。
數據庫知識
- 數據庫隔離級別有哪些,各自的含義是什么,MYSQL默認的隔離級別是是什么。
- 什么是幻讀。
- MYSQL有哪些存儲引擎,各自優缺點。
- 高並發下,如何做到安全的修改同一行數據。
- 樂觀鎖和悲觀鎖是什么,INNODB的標准行級鎖有哪2種,解釋其含義。
- SQL優化的一般步驟是什么,怎么看執行計划,如何理解其中各個字段的含義。
- 數據庫會死鎖嗎,舉一個死鎖的例子,mysql怎么解決死鎖。
- MYsql的索引原理,索引的類型有哪些,如何創建合理的索引,索引如何優化。
- 聚集索引和非聚集索引的區別。
- select for update 是什么含義,會鎖表還是鎖行或是其他。
- 為什么要用Btree實現,它是怎么分裂的,什么時候分裂,為什么是平衡的。
- 數據庫的ACID是什么。
- 某個表有近千萬數據,CRUD比較慢,如何優化。
- Mysql怎么優化table scan的。
- 如何寫sql能夠有效的使用到復合索引。
- mysql中in 和exists 區別。
- 數據庫自增主鍵可能的問題。
- MVCC的含義,如何實現的。
- 你做過的項目里遇到分庫分表了嗎,怎么做的,有用到中間件么,比如sharding jdbc等,他們的原理知道么。
- MYSQL的主從延遲怎么解決。
消息隊列
- 消息隊列的使用場景。
- 消息的重發,補充策略。
- 如何保證消息的有序性。
- 用過哪些MQ,和其他mq比較有什么優缺點,MQ的連接是線程安全的嗎,你們公司的MQ服務架構怎樣的。
- MQ系統的數據如何保證不丟失。
- rabbitmq如何實現集群高可用。
- kafka吞吐量高的原因。
- kafka 和其他消息隊列的區別,kafka 主從同步怎么實現。
- 利用mq怎么實現最終一致性。
- 使用kafka有沒有遇到什么問題,怎么解決的。
- MQ有可能發生重復消費,如何避免,如何做到冪等。
- MQ的消息延遲了怎么處理,消息可以設置過期時間么,過期了你們一般怎么處理。
緩存
- 常見的緩存策略有哪些,如何做到緩存(比如redis)與DB里的數據一致性,你們項目中用到了什么緩存系統,如何設計的。
- 如何防止緩存擊穿和雪崩。
- 緩存數據過期后的更新如何設計。
- redis的list結構相關的操作。
- Redis的數據結構都有哪些。
- Redis的使用要注意什么,講講持久化方式,內存設置,集群的應用和優劣勢,淘汰策略等。
- redis2和redis3的區別,redis3內部通訊機制。
- 當前redis集群有哪些玩法,各自優缺點,場景。
- Memcache的原理,哪些數據適合放在緩存中。
- redis和memcached 的內存管理的區別。
- Redis的並發競爭問題如何解決,了解Redis事務的CAS操作嗎。
- Redis的選舉算法和流程是怎樣的。
- redis的持久化的機制,aof和rdb的區別。
- redis的集群怎么同步的數據的。
- 知道哪些redis的優化操作。
- Reids的主從復制機制原理。
- Redis的線程模型是什么。
- 請思考一個方案,設計一個可以控制緩存總體大小的自動適應的本地緩存。
- 如何看待緩存的使用(本地緩存,集中式緩存),簡述本地緩存和集中式緩存和優缺點。本地緩存在並發使用時的注意事項。
補充
如何學習java ,分享兩個萬能學習的資料庫:
1、書籍:
2:視頻教程:
程序員必讀Java書籍SpringBoot、Spring、Mybatis、Redis、RabbitMQ、SpringCloud、高並發(持續更新)
覺得不錯的小伙伴記得轉發關注哦,后續會持續更新精選技術文章!
最后,照舊安利一波我們的公眾號:「終端研發部」,目前每天都會推薦一篇優質的技術相關的文章,主要分享java相關的技術與面試技巧,我們的目標是:知道是什么,為什么,打好基礎,做好每一點!這個主創技術公眾號超級值得大家關注。