騰訊、百度、珍愛網、中國電信、三之樂面試經歷
2016年9月中下旬面試了5家公司。留下一點經驗給後來人。
轉載請註明出處:
騰訊(運營開發)
一面
兩個幾十TB的檔案,是否是一樣的檔案,該怎麼判斷?檔案中每一行的資料一樣但順序不一樣也是一樣的檔案。
答:正常的比較是將兩個檔案先按行排序,然後一行一行的比較下去。但是檔案太大,比較次數太多了。
有一種資料結構可以去除順序的影響,那就是HashMap,將每一行資料存在HashMap中,然後再遍歷,依次比較。
大檔案的操作一般都使用分治法。我給的答案是,兩個大檔案的每一行分別計算Hash值,Hash值前4位相同的都存到同一個以前4位命名的檔案中。這樣的話,總共有
然後問面試官這樣可以嗎?面試官說,你得分析時間複雜度和空間複雜度。然後我就分析了一下。
給1億條邊,這些邊可以組成森林,問有多少顆樹?
答:先和麵試官確認邊是怎麼給的,(a,b)這樣的形式嗎?面試官說都可以。
正常情況下,需要先把這些邊構建成樹,然後判斷有多少顆樹。構建樹的時候需要先找到之前的森林中有沒有a頂點,有的話接上去,沒有的話,自己造一棵樹。這樣的話時間複雜度太高了。
由於前面有過HashMap的經驗,我想先把邊以a為key存起來。這樣判斷森林中有沒有這個頂點就會快很多。
問題還沒有解決,但是時間已經來不及了,面試官又開始問後面的問題了。
最後回來想了一下,應該可以這樣。先生成成千上萬個以起點a命名的檔案,檔名為a,檔案內容為b的集合。a放在Hash表中,這樣找起來會快很多。然後開始遍歷每個檔案的內容。比如說遍歷到b了,就找所有以b命名的檔案,然後將b的內容合併到a中去,將b刪除,繼續遍歷a的內容,直到遍歷完,第一個樹就構造完成了。然後繼續遍歷下一個沒有被合併的檔案。等所有檔案合併完成後,就知道有幾顆樹了。這樣的話,相當於只儲存了所有樹的頂點和葉子節點,並不關心樹的具體結構,最終得到了想知道的答案。
看你簡歷上會的東西挺多的,有沒有專一的地方,未來的規劃是什麼,願不願意做運維。
答:可以做運維開發,單純做運維,運營,測試,以後的路太窄了。
二面
40個有編號的球中選擇6個出來,有多少種情況。
答:
將一個檔案分成10個小檔案。10個小檔案分佈在不同的機器上,每個機器最多隻有一個小檔案。現在有100臺機器,一個機器出故障的概率為p,求這個檔案的故障率。
答:檔案的故障率=1-檔案正常的概率
接上,現在有一種技術,一個檔案分成10個小檔案和3個校驗檔案。這13個檔案中,只要有10個是正常的,檔案都能恢復成功。問檔案出故障的概率。
答:檔案的故障率=1-(小檔案都正常+一個小檔案故障+兩個小檔案故障+三個小檔案故障)
看過哪些書?
答:《深入Java Web核心技術原理》,《HTML指南》,《設計模式》。
JVM原理
答:有很多有名的JVM,但我們最常用到的就是Oracle收購的sun公司的HotSpot。
HotSpot中記憶體被分為3個代:年輕代(young generation),年老代(old generation),持久代(permanent generation)。
get和post的區別
答:Get是向伺服器發索取資料的一種請求,而Post是向伺服器提交資料的一種請求,在FORM(表單)中,Method預設為”GET”,實質上,GET和POST只是傳送機制不同,並不是一個取一個發。
觀察者模式
答:有時被稱作釋出/訂閱模式,觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件。這個主題物件在狀態發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己。
有沒有女朋友
答:沒有。
微信公眾號,微信支付
答:面試官之前研究過微信公眾號一段時間,我簡要介紹了一下我做過的一個微信商城。
XBox One
答:面試官家裡有一個XBox 360。交流了一下XBox的體感遊戲和經典遊戲。
家庭情況
答:父母有兄弟姐妹照顧,沒有後顧之憂。
興趣愛好
答:羽毛球,乒乓球,玩遊戲,寫程式。
除了給公司開發專案之外,自己有沒有做出過一些小工具
答:做過一個CSDN美化外掛。
百度(運維開發)
一面
自我介紹
答:balabala。
寫二分查詢演算法
答:手寫演算法。
public static int rank(int goal, int[] data)
{
int start = 0;
int end = data.length - 1;
while (start <= end)
{
int mid = start + (end - start) / 2;
if (goal<data[mid])
{
end=mid-1;
}else if (goal>data[mid])
{
start=mid+1;
}else
{
return mid;
}
}
return -1;
}
判斷單向連結串列有環
答:使用兩個slow, fast指標從頭開始掃描連結串列。指標slow 每次走1步,指標fast每次走2步。如果存在環,則指標slow、fast會相遇;如果不存在環,指標fast遇到NULL退出。
TCP協議三次握手,四次揮手
答:畫了兩張圖。
Linux常用命令
答:cd,ls,cp,mv,mkdir,rm,pwd,rz,sz。
HashTable,HashMap,ConcurrentHashMap的區別。從底層實現上分析。
答:HashMap執行緒不安全,ConcurrentHashMap較安全,HashTable執行緒安全。
HashMap沒有同步鎖,HashTable對整個Hash表加鎖,ConcurrentHashMap分段加鎖。
擅長的語言
答:Java。
實習公司,做哪些工作.
答:Kingsoft。做過程式碼有效行數統計工具,多執行緒下載檔案。
MapReduce的原理
答:講了一下下面這張圖的過程。
有沒有想問的?
答:想了解一下這個崗位一天正常的工作是什麼樣的。面試官說運維開發,一半的時間開發,一半的時間運維。
對運維的理解
答:運維自動化,出錯報警,自動修復,及時響應,7x24小時待命。面試官說會有輪班制,不會一年到頭都神經繃緊。
二面
自我介紹
答:balabala。
滑動視窗有過了解嗎
答:沒有了解過。
TCP三次握手,4次揮手
答:畫了一面的圖。
埠號在哪一層,IP地址在哪一層
答:埠號在傳輸層,IP地址在網路層。
交換機和路由器的區別
答:交換機每個埠都可以設獨立IP,路由器只能有一個獨立IP,然後是區域網IP地址。
歸併排序
答:手寫歸併排序。
public static int[] sort(int[] nums, int low, int high)
{
int mid = (low + high) / 2;
if (low < high)
{
// 左邊
sort(nums, low, mid);
// 右邊
sort(nums, mid + 1, high);
// 左右歸併
merge(nums, low, mid, high);
}
return nums;
}
public static void merge(int[] nums, int low, int mid, int high)
{
int[] temp = new int[high - low + 1];
int i = low;// 左指標
int j = mid + 1;// 右指標
int k = 0;
// 把較小的數先移到新陣列中
while (i <= mid && j <= high)
{
if (nums[i] < nums[j])
{
temp[k++] = nums[i++];
}
else
{
temp[k++] = nums[j++];
}
}
// 把左邊剩餘的數移入陣列
while (i <= mid)
{
temp[k++] = nums[i++];
}
// 把右邊邊剩餘的數移入陣列
while (j <= high)
{
temp[k++] = nums[j++];
}
// 把新陣列中的數覆蓋nums陣列
for (int k2 = 0; k2 < temp.length; k2++)
{
nums[k2 + low] = temp[k2];
}
}
希爾排序
答:手寫希爾排序。
int[] a = { 49, 38, 65, 97, 76, 13, 27, 49, 78, 34, 12, 64, 1 };
System.out.println("排序之前:");
for (int i = 0; i < a.length; i++)
{
System.out.print(a[i] + " ");
}
// 希爾排序
int d = a.length;
while (true)
{
d = d / 2;
for (int x = 0; x < d; x++)
{
for (int i = x + d; i < a.length; i = i + d)
{
int temp = a[i];
int j;
for (j = i - d; j >= 0 && a[j] > temp; j = j - d)
{
a[j + d] = a[j];
}
a[j + d] = temp;
}
}
if (d == 1)
{
break;
}
}
System.out.println();
System.out.println("排序之後:");
for (int i = 0; i < a.length; i++)
{
System.out.print(a[i] + " ");
}
快速排序
答:手寫快速排序。
private static void quick(int[] a)
{
if (a.length > 0)
{
quickSort(a, 0, a.length - 1);
}
}
private static void quickSort(int[] a, int low, int high)
{
if (low < high)
{ // 如果不加這個判斷遞迴會無法退出導致堆疊溢位異常
int middle = getMiddle(a, low, high);
quickSort(a, 0, middle - 1);
quickSort(a, middle + 1, high);
}
}
private static int getMiddle(int[] a, int low, int high)
{
int temp = a[low];// 基準元素
while (low < high)
{
// 找到比基準元素小的元素位置
while (low < high && a[high] >= temp)
{
high--;
}
a[low] = a[high];
while (low < high && a[low] <= temp)
{
low++;
}
a[high] = a[low];
}
a[low] = temp;
return low;
}
二叉樹,平衡二叉樹,B樹,B+樹,紅黑樹
答:沒有講出來每種樹的具體區別。
一顆二叉樹,葉子節點有5個,度為1的節點有50個,問這棵二叉樹總共有多少個節點
答:這裡用到一個公式,但是我不記得了,只能手畫出來,給出答案。
判斷單向連結串列有環
答:還是一面的答案。
給棧增加一個方法,返回棧中第二大的元素,時間複雜度為O(1)
答:當時沒有想出來。
回來之後想了一下,可以這樣做。設定一個輔助棧,輔助棧中存第二大的數,但是還要有兩個變數來存最大的數和第二大的數,這樣出棧和入棧的時候可以方便比較,及時更新輔助棧。
TCP/IP協議棧各層
答:物理層,資料鏈路層,網路層,傳輸層,應用層。
常用Linux命令
答:面試官問了一些命令,問我是什麼作用,我都不知道。
JVM記憶體模型及垃圾回收機制,Min GC,Full GC
答:新生代,老生代,永久代。
新生代 GC(Minor GC):指發生在新生代的垃圾收集動作,因為 Java 物件大多都具備朝生夕滅的特性,所以 Minor GC 非常頻繁,一般回收速度也比較快。
老年代 GC(Major GC / Full GC):指發生在老年代的 GC,出現了 Major GC,經常會伴隨至少一次的 Minor GC(但非絕對的,在 ParallelScavenge 收集器的收集策略裡就有直接進行 Major GC 的策略選擇過程) 。MajorGC 的速度一般會比 Minor GC 慢 10倍以上。
虛擬機器給每個物件定義了一個物件年齡(Age)計數器。如果物件在 Eden 出生並經過第一次 Minor GC 後仍然存活,並且能被 Survivor 容納的話,將被移動到 Survivor 空間中,並將物件年齡設為 1。物件在Survivor 區中每熬過一次 Minor GC,年齡就增加 1 歲,當它的年齡增加到一定程度(預設為 15 歲)時,就會被晉升到老年代中。物件晉升老年代的年齡閾值,可以通過引數 -XX:MaxTenuringThreshold 來設定。
網路程式設計,socket
答:寫過一個QQ聊天程式,建立連線,傳送或接收資料,釋放連線。
珍愛網(Java開發)
併發包下的訊號量
答:java.util.concurrent這個包下面的訊號量Semaphore,可以允許多個執行緒同時訪問。但是我對這個包沒有怎麼用過,瞭解的不多。
spring的@resource和@autowired
答:@resource預設按名稱,@autowired預設按型別裝載bean。
nginx做負載均衡器
答:我用過apache做過負載均衡器,面試官說公司用nginx做負載均衡器,我沒有了解過,但是回去後會看一下怎麼用的。
spring兩大特性的理解及底層實現
答:spring的兩大特性是IoC和AOP。IoC依賴注入,可以使程式碼解耦,將bean的生命週期交給容器管理。底層使用Java的反射機制來實現的。
AOP面向切面程式設計,可以實現事務,許可權,日誌等功能的統一實現,使程式碼進一步的解耦。底層使用代理模式實現的。
MySQL計劃執行有用過嗎?
答:我問面試官是說資料庫的定時任務嗎?面試官說不是。
後來查了一下,是用來檢視SQL語句的執行情況的,然後進行效能分析用的。
看你用過Hibernate,MyBatis有用過嗎?
答:沒有用過,回來後會看的。
回來後研究了一下,可以參考這篇文章。
有看過一些開源專案的原始碼嗎?
答:Java中的一些常用資料結構會看一下原始碼是怎麼實現的。其他的開源專案大多停留在會用的層面。
HashTable,HashMap,ConcurrentHashMap的底層區別?
答:HashMap執行緒不安全,ConcurrentHashMap較安全,HashTable執行緒安全。
HashMap沒有同步鎖,HashTable對整個Hash表加鎖,ConcurrentHashMap分段加鎖。
HashMap中key可不可以為null,存在哪裡?
答:沒有了解過,因為平時用的時候沒有存過key為null的物件。
回來後我看了一下JDK的原始碼。
其中有一段是這樣的。int hash = (key == null) ? 0 : hash(key);
可以看出當key為null的時候,hash為0,所以當key為null的時候,存在第一個位置上。
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
//重點是這一句
int hash = (key == null) ? 0 : hash(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;
}
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value); //重點這一句
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
private V putForNullKey(V value) {
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(0, null, value, 0);//重點這一句
return null;
}
佇列裡面放的有任務,每個任務的執行時間不一樣,怎麼讓時間在前的任務先執行?
答:這樣的話,可以用一個輔助的佇列來找到時間在前的任務。
中國電信 IT 研發中心(Java開發)
一面
Java8 的新特性
答:沒有了解過。
JRE的指令有了解過嗎?
答:Java程式碼編譯成位元組碼之後的那種指令嗎?沒有了解過。
AOP的原理底層程式碼如何實現?
答:代理模式實現的。
但是我們寫程式碼時,並沒有使用代理模式,Spring是如何做到的?
答:我沒具體瞭解過,可能是Spring改了原來的程式碼,然後用Java的反射機制載入新的程式碼。
synchronized和lock的區別
答:synchronized是Java的關鍵字,用於多執行緒的同步鎖,synchronized範圍結束自動釋放掉。lock是java.util.concurrent包下面的類,手動加鎖,手動釋放。
實現生產者消費者原理
答:有一個資源池。然後有很多生產者執行緒,很多消費者執行緒,生產者往資源池裡面放資源,消費者往資源池裡面取資源。放資源和取資源都需要加同步鎖。如果資源滿了,生產者就sleep一段時間後再生產,資源池沒有資源了,消費者就sleep一段時間後再消費。
不用sleep可以做到這個效果嗎?
答:不用sleep的話。如果資源滿了,呼叫物件的wait()方法等待。然後另一邊的消費者消費了就呼叫物件的notify()方法喚醒執行緒。同理資源池沒有資源了,消費者執行緒就呼叫物件的wait()方法等待,知道有生產者生產資源了喚醒消費者執行緒。
一組數,求出乘積最大值的連續幾個數
答:動態規劃法,快取之前儲存的最大的連續數的序列和乘積值,和新的不斷試探的值進行比較,遇到乘積序列在
二面
自我介紹
答:balabala。
MapReduce的問題在哪兒?
答:map和reduce之間有combine和partition的過程。這個地方比較耗時間。
HDFS的原理和底層實現
答:有一張元資訊表儲存block的資訊,block儲存實際的檔案,分佈在各個節點。只會用,沒有看過底層實現。
未來職業規劃
答:技術專家路線。
Spring的特性
答:IoC和AOP。
註解方式找物件的實現原理
答:Java的反射機制可以獲取類的屬性和方法等資訊,然後初始化這個物件。
為什麼使用Bootstrap
答:可以實現響應式頁面,降低前端門檻。
三之樂(Java開發)
9月14日筆試,9月20日拿到Java開發的Offer。總共有1次筆試+一次電話面試+三次現場面試。下面記錄一下我的經歷,希望能為後來人提供經驗。
①筆試
9月14日下午2:30去的公司。HR為我準備了一套試卷,要求在1小時內做完。難度不大,都是基礎題,有幾道記憶比較深的題,記錄一下。
1.給出一段英文句子。要求將英文句子逆序輸出來。例如“I’m a boy, she is a girl.”輸出”. girl a is she , boy a I’m”。
解析:如果中間全是空格的話,直接使用split方法得到一個數組,然後將陣列從後往前輸出來就可以得到結果。但是現在中間有標點符號,還是要老老實實的一個單詞一個單詞的去判斷,然後放進棧中,再輸出來。
判斷的方法,就是要使用兩個指標,後面的指標指向單詞的首字母,前面的指標找到空格,或者標點符號,就能判斷單詞的下標,然後就能把單詞和標點符號壓入棧中。還有就是要細心,考慮各種邊界問題。連續遇到幾個空格,幾個標點符號都是有可能的。
2.給定一個數據庫的表Test,表的內容如圖所示。
id | class | score |
---|---|---|
1 | one | 91 |
2 | one | 92 |
3 | two | 93 |
4 | two | 94 |
要求寫出一個SQL語句,得到如下的結果。
one | two |
---|---|
2 | 2 |
解析:看題目應該就知道要使用聚集函式count來實現。但是我們如果寫
select class ,count(id) from test group by class
得到的結果應該是這樣的。
class | count(id) |
---|---|
one | 2 |
two | 2 |
很明顯,這是一個行轉列的問題。當時沒有寫出來。回來查了資料之後,應該這麼寫。
select distinct
count(case class when 'one' then 1 else 0 end) one,
count(case class when 'two' then 1 else 0 end) two
from test
group by class
執行之後,就會得到題目要求的結果。Oracle資料庫的話有一個內建的pivot函式可以直接實現行轉列,SQL Server資料庫也有類似的函式。
但是雖然可以實現這種效果,擴充套件性幾乎沒有,下次還有一個three班級的話,又要改SQL語句。所以在實際應用中還是正規的查詢出來資料,在程式碼中實現自己想要的結果吧。
3.專業名詞解釋。
解析:這個主要就是看一下知識的廣度了。沒什麼好說的。
其他的都比較容易,也沒什麼好說的。
② 一面技術面
試卷做完之後,交上去之後,面試官就拿著一張表格來面試,上面有很多基礎問題。
先讓自我介紹,然後照著表格上的問題,一路問下來。很多問題有答案了,就不會深入問下去。都比較容易,問你對IoC和AOP的理解,Web容器的優化等等。
問你有沒有什麼想問面試官的,問了一下公司的情況和這個崗位的情況。
③二面技術面
一面面完之後,過了一個小時,深圳的面試官電話面試,還是技術面。
先讓自我介紹,然後對做過的專案中的技術進行詳細的瞭解。然後得出的結論就是我學習的Struts2已經過時了,他們已經在用SpringMVC了。繼續問一些記憶體的優化技術,資料庫的優化技術,等等。
問你有沒有什麼想問面試官的,問了一下公司的情況和這個崗位的情況。
④三面HR面
中間週六週日,沒有什麼動靜了,然後週一來電話,通知終面。面試官應該是HR。
先讓自我介紹,然後聊做過的專案,實習在哪裡,和技術沒什麼關係。最後終於聊到薪酬了。問期望的薪酬。我報了一個數,HR自己也拿不定。又喊來一個同事,又面了一次技術面。
⑤四面技術面
四面面試官貌似級別更高了一點。
先讓自我介紹,然後問我JVM的優化,資料庫的優化,Web容器的優化,CDN的原理,叢集方面的經驗,MapReduce的原理,Redis有沒有使用過,有沒有使用過佇列來削平訪問高峰,壓力測試自己的專案可以承受多大的併發量,有哪些優化措施。技術方面沒有多大問題了,又開始聊薪酬和公司發展前景以及個人規劃,最後可能我要價太高,面試官還是決定不了薪酬。
就先讓我回去等訊息,他們再商量一下。
⑥收到Offer
最終,還是收到Offer,但是薪酬和自己預期的還是有一些落差。
感謝一直奮鬥的自己,感謝三之樂各位面試官抽出時間給我面試機會,讓我能夠發現自己的不足,並不斷進步。
結束語
上面的5個公司都沒有去,簽了其他的公司。