「面經」你可能需要的字節跳動三輪面經


目錄

前言

七月收獲了字節的意向書,今日得空把面經整理出來分享給大家,也借此把好運分享給大家

簡單介紹下個人情況:

面試前:劍指 offer 刷完,Leetcode 大概 70 道。操作系統復習完畢,數據庫不會,計網不會。

后來:一面前一周學了數據庫,三面前三天學了計網。兩周時間陸續刷了 80 道 Leetcode。

希望這篇文章能對大家有所幫助,祝各位 offer 多多!

三輪面經

本人無實習,故而沒有被問到關於項目的問題。

問題構成:手撕代碼、基礎知識、場景題。

「基礎知識」都是固定答案,因此本篇中只分享題目,不分享答案。

一面

  • 手撕代碼

easy 題:中文字符串轉成數字。例:“五百三十萬六千零三” -> 5306003。約束:輸入金額在一億以內。要求:做一定的容錯處理,bug free。

這題比較簡單,方法大家應該都能想到。只是要求 bug free 和容錯處理,因此寫代碼的時候要考慮完善點。比如說輸入異常的情況(字符串是否合法,“五五百”這種就不合法,“3百五”也不合法)。

  • 手撕代碼

leetcode medium 原題:判斷字符串是否滿足斐波那契規則,如:“199100199”。由於 1 + 99 = 100,99 + 100 = 199。

這題老汪是在面試官的引導下才一步一步想到最優解的。(吹爆面試體驗,面試官很耐心的在引導,nice!)

這題的關鍵點就在於如何找到開頭兩個數字 n1, n2。找到了這兩個數字,后面就可以用 n = n1 + n2 的規則通過一次遍歷來判斷是否符合斐波那契規則。找開頭倆數字只能暴搜了,代碼如下:

