參加的是data數(shù)據(jù)平臺(tái)-大數(shù)據(jù)開發(fā)實(shí)習(xí)生的崗位面試,一面二面一起,全程視頻面試。兩位面試官態(tài)度都很好,當(dāng)提的問題我答不上來時(shí),面試官會(huì)耐心得做些引導(dǎo),體驗(yàn)還是比較好的。
一面
- 自我介紹
- 項(xiàng)目經(jīng)歷
主要聊的是實(shí)驗(yàn)室做的一個(gè)數(shù)據(jù)流可視化分析平臺(tái),面試官問的問題很專業(yè)。簡(jiǎn)歷上有三個(gè)項(xiàng)目,除了數(shù)據(jù)流可視化分析平臺(tái)之外還有兩個(gè)大學(xué)做的項(xiàng)目,面試官?zèng)]怎么問,他讓我自己講下亮點(diǎn),于是我就簡(jiǎn)單說了說放這兩個(gè)項(xiàng)目的目的——證明下自己的工程能力和算法能力。
這一部分和面試官聊的挺多,自認(rèn)為發(fā)揮的還可以。
- JVM基礎(chǔ)
3.1 JVM內(nèi)存結(jié)構(gòu)
3.2 類加載
3.3 垃圾回收
3.4 線程池ThreadPool
我基本上把JVM準(zhǔn)備的點(diǎn)都說了,過程比較順利,對(duì)自己答得也比較滿意。
- 做算法題
去除鏈表中的所有重復(fù)元素,返回去除后的鏈表指針。使用哨兵節(jié)點(diǎn),解決起來比較方便。
public static ListNode deleteDuplicates3(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode dummyHead = new ListNode(-1);
dummyHead.next = head;
ListNode last = dummyHead;
ListNode cur = head;
while(cur != null && cur.next != null){
if (cur.val == cur.next.val){
int val = cur.val;
while(cur != null && val == cur.val){ // 刪除所有重復(fù)節(jié)點(diǎn),僅保留只出現(xiàn)一次的節(jié)點(diǎn)。
cur = cur.next;
last.next = cur;
}
} else {
last = cur;
cur = cur.next;
}
}
return dummyHead.next;
}
一面結(jié)束后,面試官讓我在線等會(huì),馬上進(jìn)行二面。等了大概10多分鐘,二面就開始了。
二面
- 實(shí)驗(yàn)室研究課題介紹
面試讓我介紹下目前研究課題的內(nèi)容,我就把手頭在做任務(wù)的背景和方法介紹了一下。 - Java基礎(chǔ)
2.1 static關(guān)鍵字的理解
2.2 Object類中方法介紹,hashCode()、equals()、wait()、notify()、toString()等
2.1 回答還OK,2.2回答不是很好,因?yàn)橐矝]怎么準(zhǔn)備。
- 數(shù)據(jù)庫
2.1 MySQL索引理解
2.2 B樹與B+樹的區(qū)別
這一部分自我感覺還OK。
- 操作系統(tǒng)
4.1 進(jìn)程間通信的幾種方式
4.2 進(jìn)程調(diào)度
知識(shí)盲點(diǎn),回答的一塌糊涂。
- 計(jì)算機(jī)網(wǎng)絡(luò)
5.1 tcp擁塞控制和流量控制
回答的不是很滿意。
- 做算法題
6.1 輸出二叉樹最左下節(jié)點(diǎn)的值。解題思路:層次遍歷,從右往左依次進(jìn)隊(duì)列,最后出隊(duì)列的即為輸出。
/**
* 尋找樹中最左下角的值
* @param root
* @return
*/
public int findBottomLeftValue(TreeNode root) {
TreeNode cur = null;
//隊(duì)列
Queue<TreeNode> queue = new LinkedList();
//根節(jié)點(diǎn)入隊(duì)
queue.offer(root);
while(!queue.isEmpty()){
//出隊(duì)一個(gè)元素
cur = queue.poll();
//按順序入隊(duì)其右孩子和左孩子
if(cur.right != null)
queue.offer(cur.right);
if(cur.left != null)
queue.offer(cur.left);
}
//所有元素出隊(duì)后拿到的就是最后一個(gè)節(jié)點(diǎn),返回
return cur.val;
}
6.2 第一個(gè)錯(cuò)誤的版本。解題思路:二分法。
public int firstBadVersion(int n) {
int left = 1;
int right = n;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (!isBadVersion(mid)) {
left = mid + 1;
} else {
if(mid == 0 || !isBadVersion(mid - 1)) return mid;
right = mid - 1;
}
}
return -1;
}
兩道算法寫的比較順利,可能是面試官太nice了,沒出太難的算法題。
- 提問環(huán)節(jié)
7.1 由于二面中2-5回答的不算很好,我就解釋下,說我理論知識(shí)需要加強(qiáng);不過平時(shí)工程能力還OK,上手速度快,善于解決問題,屬于問題導(dǎo)向型。
7.2 問了一下data數(shù)據(jù)平臺(tái)部門使用的大數(shù)據(jù)框架,比如spark、flink,面試官說都會(huì)用到。
二面結(jié)束后,我就問HR小姐姐什么時(shí)候會(huì)出結(jié)果。沒想到HR很快回復(fù)了,說我二面通過了,并且預(yù)約了三面的時(shí)間。天吶,還有三面。
三面
本來HR小姐姐說,這是最后一面,我就理解為HR面,沒想到啊,竟然還是技術(shù)面。弄了半天,HR小姐姐搞錯(cuò)了,三面還是技術(shù)面,過了之后才是HR面(最后一面)。整個(gè)面試過程持續(xù)2個(gè)小時(shí),真的是太漫長了~不過面試官還是很nice的,會(huì)有提示和引導(dǎo)。
不說廢話了,進(jìn)入正題。
- 自我介紹+項(xiàng)目介紹
回答和一二面差不多。
- 算法題目
2.1 MapReduce實(shí)現(xiàn)PV統(tǒng)計(jì)
MapReduce代碼不是很熟,面試官說讓我講講思路就可以。
問題延伸:1. 堆排序應(yīng)該放到哪個(gè)階段?——Reduce階段;2. 建堆的時(shí)間復(fù)雜度——O(n)
2.2 自己實(shí)現(xiàn)一個(gè)BlockingQueue。
public class BlockingQueue {
private final Queue<String> queue = new LinkedList<>();
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public String get() {
try {
lock.lock();
while (queue.peek() == null) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return queue.remove();
} finally {
lock.unlock();
}
}
public void put(String request) {
try {
lock.lock();
queue.offer(request);
condition.signalAll();
} finally {
lock.unlock();
}
}
}
沒回答好,不過在面試官不斷提示下,還是有些思路——使用wait和notify實(shí)現(xiàn)。問題延伸:notify和notifyAll有什么區(qū)別。
2.3 DAG的拓?fù)渑判?/p>
因?yàn)檫@一部分和項(xiàng)目介紹相關(guān),所以比較熟。思路就是統(tǒng)計(jì)一下每個(gè)節(jié)點(diǎn)的入度,輸出所有入度為0的節(jié)點(diǎn)。但面試官說能不能不先遍歷圖,直接輸出。面試官真的很耐心,提示我參考二叉樹的后序遍歷——先子節(jié)點(diǎn)然后父節(jié)點(diǎn),注意使用棧,和記錄訪問日志。
public class DAG {
class Node{
String val;
List<Node> children;
public Node(String val){
this.val = val;
this.children = new ArrayList<>();
}
public void addChild(Node node){
this.children.add(node);
}
}
private Stack<String> stack;
private Set<String> visited;
public DAG(){
stack = new Stack<>();
visited = new HashSet<>();
}
public void core(Node root){
if (root == null || visited.contains(root.val)){
return;
}
for (int i = 0; i < root.children.size(); i++){
core(root.children.get(i));
}
if (!visited.contains(root.val)){
stack.push(root.val);
visited.add(root.val);
}
}
public String topoTraverse(Node root){
core(root);
StringBuilder stringBuilder = new StringBuilder();
while (!stack.isEmpty()){
stringBuilder.append(stack.pop());
}
return stringBuilder.toString();
}
public static void main(String[] args) {
DAG dag = new DAG();
Node a = dag.new Node("A");
Node b = dag.new Node("B");
Node c = dag.new Node("C");
Node d = dag.new Node("D");
Node e = dag.new Node("E");
Node f = dag.new Node("F");
a.addChild(b);
a.addChild(c);
b.addChild(d);
c.addChild(d);
d.addChild(e);
e.addChild(f);
a.addChild(f);
System.out.println(dag.topoTraverse(a));
}
}
- 愛好
- 提問環(huán)節(jié)
雖然感覺自己發(fā)揮不咋的,但還是過了。可能是面試官看中了我的潛力~~~
HR面
順利通過~
內(nèi)推內(nèi)推,很認(rèn)真的內(nèi)推,免筆試的那種哦
號(hào)外!號(hào)外! 字節(jié)跳動(dòng)研發(fā)提前批開始啦~大量坑位,歡迎大家來占哦~網(wǎng)申時(shí)間6月16-7月16日,機(jī)會(huì)多多,快快投遞簡(jiǎn)歷吧,內(nèi)推碼:GHT9VNC
感興趣的同學(xué)可以留言交流~
