# bytedance 面試準備 ## 複習 * quick sort * https://hackmd.io/@Rance/ryzJ8-eAw * quick select * Done * Min heap * https://hackmd.io/@Rance/S1eJ_ePsS * BinarySearch ``` int binarySearch(int arr[], int l, int r, int x) { while (l <= r) { int m = l + (r - l) / 2; if (arr[m] == x) return m; if (arr[m] < x) l = m + 1; else r = m - 1; } return -1; } ``` ## Kafka mmap 做了啥? 直接將 device IO 當作 memory address 操作 當 kafka msg 進到 socket buffer 的時候直接往 memory address 寫(背後是 device IO) 這樣可以做到 zero copy (from kernal to user) > Kafka 持久化用了這個 DMA 是啥? 透過 DMA controller 直接把資料從 Device 不走 cpu 塞進 memory 本質上操作的還是 memory 的數據只是繞過 CPU Copy ## DB 部份 ### 事務性和非事務性 * 是否支援 transaction 的差別,理論上非事務性的效能會比較好(? * 只做 insert 和 ETL 的是否可以用設定為 non-trnasaction(推測 * 記憶體用量,讀取效能方面都比 innodb 好 * 比較著名不支援 transaction 的 mysql kernel 是 MyISAM,支援的是 innoDB ### ACID 的 I 又名:数据库的隔离级别 幾個典型問題:Dirty Read/Non-repeatable reads(對 raw 內容)/Phantom reads(對筆數) * Read Uncommitted: 代表 transaction 可以讀到別的 transaction 尚未 commit 的資料,在這個等級中三個問題都沒有解決。 * Read Committed: 代表 transaction 只能讀到別的 transaction 已經 commit 的資料,沒有 commit 的話就不會讀到,在這個等級解決了 Dirty Read 的問題。 * Repeatable Read: 代表每次 transaction 要讀取特定欄位的資料時,只要 query 條件相同,讀取到的資料就會相同。在這個等級解決了 Non-repeatable reads 的問題。 * Serializable: 代表在多個 transaction 同時執行時,只要 transaction 的順序相同時,得到的結果一定相同。比如說 Transaction A 先執行了接下來再執行 Transaction B,在同樣的條件下,每次執行都會得到一樣的結果。在這個等級下連同 Phantom reads 也會一併被解決 > Gap Locks 可以在 Repeatable Read Level 解決一部分 Phantom reads 的問題,例如 > `SELECT * FROM `test` WHERE `id` BETWEEN 5 AND 7 FOR UPDATE;` 會直接鎖住 id 5~7 的欄位,但相對的鎖的範圍更大,Dead lock 的機率更高 > Gap Lock 如果是基於 Snapshot isolaton 做 read only lock,無法防範 write skew 的發生,Phantom reads 依然存在,這時候一定要用 Select for update。 [Reference](https://medium.com/getamis/database-transaction-isolation-a1e448a7736e) ### Snapshot isolaton 大多 Repeatable read 層級的實作方案,具體參考 https://zh.wikipedia.org/wiki/%E5%BF%AB%E7%85%A7%E9%9A%94%E7%A6%BB 相對的會有 write skew 的問題 #### Example of write skew 假設我們今天有一個條件,帳戶 A+B 的總額不得小於 0,在 Snapshot isolaton 的實作下兩個 Transaction 會同時成功 ```sql= Transaction 1 UPDATE account SET accountA_credit = accountA_credit - N WHERE accountA_credit + accountB_credit > N; Transaction 2 UPDATE account SET accountB_credit = accountB_credit - N WHERE accountA_credit + accountB_credit > N; ``` 因為對 Transaction 1 只對 accountB_credit mark 為 read,只要 Snapshot 跟更新前相同就可以成功。 因為對 Transaction 2 只對 accountA_credit mark 為 read,只要 Snapshot 跟更新前相同就可以成功。 結果就導致兩個帳戶同時被扣款,帳戶結餘為負值。 可以用 select for update 來避免 > 把所有 lock 層級上升到 exclusive lock 的級別來避免 write skew,他會把所有 read upgrade 成 write (Replace with the same value) > 複寫同樣的值有相同效果 > UPDATE account SET accountA_credit = accountA_credit - N, accountB_credit = accountB_credit WHERE accountA_credit + accountB_credit > N; ### Cluster index > 盡量對數字類型做 index 而非字串類型。 先從 index 的格式講起,創建一個 index 的語法如下 `CREATE INDEX IDX_CUSTOMER_LAST_NAME ON Customer (Last_Name);` 而 B+ tree 長的是這樣的 ![](https://i.imgur.com/VbygBAw.png) * Cluster index 每個表的 Cluster index 只能有一種,資料會直接按照 Cluster index 的排序方式擺放,也就是 cluster index 組成的 B+ Tree 會直接有序的指向資料。 這樣就可以非常方便的 sort 或是取出特定範圍的資料。 因此引出了以下的特色 1. 只能有一個,因為資料沒辦法同時以多種排序擺放。 > 在 InnoDB 中就是 primary key > 可以一次把多個欄位綁定在一起成為一個 Composite Primary Key 2. 更新 Cluster index 的代價很大,因為會牽扯到實體資料的搬動 > 因此推薦使用 auto increment 作為 primary key 3. * Non-Cluster index 又稱 secondary indexes,二級索引,補充索引,在沒有 Cluster index 會在 key 下方儲存 row ID,在有 Cluster index 的情況下會儲存 Cluster index,搜尋時先找到 Cluster index 的編號再去對應的 B+ tree 裡面找資料,這種情況的效能較差。 * Leftmost Prefixing 這個在使用複合索引 (multiple column index) 的時候會出現的概念,假設今天我們使用 (A,B,C) 實際上會被拆成 A/A,B/A,B,C 三種方式下去搜,所以最有分辨率的盡量放左邊 multiple column index 的實現 -> B+ Tree leaf node 套 B+ Tree 一路套下去就行 (A,B,C) 的意思其實就是 Sort by A then Sort by B then Sort by C 的意思 所以對下面的 SQL 實際作用是 ``` select * from table where c1 = ? and c2 = ? 有用,在 c1 filter 出來的 sub tree 內再用 c2 filter 一次就行 select * from table where c1 = ? order by c2 asc 有用,c1 後面就是 sort by c2 的,直接返回就可以 select * from table where c1 = ? and c3 = ? 有部分作用,僅止於可用 c1 做 filter 找出多筆資料,但對 c3 的處理必須另外全量做。 select * from table where c1 = ? order by c3 asc 同上 ``` ### 撈資料的三種優化方式 如果今天,我們希望撈一筆資料`select id, score from student where score > 50` 但 score 沒有 index,那我們有以下三種操作 1. 建立 score 的 non-clustered index: 額外 query 所需要的 non-clustered index ,如此一來該搜尋就會變為 Index Seek/Scan 但這樣是最慢的,依然需要跑兩層的 B+ tree 2. Covering index: 利用原本的 CustomerID non-clustered index,只是把所需的資料 Address複製一份到該 non-clustered index 的 leaf node。這樣index Scan/Seek 就只要在 Balance Tree 搜尋即可回傳所有該 Query 的資料。不需要額外建立 index,僅需要將資料複製到 index 的做法,稱為 “Covering index”。 Non-Clustered Index (Customer ID) + Copy “Address” 這裡有個例子 使用複合索引的情況下,如果 scan 的索引包含所有所需的資料,如 ``` CREATE INDEX sales_sub_eur ON sales ( subsidiary_id, eur_value ) // 以 subsidiary_id 建立 index, 並在 page 層寫入 raw + eur_value SELECT SUM(eur_value) FROM sales WHERE subsidiary_id = ? ``` 這樣在搜尋時就不用回頭做 raw key look up, 直接把 index page 裡面的資料拿出來就行,因此 MySQL 在 explain 下會顯示 using index. 另一種操作是 ![](https://i.imgur.com/cfwGzdP.png) 先從 Primary key 把 data 抓出來並排序,然後再基於這個範圍去搜,這是針對 limit 的優化,基本上就是先 filter 後拿資料 and 拿資料後 filter 的差別 > 如果每次只需要SELECT少部分欄位且範圍較大又須排序,Covering Index執行效率會比CLUSTERED INDEX來的快. 參考 https://www.red-gate.com/simple-talk/sql/learn-sql-server/using-covering-indexes-to-improve-query-performance/ & https://dotblogs.com.tw/daniel/2020/02/16/172554 non-clustered index on (CustomerID, Address): 複合式欄位的 non-clustered index,同時將兩個欄位一起建立成 Non-clustered index 這部份的效率不確定 參考 https://www.qa-knowhow.com/?p=377 ### 新手的結論 1. InnoDB 讀資料是以 page 為單位,load 一個 page 只為讀一筆資料是很浪費效能的行為。挑選好 primary key,讓關聯資料集中在幾個 page 裡面,這樣 InnoDB 可以 load 一個 page 讀到多筆資料。 2. Secondary index 去抓 row data 會需要多一次 lookup 動作,而且如同第一點提到的,單一筆資料的存取會浪費效能。因此讓 secondary index 涵蓋所有需要的欄位對效能會有顯著提升。 ### hash索引和B+树索引 hash索引 僅能應用在精準比對上,排序或取範圍都幫不上忙,可以使用一個有部份機率碰撞的 hash function,帶上 hash value 跟精準值一起做搜尋的效能會很好。 ![](https://i.imgur.com/7xWImK8.png) 參考 https://www.zhihu.com/question/67094336 ### 正規化 類似為不同的資料做 mapping ,重點在於去重 第一正規形式(1NF) ~刪除各個資料表中的重複群組。 ~為每一組關聯的資料建立不同的資料表。 ~使用主索引鍵識別每一組關聯的資料。 > 打上 timestamp + id 可以解決這部份需求 第二正規形式(2NF) ~為可套用於多筆記錄的多組值建立不同的資料表。 ~使用外部索引鍵,讓這些資料表產生關聯。 同一張 table 中的資料不該有相依於 primary key 的,相依者應該另外拉一張 table 建立 foreigner key 做 mapping 參考 https://www.mysql.tw/2013/03/normalization.html 講的很好 第三正規形式 ~刪除不依賴索引鍵的欄位。 所有資料都不能依賴於主鍵以外的資料,也就是 primary key 以外的資料互相之間絕無相依性。 參考 https://zh.wikipedia.org/wiki/%E7%AC%AC%E4%B8%89%E6%AD%A3%E8%A6%8F%E5%8C%96 ## Partition [英文參考](https://dba.stackexchange.com/questions/65665/partition-by-year-and-sub-partition-by-month-mysql) [中文參考](https://xyz.cinc.biz/2015/07/mysql-partition.html) 將資料分成不同的小塊儲存,以下舉幾個例子 ```sql= CREATE TABLE sales { ... created_at DATETIME NOT NULL } ENGINE=InnoDB PARTITION BY RANGE(YEAR(created_at)) ( PARTITION p2015 VALUES LESS THAN (2015) PARTITION p2016 VALUES LESS THAN (2016) PARTITION p2017 VALUES LESS THAN (2017) PARTITION p9999 VALUES LESS THAN MAXVALUE ) ``` 要指名 `PARTITION p2015 VALUES LESS THAN (2015)` 是因為 mysql 的限制 ``` In MySQL 5.6, it is possible to subpartition tables that are partitioned by RANGE or LIST. Subpartitions may use either HASH or KEY partitioning. This is also known as composite partitioning. ``` 因此沒辦法單純 `RANGE(YEAR(created_at))` 就好,需要直接指名分區,想要把資料持續按照年份分,對於持續發展的服務有兩種解法。 1. 指名 range,到期後換表 ```sql= CREATE TABLE sales15-17 { ... created_at DATETIME NOT NULL } ENGINE=InnoDB PARTITION BY RANGE(YEAR(created_at)) ( PARTITION p0000 VALUES LESS THAN (2015) PARTITION p2017 VALUES LESS THAN (2017) PARTITION p9999 VALUES LESS THAN MAXVALUE ) ``` 並且在 17 年到了之後開新的表 ```sql= CREATE TABLE sales17-19 { ... created_at DATETIME NOT NULL } ENGINE=InnoDB PARTITION BY RANGE(YEAR(created_at)) ( PARTITION p2015 VALUES LESS THAN (2017) PARTITION p2016 VALUES LESS THAN (2018) PARTITION p2017 VALUES LESS THAN (2019) PARTITION p9999 VALUES LESS THAN MAXVALUE ) ``` 中間有一個重複的 Range 代表我們可以提早把 table 切過去 2. 用 Hash 去分(不推薦) ```sql= CREATE TABLE aa ( id INT NOT NULL, mydate DATE NOT NULL DEFAULT '1970-01-01' ) PARTITION BY HASH(id) PARTITIONS 3; ``` 不推薦的原因是 HASH 本身也是有成本的,而且 PARTITIONS 的數量依然沒辦法動態產生,若是年分超過三之後可能會有多個年份混在同一個分區的事情,這就很難解決了。 所以建議用上面的分表法比較好。 ### 切 partition 的好處都有啥 1. 可以定期移除部份 Partition 來避免 table 大小無限成長 2. 可以壓縮,批量分表,幫助分表分庫的後續操作 3. 增加 range query 的效能 ### 分散式事務 (distributed transaction) #### 2 Step commit 1. coodinator propose transation - failed -> return fail 2. follower record transation -> reply ok - failed -> coodinator received failed / timeout -> propose cancel 3. coodinator commit transaction - commit failed -> follower auto rollback - committed then down -> recover by log 4. follower commit transaction -> reply ok - commit failed -> retry & warning (depends on config) 5. coodinator confirm transaction committed. - retry if not received #### SAGA SAGA = LLT = long-lived transaction 就像 bybit bot 的做法 ## Liunx 部份 ### 线程安全和可重入、线程和进程 * Process/thread 獨立 or 共用記憶體區塊,隔離性也不同 在不同語言的意義上不同 * Go GPM * python -> GLI * C++ -> fork 可否重入要看是否有 function 本身是否有引用到外部的 status, * 同步机制、IPC(主动扩展到中断等中的现场安全) * 文件缓存机制(主动扩展到CPU多级缓存乃至网络上缓存、反向代理的概念) * 然后说我这反向代理的知识体系是十年前的,给我聊了下动态页面什么的。 * 问对UNIX的文件IO接口的某某机制有了解没,没听过的词,说没有。 * 问有UNIX、Windows下多线程编程经验没、读过APUE没,没有,然后就不问操作系统相关了。 * 操作系统虚拟内存换页的过程 4.用户态和内核态 ## multi-thread * 線程池的線程數怎麼確定? * 在取跟還得時候加鎖計算 * 如果是IO操作為主怎麼確定? * 視需求而定,通常不會特別計算,但會做 timeout * 如果計算型操作又怎麼確定? * 用 worker thread ## Redis * Redis熟悉麼,了解哪些數據結構? * 用過的 set, sorted set * 沒用過的 string, Lists, HyperLogLog, Hashes, Bitmaps, Bitfields, HyperLogLog * bitmaps 可參考這篇 * https://blog.csdn.net/u011957758/article/details/74783347 * 底層是 string,可以透過 and 之類的操作做到取出活耀是特定 pattern 的用戶 * 跳表的查詢過程是怎麼樣的,查詢和插入的時間複雜度? * 查詢跟插入都是 logn * 找到 range end -> 往前一層,看下一個 link 的 end,以此類推 * 紅黑樹了解麼,時間複雜度? * 查詢跟插入都是 logn * c++11 STL 的 set & map 大部分都是 * 既然兩個數據結構時間複雜度都是O(logN),zset為什麼不用紅黑樹 * The most is....Easy(By author) * redis基本数据类型以及如何实现的 * redis的三种集群 * Main & Follower: 基本的主從架構 * 好處:簡單,Follower 可按需分擔流量 * 壞處:單 Redis 的容量依然有限,數據有不一致的問題,任何一個節點掛掉都會影響服務 * Sentinel: 引入多個 Coordinator,監控 Main&Follower 狀態以及做 Failover * 好處:自動 Failover,減少單節點不可用對服務的影響,可自動切換 Master * 壞處:繼承 Main&Follower 除了 Failover 以外的所有缺點 * Cluster: 如下方敘述的網狀結構,最少配置 6 台(3Main+3Follower),Follower 只用於備份,不參與請求處理,借此提高一致性。 * 好處:進一步提昇可靠性,藉由請求重導可以做到在任何一台 Redis 都取得 Key 的效果,支援 Sharding(IMPORTANT!!!) * 壞處:對 Transaction 的支援能力降低,只支持多key在同一节点的事务操作(因為涉及請求重導就再也不是 atomic 了) > 這也是為什麼我們的 Redis 不能用 Transaction * 如果让你实现redis的负载均衡,你如何实现 * 參考 https://catkang.github.io/2016/05/08/redis-cluster-source.html * 基本上就是網狀結構,透過 HeartBeat 傳遞狀態,如果 Fail 的狀態傳遞過半,則送訊息給 Coordinator 進行投票。 * redis的通信协议是什么? * RESP,基於 TCP 的雙向協議,分為 ping-pong (一來一回) 及 pipeline 模式 * binary safe,所有請求有嚴格的長度限制,而不是像 CString 那種 '\0' 的終止方式。 * Redis的使用,分布式锁的实现 * 參考下方實現 * 乐观锁、悲观锁 * 樂觀鎖:基於 Version 的實現,如果 Version 被修改則回退 * Redis 使用 Watch + MULTI + EXEC 實現,如果 Multi~Exec 之前 Watch 的值被修改則無效(Multi 內部可以修改 Watch 的值,畢竟 Exec 之前並不會真的生效) * MySQL 使用以下語法 Update {table_name} set n=n+1, version=version+1 where id=#{id} and version=#{version}; * 此做法稱為 CAS, Compare and set || Compare and swap * 悲觀鎖:僅允許資源被一個對象所持有,其他人獲取會全部失敗 * Redis 使用 setnx 來完成,原子操作,僅獲取成功者會 return ture,需手動釋放及添加 TTL(一定要加,不然有可能死鎖),解鎖時需比較 Value 避免誤解鎖,Value 必須有唯一性。 * 會有單點故障的問題,因此引入了 Redlock,基本上就是共識決,必須要 n+1/2 數量以上數量的集群同意加鎖才行。 * MySQL 可以手動對行加上 excusive lock,或是用 select for update,或是直接開 Transaction,讓 innodb 自動幫忙解析要如何上鎖。 * 此處就會延伸出 isolation level 的問題,也就是 innodb 的上鎖策略 * Redis扩容机制 * Redis 的持久化機制 分為 RDF & AOF * RDF: Redis database file * 固定時間做 snapshot * 每過一個小時做一層快照之類的,可以儲存區間資料 * 有 save(Block until finish) & bgsave(fork),因為 Fork 共用 memory address,只對增量修改進行 CopyOnWrite * 基於 Linux 底層優化實現的,原本 Parent & Child 共享同一份內存 -> Page 的映射,標記為 Read-Only,寫入時觸發 Page Fault,複製一份新的並更新修改者的內存映射,此時雙方各自持有一份。 * 性能影響小 * AOF: Append only file * 原先類似 Binlog,記錄所有修改的操作,在 4.0 之後改為 RDB(全量) + Diff(AOF) * AOF 有三種 flush 機制 * No:只在 buffer 滿時 flush i/o,效能最高 * Aways:每個指令都 flush i/o,這樣最多只掉一條,效能最差 * EverySec:每秒 flush i/o,最多只掉一秒的數據,折衷方案 ## network http三次握手,如果第三次客户端发出的信息服务器没收到怎么办? socket编程和netty 如果让你实现按照优先级的抢占式调度,你会如何实现?有0-15个优先级,0是最高的优先级 3.https如何实现 对称加密+非对称加密 .get和post区别 epoll{讲了码实现, ET和LT在源码层面是怎么实现的 僵尸进程与孤儿进程 一致性哈希 手撕单例模式 ## Nginx * nginx 的用途 * TLS termination * reverse proxy * virtual hosting * cache, CDN ## Go 讲讲管道的源码 ## Question * 问:如果你入职的话知道要补哪些方面的知识么? * NoSQL 部份 ## coding test ### Top K problem * N 個 sorted arrat * 将每个数组的最小元素加入到优先队列中,每次从优先队列中pop出一个元素,然后push进同组的下一个元素,直到第k个 * N 個 unsorted arrat * 先全 sort 一次,剩下步驟如上 ### 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点 雙指針,一個先走一定距離即可 ### 给一个String,output the reversed order (e.g. Good Morning -> dooG gninroM) 按照 space 切 左右互相 swap ### 给两个有序数组找交集 (e.g. [1,2,4,5,6,7,9], [2,3,5,7,8,9] -> [2,5,7,9]) 用個 map 紀錄 ### SQL 用sql写选出第二高薪资员工,如果没有这个人就return NULL (参考: https://www.nowcoder.com/practice/8d2c290cc4e24403b98ca82ce45d04db?tpId=82&tags=&title=&diffculty=0&judgeStatus=0&rp=1) select emp_no,salary from salaries where to_date='9999-01-01' order by salary desc limit 1,1; ### Next permutation 從後面往前掃,找到後面比前面大的,標記為 target if 沒找到 = 跑完一輪了,整個 reverse and return 從後面往前掃,找到第一個比 target 大的,交換 target 後面 reverse 回最小值 ``` 1.n个有序数组中取最小的k个元素,包括复杂度分析 先答了n个指针通过比较每次取最小的那个O(nk)的算法;然后思考后又答了使用最小堆的O(n+klogn)的,然后让在白板上画出算法过程,要求证明n个元素的二叉堆的构建的复杂度是O(n),忘了怎么证。。。 ``` -> build minheap 應該是 nlogn ``` •那我們做一道題吧,數組A,2*n個元素,n個奇數、n個偶數,設計一個算法,使得數組奇數下標位置放置的都是奇數,偶數下標位置放置的都是偶數 ``` 股票买卖能够买卖ㄧ次 股票买卖能够买卖多次 ## 面試前準備 使用 Lark,一個 ByteDance 自己開發的辦公面試軟體,類似 Zoom 測試麥克風的功能很爛,至少加個聲音測試回放功能吧? ## 開始 自我介紹完直接開始刷題 buy sell stock 秒掉, C++ 的 range for 寫錯 QAQ 講講 Go 吧 gpm 模型 稍微講一下,然後提到 Preemptive 去 Go 在執行時會起多少個 Process Go 在 runtime 的 Process 閒置會怎麼應對 go 的網路 io go 的 disk io(直接炸掉) goroutine 結束後 Memory 是如何回收的 「透過通信來共享,而不是透過共享來通信」的意義 代码题:反转单链表。 代码题:复杂链表复制。 给出两个升序数组A、B和长度m、n,求第k个大的数 给出数组A,长度为n,数组中元素的值位于[0, n - 1]之间,求是否有重复元素 讲一下多线程与多进程区别 ## design 场景题目:设计一个短域名服务:短信存不了太长网站,需要弄成短域名,你该如何设计一个服务,可以为全国的网址服务。 sql题,写了个连表查询外加模糊查询 算法:镜像二叉树 ## TCP/IP 是針對 OSI 七層的簡化方案,TCP/IP 本身是一個「網路協議組」,只有四層,差別參考鳥哥資料 ![](https://i.imgur.com/YAtxjLU.png) 首先拔掉了實體(物理層)的差異,然後傳送到的資料全部交給應用處理。 TLS/SSL 在 wiki 中被歸類在應用層,也就是說應用層的協議是可以互相嵌套的。 所以 http 可以說是 Layer 7(OSI) 也可以說是 Layer 4(TCP/IP) ### 為什麼 TCP 要三次交握,四次揮手 #### 三次交握 一樣參考鳥哥的圖 ![](https://i.imgur.com/WyVzBCh.png) 最基本就是 * A:封包發起 (SYN by Client) * B:封包接收與確認封包傳送 (SYN+ACK 包在同一包 by Server) * C:回送確認封包 (ACK by Client) > TCP 是雙向連接,所以如果防火牆擋了連入/連出其中一個都會導致 TCP 連線建立失敗 #### TCP四次挥手 ![](https://i.imgur.com/oYgQLiM.png) 四次揮手斷開連接: 第一次揮手:主動關閉方發送一個FIN,用來關閉主動方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方:我已經不會再給你發數據了(當 然,在fin包之前發送出去的數據,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些數據),但此時主動關閉方還可以接受數據。 client 進入 Fin-Wait-1 第二次揮手:被動關閉方收到FIN包後,發送一個ACK給對方,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號)。 回覆 ACK 1 ~ Fin 1 的過程中有個 Close-Wait,意義在等待 server-application 處理完畢。 第三次揮手:被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,我的數據也發送完了,不會再給你發數據了。 第四次揮手:主動關閉方收到FIN後,發送一個ACK給被動關閉方,確認序號為收到序號+1,至此,完成四次揮手。 主動方此時進入 TIME-WAIT,等待兩個封包的生命週期,來確保沒有收到對方重發的第三次握手,如果收到對方重發的第三次交握包(FIN),我方也會重發一次第四次交握的封包 同時也避免太快釋出這個 socket fd 的話會有之前迷路的封包突然衝過來。 所以當你看到 MySQL Server 有大量 TimeWait 的封包怎麼辦 1. 排查是否有 Server 大量連線後沒有 close connection 2. 排查是否有使用短連線的 Server 3. 調整 Linux 網路參數,提早回收 socket fd 注意 epoll 有 65535 個 socket fd 的限制,如果被 CLOSE_WAIT 或是 TIME_WAIT 佔滿就會無法接收連線。 ## TCP MSS MSS = Maximum Segment Size 一個 TCP Message 能傳遞的資料我們希望越多越好,但這牽扯到 MSS 大了可能會因為 MTU 被切成多個封包,對接收端也有影響。 MTU = Maximum Transmission Unit Router 單次能接收的「單一封包大小」,故一個 MSS 可能被切成多個 MTU 送出 > 這意思不太精確,但大致上的意義是這樣。 如果送給一個 Router 超出對方 MTU 大小的包,可能會有三種可能。 1. Receive ICMP “packet too big” 2. Split by Router(When Router to Router) 3. Discarded by Router(Not in RFC) > Ipv6 開始已經不支援 2 的行為,容易被 attack 利用。 > 部分 Router 為了加快效能,會直接採取 3 的做法 所以為了確保自己的封包能正常到達,MSS<=MTU 是最穩的作法。 Different: | Name | exceed action | | ---- | -------------------------- | | MSS | Invalid package, discarded | | MTU | Split to multiple packages | ## Select/Poll/Epoll * Select * check each fd status * 1024 fd limitation, using a statis size array * Copy fd array * poll * Check each fd status * no fd limitation, using linked list * epoll * Event trigger, made by rbtree + callback & a queue * LT(level trigger): 可读则返回 * ET(Edge trigger): 只返回一次可读 * epoll 让 user and kernal share same memory space, reduce copy ## HTTP study note: https://hackmd.io/@Rance/BJHDdsMRD ### Get和Post区别 #### Get * GET requests can be cached * GET requests remain in the browser history * GET requests can be bookmarked * GET requests should never be used when dealing with sensitive data * TLS 會加密 Url, Header 等東西。 * GET requests have length restrictions * GET requests are only used to request data (not modify) #### Post * POST requests are never cached * 這是 RFC 的規範,瀏覽器一定會照做,但伺服器跟 CDN 可以自行控制行為。 * POST requests do not remain in the browser history * POST requests cannot be bookmarked * POST requests have no restrictions on data length ### 延伸閱讀 InfoSec 是怎麼擋 Port 的 為什麼我可以直接 Reverse ssh to ec2,但沒辦法 Reverse ssh to ngrok URI? 1. 有沒有辦法擋掉 Reverse ssh ? * 沒有辦法,因為 Reverse ssh 是建立在 ssh 的連線之中的,除非把 ssh 這個協議整個擋掉,不然沒辦法只允許 SSH 卻不允許 Reverse ssh 2. 那為什麼我沒辦法 Reverse ssh to ngrok URI * 公司把對 10. 以外的 SSH request 全部 Ban 掉了,所以其實是完全不讓你 SSH 到外網去。 3. 那我有沒有辦法從外網打到公司內部網路? * 目前的話,可以。 1. 從公司機器開一個 SSH tunnel 到 EC2,做 port forwarding 2. 在 EC2 上用 Ngrok 開一個 Http WebSocket 對外,作為 SSH 登入的界面 3. 從外網登入 Bastion(步驟二的 EC2),然後再 SSH 進公司機器 * 有辦法檔嗎? * 很難,除非不讓公司機器對 EC2 送 SSH 連線,或是不讓 EC2 接 HTTP request * 有辦法監控嗎? * 有,InfoSec 的角度可以觀察持續過久的連線,過一陣子就斷掉這個連線 * 如果連線會被斷,有辦法解決嗎? * 可以自動重建 SSH 連線(參考 autoSSH),常常換 EC2,用浮動 IP 連線等,由於沒辦法把協議擋掉,所以基本上就是個貓捉老鼠的問題。 ## gRPC ![](https://i.imgur.com/iorkRU3.png) gRPC FrameWork 提供同步跟異步的作法處理連接。 ## SMTP 從 SMTP~ESMTP, SPF/DKIM/DMARC 都有 [study note](https://hackmd.io/@Rance/S1-Yu-NAv) > 以下皆是過期資料,可跳過。 ## Hr 面 介绍一下自己 前面几轮面试体验怎么样 自己最不能忍受的一个点 别人对自己的一个评价 对字节跳动的看法 讲一讲华为软挑比赛 比赛时侯有没有碰到什么难点 如何配合协作 在实习时侯的一些收获 如果自己是顶目组的一个Leader,组内有人进度老是拖延你会怎么办 如果收获了字节阿里腾讯offer怎么选? 能不能来提前实习 反问环节 What exciting news it is! However, I have scheduled another interview that day last week. Even though Bytedance is my first choice, a promise is a promise. Would you help me to set up the another day? Any time after 2021/01/13 will work. [Reference](https://www.jianshu.com/p/5476af091050) 1. 自我介绍 2. 毕业时间 3. 是否考研 4. 高考志愿 5. 专业人数 6. 专业排名 7. 有无实习 8. 大学生活 9. 学 生会哪个部门 10. 参加什么社团 11. 参加什么比赛 12. 获得什么奖 13. 有无团体赛经历 14. 参赛时间 15. 项目背景 16. 项目分工 17. 是否项目组长 18. 项目用什么编程语言写的 19. 自己选的编程语言还是老师给选的 20. 团队分工是你安排的还是各自认领的 21. 团队内产生分歧怎么办 22. 做项目过程中对你来说最大的挑战是什么 23. 大学中让你最有成就感的事情 24. 班里担任什么职务 25. 参加比赛和项目,收获了什么 26. 有发表论文吗 27. 平时的兴趣爱好 28. 老家是哪里的 29. 意向工作地点 30. 职业规划 31. 目前主要在干什么 32. 还投递了哪些公司 33. 对行业有什么倾向 34. 如何看待互联网行业的工作强度 35. 家里人对工作和考研有什么看法 36. 遍地都是研究生,不考研会有遗憾吗 37. 工作后还会去考研吗 38. 自制力高吗 39. 喜欢玩什么游戏 40. 什么时候可以去实习 41. 大四上学期有几门课 42. 什么时候开学 43. 预期的薪资是多少 44. 擅长什么编程语言 45. 有什么优缺点 46. 是不是很宅 ## Hr 面必問 1. 询问了除字节跳动以外,还在看其他工作机会么?分别是什么 * 目前都是看 backend 的 2.字节、XXX公司、XXX公司,你的优先级是什么,为什么? * 字節還是先的,因為領域比較有趣,而且字節快速成長,產品也更全面,尤其企業中台可以接到更多的產品有更全面的經驗,能參與一個創造性的服務從獨角獸新創成長到上市,在各國不斷的使用量不斷高速成長的機會是很難得的,因此可以的話我會優先選擇 bytedance 的。 3.之前薪资待遇是多少?你期望的薪资是多少? * (備而不用)其實我另外一家已經在做 reference check 的公司只比這個低一點,甚至在台灣的話省下房租那些我實際收入更高,但 bytedance 的用戶量級,領域,以及發展性的前景都更讓我感興趣,能的話我還是會先, * 嗯 N 這個數字是由新加坡政府提供的 engineer avg 的 salary,並且我認為我是一個很有熱忱,善於學習及分享的工程師,我認為我值得這個薪水,更甚至工程師很多,會不斷寫筆記跟同事同學甚至是面試官分享的人我覺得肯定不如平均數常見,至於台灣跟新加坡的物價水平本就不同,我想跳到新加坡就是希望能跨出新的一步,我希望過往的薪資不要再成為我們討論上的錨定點。(其實開低了) 4.平时有什么爱好? * 跟朋友打打球,聊聊程式,幫家人改改小說,挺單純的。 5.了解职位需求吗? * 資料處理跟可用性偏重,主要應該是 Notification Platform & Marketing Platform,Notification Platform 主要是負責信件跟簡訊相關通知,之前面試中也有跟面官討論過從我 ERS 做信件防護的角度來看,tiktok 的信件還有哪些方向可以改進可以增加郵件可見度,避免被分類到垃圾信,甚至分享了一個我寫的深入淺出信件協議的筆記給他。 * Marketing Platform 應該是資料處理為重,所以才會在 JD 提到 hadoop 跟 mapreduce 相關技術,不確定會不會像現職一樣需要兼職做一些 data mining 的工作。 6.有没有想问的? * 參考下面反問環節 1. 自我介紹(https://hackmd.io/@Rance/SJpJ9DJRw) * English: https://docs.google.com/document/d/12K2NjIlmoPVg3WJ0DB4FX08FS8fTjjpH/edit 2. 意向工作地点 * Singpore * 已經有在 MOM 模擬過 quality for EP 3. 职业规划 * Become an senior enginer * Have larger scale development experience * Make me can think solution in larger scale,了解億級解決方案的思路 * 專注在程式上,更快的提供更棒的 Solution,能夠自己快速提供一些很棒的 poc 之類的想法,知道更多的後端知識能跟大家分享。 4. 目前主要在干什么 * I just diliver a new feature * Now, I'm doing the enhencement that propose by me 5. 还投递了哪些公司 * 幾間不同的,電商,高頻交易的都有。 6. 对行业有什么倾向 * large scale * large scale 的需求才能突顯技術的價值。 * 有更多客戶使用的服務會更有成就感 * 接納 open source * bytedance 的 github 也開源了不少專案 7. 如何看待互联网行业的工作强度 * If we're keep delivering value, that worst. * 在前公司就為了導入 Go 帶頭加班過,很充實,學習到很多,公司也能準時上一個更容易維護的服務,雙贏。 8. 自制力高吗 * 有自制力才能克制住欲望,把假日或是下班的時間拿來繼續精進編程,達成自己想到的目標。 * 我也想下班後耍賴阿,假日打遊戲呀,但我會逼自己一定要把讀書會跟運動的習慣維持起來。 10. 優點 * 三個 * 熱愛分享及教學 * 教學相長,教學一直都是我用來驗收自身成果的最佳方式,尤其我認為,教學要能把知識用自己的語言彙整,用對對方最淺顯易懂的方式傳達。 * 以我在準備 bytedance 面試的過程來舉例好了,我還是相當看重 bytedance 這個機會的,所以面試前都有用下班時間及假日上網做一些 study,回憶一些平常工作比較用不到,但面試時可能會討論到的基礎知識細節,並且整理成筆記,換成用平常在上班時會遇到的情況來說明,直接分享給同事,多好,連下班準備面試別的公司都還能對團隊有貢獻,我覺得超棒的。 * 熱愛程式相關 * 如同我剛剛所提的,我常常寫筆記跟同事/同學/前同事做分享,我的教授說過,我在分享程式時它覺得我充滿喜悅,眼神像在發光一樣,我認為這是真的,因為我後來看到很多對程式有熱忱的人也是這樣的。 * 能有那麼多新的知識能跟別人分享也是因為我很喜歡了解更多跟程式相關的知識,對我來說了解這些原理或是新技術很有趣,所以我常常用休閒時間讀相關書籍或參加一些 tech conference,能以此為工作,學習,實踐,分享,對我來說是很有成就感的,我也認為這樣的特質。 * 處事客觀,就事論事 * 在討論任何事情時我都會盡量保持客觀,就事論事,即使對方是一個 Junior ,他提的方案也有可能比我更切入核心,即使對方是 manager,他也有可能對狀況有所誤解。 * 舉個例子,有一次我們需要做一個新的字符比對的功能,我首先提出了用一種叫字典樹資料結構可以有效處理,然而對面的一位剛畢業的 Junior 就問說為什麼我們不用暴力解掃過去就好?此時我沒有跟它爭論說喔我的解決方案有更高效更好之類的,而是就事論事去看那種是更好的「解決問題」的方法,而這個新的功能確實使用到的用戶不多,效能的影響現階段說不定差異不大。那說不定確實可以快速先交付一個暴力解的方式就好,後續再依需求來優化,確實我的提案從架構面來說更完整,但以解決問題來說對方提的暴力解說不定是現下更合適的「處理方式」,於是我轉頭去跟 manager 確認說目前的需求,進而改為贊同對方說 ok 那我們現階段確實可以先以暴力解為主,並且可以設一個門檻,等用量成長到某個階段再來考慮優化該部份的效能,我們可以按照需求迭代的交付最好的方案。 11. 缺點 * 分享一個我同事跟我回饋過的吧,有一位我帶的 Senior 吃飯閒聊時跟我反應過,他剛進來攻斯時覺得我討論事情時有點兇,是後來相處久了他才知道說我其實沒那個意思,喔?我就仔細的跟它了解說是哪些「因素」讓他覺得我兇他,那整理出兩點一是表情,二是用語,他說有時候他搞錯的時候我會這樣說「你怎麼會這樣想」,會讓它覺得好像我在質疑他很菜,這樣都不會。 * OK, 那我後來不管是開會或是再跟同事說話時我都會在意這點,就盡量不要露出可能給別人負面感覺的表情,然後溝通盡量採取正面表述來代替詢問,像是同樣的「你怎麼會這麼想」,可以改成「恩,可以跟我分享一下你的思路嗎?」再從中去找出有理解錯誤的地方。講話是一門藝術啦,注意講慢一點婉轉一點能讓團隊更和諧更有效率我覺得是值得努力的。 12. 為什麼會想要換工作 * 因為是 bytedance 呀 1. 現有的工作其實也不差,很穩定,百萬級流量。但 bytedance 更吸引我呀,億級的流量呀,參與一個高速成長新創的機會,產品也很有創造性,在接下來必定會繼續成長,並且基地在新加坡,更為國際化的團隊,又是企業中台這個相當核心,能基於我過往經驗在可用性及規模上有所挑戰的業務。 ### 反問 * Hr 怎麼跟 RD 一起討論 hiring 的看法的? * 在特雷維經驗跟 Trend 經驗的比較 * 特雷維 > trend * 住宿 * 機票 * 健保 * stock * 會有大小週需要加班的狀況嗎? * 接下來流程大概會怎麼走? --- For team lead * How this team management the permission of new commer * Should this chaos happen again and again? * Will this team treat document as an necessary thing? * Do you know who write most documnets in your team? ### 自我介绍 [參考這裡](https://hackmd.io/@Rance/SJpJ9DJRw) singanl bouns is RSU XX00 Tag 1.5 X0000 2 payment first month/ end of probation RSU X00 Base 135 SGD ### 核對 記得確認有成功錄音,要把聲音切到大耳機才能錄到 問保險的部分 * Health Insurance 問假日的部份 * Paid Time Off 問試用期的部份 * How long is the probation? 問簽證的部份 * How about the permit? * How company help me to get the permit? 問機票有沒有補助 * Will there any allowance on air ticket? 問如何 Onboard * How is your expected onboard day? 問 Remote work 跟 * Is bytedance work remotely now? * Will this effect my onboard? * 希望能再聽一次 Feedback,因為我很重視這部份希望能再跟之前的紀錄核對一下。 Hi, Jwen Again, thank you for your time and help I'm ready to accept the offer However, before I accept it, I would like to know more about the welfare and the onsite process of Bytedance I think detail positive feed algorithm good communication ok pro can be more comfrortable not deep dive to project good technical view good problem sovler from my end, clear in enegineer, don't need ## Linkedin message Hey PIN-QIAN! By way of introduction, I'm Jwen, from ByteDance's HR team. Hope you're keeping well and safe in this challenging climate. I chanced upon your profile and thought your skills and experiences would make you a great fit for our team. We are currently hiring a Software Engineer to join our Singapore office and be a part of this exponential growth in the region. I thought you could have a huge impact at ByteDance given your prior experiences, and we think you might be the one who can build the future together with us. I'd love to take you through everything in greater detail if you're open to hearing more. Just for your reference, I am including the JD here: https://job.bytedance.com/en/position/6906025462060648712/detail To join us and pave into the new era together, kindly reply to this message with your up-to-date resume and we can kick-start your application process. Otherwise, if you're happy at your current company and the timing is a little off, let me know and I'd love to keep you in mind for future roles. Thanks PIN-QIAN - Have a great day! I am also contactable at: - Email: jwen.ho@bytedance.com Cheers! Jing Wen (Jwen) Ho Tech Recruiter @ ByteDance / TikTok | ex-Facebook, ex-Shopee ## JD Software Engineer, Platform Services Singapore R&D - Backend Experienced Responsibilities The ByteDance Platform Teams provide Product Foundation Services with leading infrastructure and application solutions. Our product handles information at a massive scale and extends well beyond the business scene. We are building end-to-end solutions that highly impact the core metrics of ByteDance, including Identity & Access services, Notification Platform, Marketing Platform, etc. Our products are engineered for security, reliability and scalability, running the full stack from infrastructure to applications. Our teams are dedicated to helping our customers, small, large or huge applications, educational institutions and gaming platforms. Identity & Access provides leading Passport and User Identity products. We are also tasked with identifying and taking on the biggest problems that challenge the safety and integrity of our products. On this team, you're a big-picture thinker and strategic team-player with a passion for doing what’s right. Notification Platform delivers one of the world's leading infrastructure and technologies of messaging and notifications, including System Notification, SMS & Email service and In-App Notification. We are dedicated to helping our mobile applications grow their business, and also to build deep relationships between our customers. Marketing Platform shapes the voice of the product and helps it grow a consumer base. We identify actionable user insights and opportunities for user growth, and then drive the marketing strategy in ways that delight our users and promote adoption. Responsibilities 1. Build, design, implement, improve and maintain platform services (LBS, IM, ES, middlewares, etc) for ByteDance's products. 2. Build platforms, systems and infrastructure utilizing your strong background in distributed systems and large scale storage systems. 3. Work on core services for all ByteDance products, such as device, account, system notification, etc. 4. Manage individual projects priorities, deadlines and deliverables with your technical expertise. Qualifications 1. B.S. or M.S. degree in Computer Science, related technical discipline, or equivalent practical experience. 2. Software development experience in one or more general purpose programming languages. 3. Excellent proficiency in backend server development and expertise in relational database. 4. Experience in architecting and developing large scale distributed systems. 5. Experience in concurrency, multithreading and synchronization. 6. Understanding of technologies such as virtualization and global infrastructure, load balancing, networking, massive data storage, Hadoop, MapReduce and security. 7. Strong analytical thinking and exceptional attention to details. 8. Working proficiency and communication skills in verbal and written English. ### Asking for put off the onsite date I was planing the relocate schedule with my family yesterday. We found that there is an family gathering at 7th of Mar, Is that possible to put off the onsite date to 15th of Mar? If not, that's okay. intro thos role is development global market application -> post settlemenp & messaging new team still learning from US Most of people is still learning one of the big project establish swift transfer platform internal or external Java & MQ & mule soft Kick code