public boolean solve(String str){
 if(str == nullreturn false;
 int n = str.length();
 for(int i = 1; i < n; i++){
   int n1 = Integer.parseInt(str.substring(0, i)); //獲得第一個數
   for(int j = i + 1; j < n; j++){
     int n2 = Integer.parseInt(str.substring(i, j)); //獲得第二個數
     if(judege(str, n1, n2, start)) return true;//判斷是否符合規則
   }
 }
 return false;
}

//給定 n1, n2,判斷字符串是否符合斐波那契規則
boolean judge(String str, int n1, int n2, int start){
 int n = str.length();
 for(int i = start; i < n;){
   int n3 = n1 + n2;
   int len = (n3 + "").length();
   if(start + len > n || n3 != Integer.parseInt(str.substring(i, i + len))) return false// 下標超了,或者后一個數字不等於 n3
   i += len;
 }
 return true;
}

時間復雜度:O(n^3),找到開頭兩個數字需要 O(n^2),判斷字符串是否符合規則需要 O(n)。

這題可以剪枝來稍微降低一些時間消耗,大家可以自行優化。

  • 手撕代碼

10億個無序整數找出中位數。

這題老汪也是在面試官的引導下才一步步想到最優解的。(再次吹爆面試體驗)

由於是 10 億個整數,因此無法在內存中處理。也就是說要采用合適的外排序算法。

這里可以使用桶排序,使用 n 個區間均勻的桶,遍歷一遍整數,將它們存入對應區間的桶中,並統計桶中數字個數。這樣就可以找到中位數所在的桶,如果桶中數字還是很多,再進行桶排序,否則進內存中排序即可。

二面

  1. 事務的 ACID 特性

  2. Innodb 使用的索引結構

  3. b+ tree 的優點,為什么要用它

  4. 給定復合索引 (a, b, c),查詢語句中用 where a = 1 and c = 1,索引是否會失效?(最左前綴匹配的相關知識)

  5. 一條 SQL 語句的執行流程 (不會)

  6. 進程和線程的區別

  7. 並發和並行的區別

  8. 進程調度的策略

  9. 死鎖發生的原因

  10. leetcode 原題 41 (不會,換了一題)

給你一個未排序的整數數組,請你找出其中沒有出現的最小的正整數。

思路:要找最小的正整數,數組中有 n 個數字,那么缺失的最小正整數一定在 [1, n + 1] 內。

因此可以利用數組本身做哈希,遍歷一遍數組,將 [1, n] 內的數字 i 放到對應下標 i - 1 上。

再遍歷一遍數組,第一個 nums[i] != i + 1 的數字 i + 1即為缺失的最小正整數。

代碼如下:

public int firstMissingPositive(int[] nums) {
  int n = nums.length;
  for(int i = 0; i < n; i++){
    while(nums[i] > 0 && nums[i] <= n && nums[nums[i] - 1] != nums[i]){ //(0, n] 的數字放到對應下標上
      int temp = nums[i] - 1;
      nums[i] = nums[temp];
      nums[temp] = temp + 1;
    }
  }
  int i = 0;
  for(; i < n && nums[i] == i + 1; i++); // 找到第一個未出現的正整數
  return i + 1;
}

時間復雜度:O(n),雖然有 while 循環,但每個數字最多被交換一次即可到對應下標上。

  1. leetcode 原題 3

給定一個字符串,請你找出其中不含有重復字符的 最長子串 的長度。

思路:很經典的一道題了,滑動窗口即可解決。

代碼如下:

public int lengthOfLongestSubstring(String s) {
  if(s == nullreturn 0;
  Map<Character, Integer> map = new HashMap<>();
  int start = 0, ans = 0;
  for(int i = 0; i < s.length(); i++){
    char c = s.charAt(i);
    if(map.getOrDefault(c, -1) >= start) start = map.get(c) + 1;
    map.put(c, i);
    ans = Math.max(ans, i - start + 1);
  }
  return ans;
}

三面

  1. 手撕代碼

算法題:二維數組,按行遞增,按列遞增,問是否能找到某個數字(劍指offer原題)

思路:利用遞增的特性,從最左下角開始遍歷(該列最大值,該行最小值)。和目標數字比較:

< 目標數,說明這一列都 < 目標數,因此列下標 + 1

> 目標數,說明這一行都 > 目標數,因此行下標 - 1

這樣,每次比較都可以排除一行/一列。

代碼如下:

public boolean canFind(int[][] matrix, int target){
 if(matrix == null || matrix.length == 0return false;
 int rows = matrix.length, cols = matrix[0].length;
 int row = rows - 1, col = 0;
 while(row >= 0 && col < cols){
   if(matrix[row][col] == target) return true;
   if(matrix[row][col] > target) row--;
   else col++;
 }
 return false;
}
  1. 手撕代碼

算法題:2 * 1 的小矩形填充滿 2 * n 的大矩形有多少種方案?

思路:挺簡單的動態規划題

代碼如下:

public int nums(int n){
 if(n < 0return 0;
 int[] dp = new int[Math.max(n, 2)];
 dp[0] = 1;
 dp[1] = 1;
 for(int i = 2; i < n; i++) dp[i] = dp[i - 2] + dp[i - 1];
 return dp[n];
}

這里空間復雜度是 O(n),也可以通過 狀壓 dp 將空間復雜度降到 O(1)。

  1. 場景設計

1000 億個無符號整數,找最大的 100 個。內存不夠的情況下用什么方案?內存充足的情況下呢? partition 的方案不穩定,有什么穩定的方法嗎?

內存不夠堆排序,內存夠用計數排序。

  1. https 如何加密的

  2. os 中的 pagefault (缺頁中斷)

  3. mysql 中的底層索引結構?為什么用這個結構

  4. hashmap 是線程安全的嗎?想要線程安全怎么辦?

  5. 場景設計

大文件的斷點續傳

這題網上也有很多方案。老汪是參照 tcp 的滑動窗口和重傳機制來回答的。

把大文件分塊並打上編號,接收端對塊進行有序確認,如果有某塊沒收到,就告知發送端讓其重發。

發送端記錄最后一次發送的編號,斷點續傳時從這個編號開始傳。

因為負載均衡,續傳的時候要確定從哪個服務器拿的,這個可以讓接收端記錄發送端的標識。

關於字節

  1. 工作強度:大小周,10 10 5.5。不強制加班,做完就可以走,但工作量一般要加班完成。因人而異,也有摸魚的。

  2. 福利:三餐全包,下午茶,房補 1500,免費健身房(基本上工作一年后都會吃胖,hhh)

  3. 氛圍:扁平化管理,網傳風評都挺不錯的。

  4. 新人培養:mentor 制,一對一帶領新人熟悉。不過和老牌 BAT 相比,文檔不夠完善,新人培養流程還是有些欠缺的。

  5. 字節校招的考察重點:后端的話,基本上是要轉 go/python 的,所以不怎么考察語言。

主要考察「操作系統」、「數據庫原理」、「計網」和「手撕代碼」,字節是非常重視手撕的,這個一定要好好准備。當然項目做得好的同學,也是有加分的。

老汪點評:工作強度大,面對的挑戰多,薪酬也給力。適合能力強、抗壓能力強的同學,扛得住壓成長會很快。不過對新人確實有點考驗,因人而異吧。

彩蛋

  1. 雖然字節的手撕代碼比較難,但題庫是有限的,多刷面經中的算法題,會有很大概率碰上原題。
  2. 有三面掛了的,想投上海 data 部門的,老汪可以幫忙聯系 HR 直撈。
  3. 點贊的各位小伙伴 offer 多多。沒點贊的小伙伴嘛,也 offer 多多吧。嘻嘻~
  4. 聽說發一句 “一切都會好起來的!”,就 真的一切都好起來了!
一切都會好起來的
一切都會好起來的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM