如何拿到各家大廠的前端校招offer

本文由 楊珏成 原創發佈於 SegmentFault,未經許可請勿轉載
原文連接: https://segmentfault.com/a/11...

0x00 做者是誰

我就讀於北京理工大學軟件工程專業,是一名大四學生。從大一開始投入之前端爲主的全棧開發,獨立開發過多箇中型和小型項目,是 佬鐵|宿舍市集 小程序的社區創始人及獨立項目負責人。php

在學校裏讀書的時候,我就是一個閒不住的人。最近由於一個偶然的契機,接觸到了校招季,最後定下了本科畢業就工做的規劃目標。css

因而我在一個月的時間裏參加了9家國內大廠校招,收穫了以下結果(截至2019年9月5日):html

  • 騰訊(WXG):等待二面
  • 阿里巴巴(淘寶FED):三面等結果
  • 字節跳動:收到offer
  • 美團點評(LBS):收到offer
  • B站(電商平臺):等待offer結果
  • 小米(金融平臺):等待offer結果
  • 網易(嚴選):hr面要去杭州現場,放棄
  • 攜程:放棄筆試
  • 滴滴:放棄筆試

0x01 爲何要寫這篇文章

從一開始手指冒汗被懟的說不出話,到最後和麪試官侃侃而談遊刃有餘,我發現:一樣的能力水平,在不一樣的面試表現下,反饋到面試官眼中的結果能夠有着天壤之別前端

所以,若是你但願把本身的真實水平展現給面試官,那麼掌握一些合適的方法是很是有必要的。vue

正文脈絡

正文的內容聚焦於應聘大廠校招所需具有的能力,以及分析各個大廠具體的校招策略。分爲兩個部分:node

  • 如何進入面試
  • 如何經過面試

但願能爲第一次走上職場的同窗們提供參考,也是對本身過去數週奔波忙碌的一個總結。python

0x02 大廠前端校招:如何進入面試?

2.1 經過簡歷初篩

想要拿到offer,第一步天然是經過大廠的校招初篩。在初篩,尤爲是大廠的初篩環節中,面試官面對的將是成千上萬份看起來沒什麼區別的簡歷文件。想要脫穎而出,你必須以對待工程項目的態度精心設計你的簡歷。mysql

2.1.1 簡歷佈局與層次

就像web開發的layout,寫簡歷時也應該考慮本身的簡歷layout。怎樣劃分簡歷內容板塊,我的信息是居中仍是居左,頭像應該和我的信息一塊居中仍是和我的信息對稱放置。react

這裏比較玄學,個人建議是參考身邊學長或者hr發的簡歷模板。jquery

2.1.2 簡歷內容的取捨和順序

這點是簡歷構建中最重要的,寫簡歷切忌一股腦把本身的驕傲倔強都寫上去,這樣只會讓面試官不知道這我的想要表達什麼。

建議先把本身的驕傲倔強所有整理成一個文本庫,再根據應聘的不一樣職位精心挑選出最對口的內容。

這裏推薦一個技術簡歷的最佳實踐:

改良程序員的問題簡歷,從反模式到最佳實踐

我在附錄3裏附上了本身的求職簡歷,供感興趣的同窗查看

2.1.3 玄學的亮點

亮點也是一個玄學,由於亮點是由面試官決定的,也許你的面試官恰巧和你同樣喜歡攝影 / 爬山 / ……,有可能他正好從你的一段項目經歷中看到了你的我的魅力,而另外一個面試官卻對此毫無感觸。

可是就像美國大片總能打動絕大部分觀衆的心裏,簡歷的亮點也是能夠設計的,這裏依然是建議多參考一些優秀的簡歷進行學習。

2.1.4 郵件格式的小細節

有的時候會發簡歷到HR或者內推人的郵箱,很容易忽視郵件的格式細節。

簡單歸納,一封簡歷郵件須要有明確的郵件標題以及表現本身誠意的正文,不要小看這一句話,看看滴滴在打車時的推薦問候語就知道一句問候的價值了。

千萬不要留空,印象分會減不少。

這裏推薦一個我本身的最佳實踐:

簡歷郵件

2.2 經過筆試

這點能夠說的不少也不多。可能是由於筆試題型太多了,一道道講不完。少是由於筆試不一樣於面試,筆試是全部人統一題目,所以目的和簡歷初篩是同樣的,都是爲面試官快速篩選提供幫助。

有的公司還會在筆試以後再開始初篩。甚至有些狀況下(好比內推)是能夠免除筆試的,所以這裏不作贅述。

筆試沒有什麼竅門,惟一的辦法就是刷題庫,推薦 Leetcode。要是能刷100道基本上面試題就不用愁,要是刷到200道就不用害怕校招筆試了。

我在附錄2中記錄了本身遇到的一些筆試題,僅供參考。

0x03 大廠前端校招:如何經過面試?

3.1 克服緊張

任何人在第一次面對面試官的時候都會緊張,即便我經歷這麼多場面試,依然會在有的時候感受控制不住本身的狀態。若是你能克服這種緊張,你就已經比多數面試者成功了一小半。記住,面試官永遠都喜歡你臨危不亂,面對難題依然可以掌握大局的樣子。在之後任何場合都是如此。

如何克服緊張,我這裏提供兩點建議

  1. 儘量多的參加你所能參加的一切 優質 面試,注意,是優質面試,好的面試能夠幫助你進一步鞏固本身的知識系統,最重要的是培養你的臨場反應能力。
  2. 儘量少的在心裏期待面試官對你的評價,把重心放在解決問題上,不要把本身的實力依賴於面試官的承認,更要學會自我評估。

3.2 完備的邏輯思惟

面試的時候,面試官老是喜歡出一些看起來很刁難的問題:實現一個Vue雙向綁定,寫一個公平的洗牌算法,寫一個css走馬燈樣式,獲取某個字符串的全排列,寫一個class的polyfill等等。

或者是深挖你的項目經歷一步步追問技術細節,讓你現場考慮如何實現更好的效果。

這種時候,你要意識到面試官是在考驗你的邏輯思惟,面試官的目的不是要你給出一個絕對完美的解決方案,而是想看到你如何運用一套好的邏輯思惟來調用本身的知識庫,最終給出你本身的思考路徑,最重要的是這個過程當中間的思考,必定要闡述給面試官

3.3 紮實的技術儲備與工程能力

重點來了!如下是整個面試中90%時間在乾的事情,也就是對你的技術儲備與工程能力的考覈。

通常來講,大廠的前端校招會比其餘中小企業更看重對面試者的全方位考覈,若是你是科班出身,校招的技術考覈會包括且不限於:

  • 計算機專業基礎(數據結構,算法,計算機網絡,操做系統,數據庫)
  • 職位相關基礎(JS/ES知識體系,瀏覽器渲染與緩存,先後端通訊,Web安全)
  • 工程實踐經驗(性能優化,依賴管理,依賴打包,模塊化,組件化,用戶鑑權,版本管理,包管理,服務器基礎)
  • 主流框架理解(Vue,React二選一)
  • 部分要求極高的大廠還會考覈你的理科基礎(線性代數,高等數學)

另外,不一樣的大廠也有不一樣的側重點。

技術實力最頂尖的阿里淘系FED會對你的基礎知識體系以及你簡歷上寫到的技能展開一場慘絕人寰的刨根問底,而字節跳動則更看重你的實際工程經驗以及對於軟件系統架構的理解。

經過每家大廠的面試策略,你也能夠側面觀察出這家企業的團隊技術實力和業務發展前景。

爲了更清晰的描述大廠校招知識體系,我將考覈中涉及到的全部面試題整理成了一張思惟導圖。建議一條一條仔細查閱,對於任何沒有百分百把握的知識點,我都建議你把它整理到一個列表裏,逐條梳理。

PS.標星的是非必須知識,能夠略過:

前端知識體系

3.4 職業規劃

若是你經過了以上全部考覈的話,恭喜你,你離得到offer基本只剩一步之遙了。

通常到這個時候,面試官會問你對本身的職業規劃,千萬不要小看這個問題。

這個問題其實也是須要本身問題本身的,最好在投遞簡歷的時候就想清楚:

  • 我爲何要去這家企業,我看中它哪方面的優點
  • 我爲何要應聘這個崗位,我對本身將來的發展方向有什麼樣的期許

仍是那句話 —— 不想當架構師的前端不是好程序員(霧)。

3.5 每次結束後必定要覆盤總結

這點就不用多說了,現場面試最好一齣場就開始回憶面試流程&寫備忘錄,若是是電話面試能夠錄音下來重聽一邊,捋一捋面試官的問題和本身的回答,看看本身答得如何(答成了什麼b樣),有沒有可能答得更好。沒有這點,你參加再多的面試也和沒有參加同樣。

我在附錄1中記錄了每次參加校招時的覆盤。

0x04 各家大廠的面試體驗

這裏原本想仔細量化評測一下各家大廠面試流程中的面試體驗,遺憾的是有些面試已通過去一段時間了,印象不是那麼清晰,我擔憂個人評價會有失偏頗。因此就簡單說一下在各家面試過程當中讓我印象深入的一些事情吧。

  • 字節會給參加面試的每一個人發一個包含抖音帽子在內的小禮包,還有一袋早餐,中午還有免費的自助午飯供應,很是貼心了
  • B站的老哥在問我爲何選擇B站的時候,補充了一句「除了二次元情懷以外」
  • 阿里淘系FED的每一輪面試都是突襲電話面試,分別在我睡覺、飛翔、吃飯的時候打了進來,每一輪平均時間90分鐘,並且會提早告訴你面試的目錄……(具體能夠看附錄1裏的 # 6.8 阿里校招二面
  • 我騎着摩拜單車去美團摩拜總部的大樓參加了摩拜單車小程序開發的面試
  • 在字節認識了一個很逗的學弟和一個很可愛的負責飛聊的小姐姐
  • 騰訊的內推仍是挺重要的,否則面試官可能看不到你
  • 上面這條對於多數大廠都適用
  • 上面這條不適用於字節
  • 很是但願騰訊和阿里的小哥哥看到這裏不會掛掉我

0x05 寫在最後:如何成爲一個優秀的前端工程師

最近看到一篇文章《前端深水區》感觸頗深,技術崗的最終出路必定是創建技術壁壘和影響業務決策。

在面試B站的時候,也遇到了一個讓我陷入了思考的問題,面試官當時問我:「我對你的職業規劃印象很好,你打算怎樣去實現它呢?我給你一分鐘的時間仔細思考這個問題。」

最後我回答了他三句話:

  • 保持進取
  • 保持客觀
  • 天天堅持探索最佳實踐

與你們共勉。

附錄1:大廠面試題整理

6.1 符號約定

符號 含義
現場回答正確
× 現場回答錯誤
? 現場沒法判斷是否答對
追問 對於父問題的追問
() 我在面試現場的回答思路
()右邊 最合適的回答(或對現場回答的補充)
補充 面試官親自對現場回答的補充
我向面試官提出的問題

PS. 並非全部試題都包含以上符號,由於都是現場回憶記錄,因此有不少不全的地方。

6.2 阿里實習一面

  1. 用js描述一棵樹 √
  2. 非遞歸遍歷樹 ×
  3. 詳述js new操做 √
  4. 方法調用模式this指向 ×

    • 追問:函數調用模式this指向 √
  5. 什麼是js閉包 √
  6. 如何跨域訪問 √
  7. vue的父子組件之間如何通訊 ×
  8. 用css寫無限循環動畫 ×
  9. 如何響應式佈局 √
  10. 如何清除float √
  11. 手寫jsonp √
  12. 爲何禁止跨域 ×
  13. osi七層 × 漏說了
  14. tcp三次握手 √ 四次揮手 ×
  15. setTimeout爲什麼能在單線程的js裏異步執行 ×
  16. 進程和線程的區別 ?
  17. 寫一個數字轉中文的程序 √
  18. js函數中如何綁定this到新對象上 √
  19. bind和call有什麼區別 ×
  20. 手寫快排 ×
  21. 講一下http狀態碼 √,其中303 304表明什麼 ×
  22. 死鎖的原理和四要素 √
  23. cookie和session的區別 √
  24. 同源的定義 √

6.3 Bilibili校招一面

  1. 詳述es5 es6中的做用域和閉包 √(es5全局+函數級,函數化閉包,es6塊級)
  2. 詳述輸入url到頁面渲染完成 √(域名解析-TCP分包-IP尋路-握手-滑動窗口傳輸-持久化鏈接-揮手-解析-構建dom樹與cssom-構建渲染樹-迴流-重繪-渲染)
  3. 詳述js異步機制Event Loop,MacroTask和MicroTask √(1個主線程+n個任務隊列,瀏覽器異步處理後推入隊列,循環處理,一個macroTask後跟所有microtask)
  4. Promise.all的用法 √(在全部all中的promise結束後再執行)
  5. 如何讓Promise.all在拋出異常後依然有效 ×(正確答案:主動reject)
  6. 什麼是VueX √(狀態量跨組件管理)

    • VueX中action和mutation的區別 ×(正確答案:同步和異步)
  7. 詳述Vue的雙向數據綁定原理 √(語法糖,dom監聽+模型監聽)
  8. Vue的優點 √(virtual dom,數據綁定,視圖與模型分離,隱去冗雜的dom操做)
  9. 如何實現SEO優化 ?(只答了服務器端僞靜態)
  10. 詳述迴流和重繪優化 √(迴流是對物理尺寸的變動,迴流必定會重繪,重繪不必定迴流,所以儘可能減小回流次數,將元素移出dom樹再變動)
  11. 詳述防抖和節流優化 √(狀態鎖/同步鎖)
  12. 簡述ES6新特性 √(塊級做用域,變量不提高,let, const,箭頭函數,模板字符串,promise,async)
  13. 簡述箭頭函數特性 ×
  14. webpack打包如何優化 ×

6.4 阿里校招一面

  1. 列舉幾個css中可繼承和不可繼承的元素 √
  2. 用css選中列表第二項 √
  3. 僞類和僞元素的區別 √
  4. h5字體如何自適應屏幕 √
  5. rpx是什麼 √

    • 追問:rem是什麼 ?
    • 追問:vw是什麼 √
    • 追問:vw和rem區別 ×(vw根據屏幕寬度,rem根據根元素肯定font-size換算比例)
  6. 什麼狀況下css會使用gpu加速 √
  7. css filter是什麼 ×(元素的可視效果例如:模糊與飽和度)
  8. 網頁如何去適配不一樣寬度 √
  9. 詳述meta標籤的做用 √
  10. position默認值和全部可能值 √
  11. 什麼是sass和less √
  12. css動畫最小間隔 √
  13. shadow dom是什麼 ×
  14. svg和canvas的概念和區別 √
  15. canvas圖層怎麼用 ×
  16. dom渲染的性能損耗在哪裏 √
  17. 如何高效地從1000個div中刪除10個div √
  18. 如何監聽img加載完成 √
  19. 瀏覽器裏除了js還能運行什麼 × (webAssembly和actionscript)
  20. promise有幾種狀態 × (fufilled, rejected,  pending)
  21. 如何捕獲promise錯誤 √
  22. promise能夠串聯嗎 ?答的不清晰
  23. 詳述vue都能解決什麼問題 √
  24. virtual dom如何進行diff操做 ×
  25. vue中data爲何是函數不是對象 √
  26. 爲何須要深拷貝 √
  27. 簡述指針是什麼 √
  28. node.js瞭解嗎 × 不瞭解
  29. 進程和線程的區別 √
  30. 你本身開發的平臺有多少用戶和訪問量 √
  31. 如何監控未處理的異常 ?(只說了監聽console error)
  32. 5G是什麼,爲何要用5G(開放題目)
  33. 想象一下5G的應用場景(開放題目)
  34. http和https的區別 √
  35. 爲何https不會被截獲 √
  36. 量子計算機可否破解非對稱加密 √(附加)
  37. 量子計算機的原理 √(附加)
  38. 瀏覽器如何緩存 ?(答的很差,設置http頭部)
  39. 詳述http 1.0, 1.1, 2.0的區別 √
  40. 詳述TCP如何保證傳輸完整性 √
  41. UDP和TCP有什麼區別 √
  42. 爲何使用UDP × 答的很差
  43. WebSocket是基於什麼協議鏈接 √
  44. 冒泡算法和快排時間複雜度 √
  45. 分佈式系統用什麼算法排序 ?半對
  46. 廣搜和深搜的應用 √
  47. 廣搜的數據結構 √
  48. 鏈式求導是什麼 ×
  49. 矩陣的秩是什麼 ?半對
  50. 梯度和導數,偏導 √
  51. 信息熵 √
  52. 編譯原理 ?半對
  53. sql如何獲取當前時間 √
  54. char和varchar區別 √
  55. drop, delete, truncate ?(半對,truncate能夠持久化)
  56. python用過嗎 ?作過爬蟲

6.5 小米實習電話面試

  1. 做爲全棧爲何報前端 √
  2. js用的哪一個版本 √
  3. es6新特性 √
  4. promise有幾種狀態 √
  5. promise如何知足多個異步進程的同步順序 √
  6. promise.race和promise.all的區別 ×
  7. 怎麼設計頁面佈局(開放題目)
  8. 如何用flex讓8個圖標排成兩行 ×(flex-wrap)
  9. 垂直居中和水平居中 ×(說反了)
  10. 你的頁面是用一套界面響應不一樣寬度嗎 √
  11. 本身如何調先後端api √
  12. vue中的fetch和axios是什麼×
  13. 跨域問題怎麼解決 √
  14. 跨域怎麼作post ×(用iframe)
  15. 詳述git操做 √
  16. vue.js 加載完成前隱藏花括號 ×(v-clock)
  17. 開發主要用react,有興趣轉技術棧嗎(有)
  18. 能夠實習多久

6.6 Bilibili校招二面

  1. 純js如何獲取scrolltop值 √
  2. 詳述js閉包原理和意義 √
  3. 深拷貝 淺拷貝是什麼 √
  4. arguments如何轉數組 √
  5. 移動端和pc端click事件爲何差了300毫秒 ×(由於iphone能夠雙擊縮放)
  6. flex佈局用法 √
  7. 如何實現移動端響應式佈局 √
  8. ES6的做用域 √
  9. async await是什麼 √
  10. 塊級做用域有哪些 √
  11. 詳述promise異步機制 √
  12. 如何實現跨域訪問 √
  13. http通訊如何設置緩存 √
  14. 詳述http狀態碼 √
  15. 如何實現vue組件通訊 √
  16. 簡述VueX的做用 √
  17. 如何實現一個swiper √
  18. hybrid是什麼 √
  19. hybrid js如何調用native接口 ×
  20. 爲何要作前端
  21. 對於本身的發展規劃
  22. 上海怎麼樣

6.7 網易校招一面

  1. 塊狀元素 行內元素 √
  2. 標籤語義化是什麼 √
  3. css清除浮動 √
  4. 什麼是盒模型 √
  5. css優先級 √
  6. position屬性 √
  7. 移動端適配?(媒體查詢,flex,rem)還有viewport
  8. px em rem √
  9. ==和===的區別 √
  10. 原型和原型鏈是什麼 √
  11. 什麼是深拷貝 √
  12. 什麼是同步 什麼是異步 √
  13. 如何順序執行10個異步任務 ?(答的不全)
  14. es6 proxy是什麼 ?(不瞭解,說了下代理模式的概念)
  15. 題目:遍歷一個任意長度的list中的元素並依次建立異步任務,如何獲取全部任務的執行結果 ?(用promise.all,感受面試官不是很滿意,應該是用proxy代理)
  16. 對一個對象數組排序 ?(增長原型方法)
  17. 亂序一維數組排序
  18. 數組去重 ?(map.set,鍵值對象)
  19. 如何進行git的分支管理 ?(答的不全)
  20. 瀏覽器有哪些緩存 √
  21. 什麼是跨域 √
  22. 如何解決跨域 √(jsonp,代理,白名單)
  23. 不考慮還有別的辦法 √

    • 補充 本地存儲,window.name,form.message
  24. 頁面性能的優化 √(重繪,迴流,防抖,節流
  25. 還有嗎 √(懶加載,預加載)還有base64,壓縮,骨架屏
  26. 瀏覽器安全處理 √(xss,數據庫注入)還有csrf,文件上傳漏洞
  27. 有沒有真機瀏覽器debug經驗(開放題)

6.8 阿里校招二面

  1. 一分鐘介紹一下你的項目經歷 √
  2. 是否瞭解淘系FED這個部門 √

一.基礎部分

  1. html

    1. 如何在移動端處理兼容性 ?(css前綴)

      • 追問 工程中遇到過相似的問題(svg)
      • 追問 還有補充嗎(沒了…)還有meta viewport http-equiv
    2. vw em rem的區別和使用場景 √
    3. 不一樣定位模式之間的區別 √
    4. fix的顯示問題?(寬度塌陷)沒答全,還有z-index覆蓋
    5. canvas如何使用圖層 √

      • 追問 如何避免圖層覆蓋 ?(答的封裝)
  2. css

    1. 全部絕對居中的實現 ?( flex, text, padding: auto)沒答全,還有translate
    2. sass和less有什麼區別 √
    3. 實現響應式佈局的方法 √ (flex 媒體查詢 rem)

      • 追問 還有嗎 √ (grid)
    4. 瞭解過BFC嗎 ×(不瞭解)
  3. js

    1. 用三句話歸納全部值傳遞類型,全部引用傳遞類型,以及如何用引用的方式傳遞值類型 ?
    2. js全部基礎類型 ?(布爾值,數字,字符串)還有null和undefined,symbol

      • 追問 null和undefined的區別 √(未定義和賦空值)
      • 追問 怎麼比較 ×
    3. 指針和引用的區別 √(地址和別名)
    4. js當中對於不一樣環境的變量何時釋放 √(標記清除和引用計數)

      • 追問 在非閉包的狀況下變量何時會被回收?(不肯定)
    5. js的做用域你怎麼理解 √
    6. js裏的多重繼承怎麼實現 √(call,es6 extend)

      • 追問 還有嗎?(不知道)

2、工程部分

  1. React 和 Vue 生命週期有什麼區別?(答了vue,react不瞭解)
  2. Vue如何監聽數據的變化 √ (defineProperty,訂閱者模式)
  3. Vue裏如何實現父子組件之間的通訊 √
  4. 瞭解太高階組件嗎(不瞭解)
  5. 看過Vue的源碼嗎(目前主要在理解原理階段)
  6. 有沒有使用工具構建過工程項目(vue cli+webpack)
  7. webpack編譯和構建原理(分析依賴,chunk)沒有說loader
  8. 平時使用什麼工具轉換es6(babel)
  9. babel轉碼流程(配置.babelrc,解析語法數,改變塊級變量名等等)

3、算法部分

  1. js哈希存儲結構的構成方式 √(哈希值,哈希表,哈希衝突)
  2. js當中如何實現某一個數的階乘 ?(只答了for循環)
  3. 設計一個算法找到亂序數組中相加等於指定值的全部數對 √(快排+兩端查詢 / 兩層for)

6.9 阿里校招三面

  1. 介紹一下你的項目(中大型小程序系統,企業控制檯,Vue CLI單頁面web應用等)
  2. 你的小程序是怎樣一個軟件(校內交易社區)

    • 追問 爲何不經過閒魚去賣呢(解決樓內交易)
  3. 你的小程序用openid去登錄,能夠講一下OAuth流程嗎(可信平臺對前端發放token,後端處理敏感信息)

    • 追問 OAuth有什麼優點(避免前端直接接觸敏感信息)
  4. 你的小程序Websocket通訊系統是作什麼的(各類類型消息的實時通訊)

    • 追問 你的實時語音通訊是怎麼作的(接口鑑權->手勢狀態機->本地持久化->上傳服務器->緩存管理)
    • 追問 微信的錄音返回數據是傳回base64嗎(不是 是返回tmp協議路徑)
    • 追問 你的錄音本地持久化的目的是什麼(減輕服務器負載,減小冗餘的資源重傳)
    • 追問 你的本地持久化是怎麼作的(用local storage)
    • 追問 你的一條語音大概有多大(幾十k到幾百k)
    • 追問 小程序的localstorage有多大(10-20M)
    • 追問 你的websocket爲何要作心跳(避免網絡環境變化帶來的通訊中斷)
    • 追問 你的心跳機制是怎麼作的(計時器控制 超時重連 網絡狀態監聽)
  5. 你是本身買的服務器嗎(阿里雲)
  6. 你的CDN服務是怎麼作的(阿里雲)
  7. 你的SSL是怎麼作的(配置ssl證書鏈,非對稱加密)
  8. 你的搜索爲何用Elastic Search(中文分詞,倒排索引,高效)

    • 追問 你的中文分詞搜索是怎麼作的(IK分詞器)
  9. 你的數據庫用的是什麼引擎(INNODB)

    • 追問 爲何用INNODB引擎(外鍵,索引類型,utf8mb4)
    • 追問 INNODB的鎖是什麼粒度級別(答的表級,不太肯定)
    • 追問 對於事務的原子性有了解嗎(不瞭解)
  10. 你的單頁面web應用是怎麼作的(Vue CLI+Webpack自動構建,Vue Router路由)
  11. 你的用戶密碼是怎麼存在數據庫裏的(PASSWORD函數)

    • 追問 用戶密碼在前端傳輸的時候有作加密嗎(有了ssl不須要)
  12. 你有沒有作登錄態持久化,怎麼作的(設置cookie過時時間)

    • 追問 你的服務器端怎麼管理session登錄態(php自動分發)
    • 追問 怎麼在多臺服務器同步session數據(數據庫或者分佈式系統)
    • 追問 分佈式怎麼作(hbase或者es)
    • 追問 存儲完之後怎麼用php獲取呢(不知道)
  13. 在中航通用實習的主要成果(獨立開發web系統,數據控制檯,後端服務器)

    • 追問 你的控制檯管理什麼數據(產品,新聞,職位,簡歷)
    • 追問 你的WYSIWYG編輯器是本身作的嗎(基於summernote二次開發)
    • 追問 你的異步交互和事物存儲是什麼(AJAX+PDO)
  14. 你對於本身將來發展的規劃是什麼樣(讀框架源碼-寫本身的框架-掌握先後端深層知識-掌握整個軟件架構)
  15. XSS,CSRF,數據庫注入怎麼防範(控制前端渲染,控制後端處理,預編譯)
  16. 解釋一下深拷貝和淺拷貝(引用傳遞和值傳遞blablabla)
  17. 平時本身是怎麼關注前端領域的知識的(工具書,技術博客,官方文檔,交流羣)

6.10 美團校招一面

  1. 介紹一下你的項目經歷
  2. 影響頁面加載性能的主要因素 √
  3. 你是怎麼統計頁面數據的 √

    • 補充 其實這些數據能夠用小程序控制臺查看
  4. 你的微信OAuth登錄怎麼作的 √
  5. 你的微信模板消息怎麼作的 √
  6. 小程序的分包原理是什麼×(用戶點擊時加載對應包)
  7. 如何自動構建前端項目並自動部署?(webpack+第三方插件自動化)
  8. 視差屏原理 √

    • 追問 用absolute和translate作視差哪一個好 √
    • 追問 你的vue項目裏爲何用了jquery,用在哪 √
  9. 數組有哪些方法 √
  10. 函數bind方法會接收什麼,返回什麼 √
  11. 哪些靜態資源會阻塞頁面渲染,怎麼解決,有什區別 √
  12. 如何跨域訪問 √
  13. JSONP原理 √
  14. 事件代理原理 √
  15. 你如今的實習主要作什麼
  16. 能接受加班嗎 以及能接受的加班時間
  17. 爲何選擇美團

6.11 字節跳動校招一面

  1. 你的項目經歷
  2. js有哪些基礎類型√
  3. 閉包是什麼√
  4. 如何循環間隔1秒輸出數組元素√
  5. 如何實現事件監聽√ (callback,addEventListener)

    • 追問 二者有什麼區別√ (後者會被覆蓋)
  6. Vue生命週期√
  7. BFC瞭解嗎× 塊級格式化上下文
  8. 畫一個盒模型√

    • 追問 box-sizing√
  9. 實現一個三欄佈局√
  10. websocket原理√
  11. 登錄的cookie怎麼存的√
  12. www.toutiao.com轉爲com.toutiao.www

6.12 字節跳動校招二面

  1. 介紹一下你的項目經歷
  2. 你的php包管理用什麼√ composer
  3. composer的autoloader怎麼實現的?
  4. php fast-cgi是什麼?併發管理
  5. php set_cookie是否會改變$_COOKIE數組√不會
  6. 你的MYSQL Procedure是幹什麼的√函數交互
  7. 跨域請求怎麼設置header字段√
  8. Vue Router原理√
  9. VueX具體應用在哪些場景內√
  10. 用過哪些Ajax組件√ Axios
  11. Axios怎麼實現攔截√
  12. js二維數組反向合併√
輸入:[1, 2, [3, 4], 5, 6, [7, 8], 9] 
輸出: [[3, 4, 1, 2, 5, 6][7, 8 ,9]]
  1. js駝峯轉換√
輸入:contentType
輸出:content_type

6.13 字節跳動校招三面

  1. 介紹一下你的項目經歷
  2. 給我看看你上線的小程序√

    • 追問 這裏瀑布流不平衡怎麼回事√(用10px顯示偏差換取預加載帶來的性能提高)
    • 追問 服務器用的什麼√(阿里雲騰訊雲都用)
    • 追問 服務器運維瞭解嗎√
    • 追問 服務器宕機之後怎麼解鎖mysql×(工程中沒有遇到,不肯定)
    • 追問 cpu使用率異常升高怎麼解決√
  3. 描述一下你的小程序開發流程√
  4. 你的websocket是幹什麼的√

    • 追問 你的websocket是怎麼通訊的√
  5. 離線怎麼獲取消息√
  6. Vue Router原理√
  7. 你的發展規劃(前端工程-前端架構-系統架構)
  8. 你的意向部門(C端)
  • 問 有可能去哪一個部門(不肯定,雙向選擇)

6.14 網易校招二面

坑點:沒有準備耳機,視頻面試官聲音比較小,一開場亂了節奏
  1. 性能上面作過優化效果最好的×××(懶加載,預加載)

    • 追問 在什麼狀況下判斷預加載(點擊時利用150ms延遲進行預加載)
    • 追問 還有其餘狀況會用預加載嗎(沒有用過)

這兩個是你認爲最明顯的嗎×××(嚴重失誤,忘記說重繪和迴流以及防抖和節流,瀏覽器緩存,代碼壓縮,異步加載等等)

  1. 其餘方面好比構建 組件化的拆分作過嗎 ()

6.15 Bilibili校招三面

6.16 騰訊校招一面

6.17 小米校招一面

6.18 小米校招二面

附錄2:大廠筆試題整理

7.1 騰訊校招筆試

1. 字符串解碼

小明和小紅用字符串壓縮通訊。
字符串壓縮規則是:若是有連續重複的字符串好比ABCABCABC就縮寫成[3|ABC]。
現有壓縮後的字符串,設計一個解壓程序還原字符串。

樣例:
輸入:
HG[3|B[2|CA]]F
輸出:
HGBCACABCACABCACAF
坑點:

須要優化內存,我之因此87.5就是由於內存溢出MLE了,正在考慮用棧結構重寫一次。

思路(87.5/100分):
string decode(string s) {
    string res = "", ans = "";
    int len, start , end;
    int time, counting;
    time = 0, counting = 1;
    len = s.size();
    for (int i = 0; i < len; i++)
    {
        if (s[i] == '[')
        {
            start = i;
            for (i = len; s[i] != ']'; i--);
            end = i;
            res += decode(s.substr(start + 1, end - start - 1));
            i++;
        }
        if (counting && s[i] >= '0' && s[i] <= '9')
        {
            time = time * 10 + (s[i] - '0');
        }
        else if (s[i] == '|')
        {
            counting = 0;
        }
        else
        {
            res += s[i];
        }
    }
    char tmp = res[res.size() - 1];
    if (tmp == '\0')
    {
        res = res.substr(0, res.size() - 1);
    }
    if (time > 0)
    {
        for (int i = 0; i < time; i++)
        {
            ans.append(res);
        }
    }
    else
    {
        ans = res;
    }
    return ans;
}

int main()
{
    string s;
    cin >> s;
    cout << decode(s) << endl;
    return 0;
}

2.識別IP

判斷一個ip地址是否是私有的
已知私有IP範圍是:

10.0.0.0 - 10.255.255.255
172.16.0.0-172.16.255.255
192.168.0.0-192.168.255.255
127.0.0.0/8 # 注意!這裏是一個巨坑,0/8的意思表明子網掩碼255.255.255.0,也就是最後8位能夠有動態範圍,這是一種簡寫方法,可是騰訊並無說明其含義,可能也是一處考察。

樣例:

輸入:
0.0.0.0
輸出:
false
思路(100/100分):
function isPrivate(ip){
    // TODO
    let ipVal = ip.split('.');
    ipVal[0] = Number(ipVal[0]);
    ipVal[1] = Number(ipVal[1]);
    ipVal[2] = Number(ipVal[2]);
    ipVal[3] = Number(ipVal[3]);
    if (ipVal[0] == 10) {
        if (ipVal[1] >= 0 && ipVal[1] <= 255) {
            if (ipVal[2] >= 0 && ipVal[2] <= 255) {
                if (ipVal[3] >= 0 && ipVal[3] <= 255) {
                    return true;
                }
            }
        }
    }
    if (ipVal[0] == 172) {
        if (ipVal[1] >= 16 && ipVal[1] <= 31) {
            if (ipVal[2] >= 0 && ipVal[2] <= 255) {
                if (ipVal[3] >= 0 && ipVal[3] <= 255) {
                    return true;
                }
            }
        }
    }
    if (ipVal[0] == 192) {
        if (ipVal[1] == 168) {
            if (ipVal[2] >= 0 && ipVal[2] <= 255) {
                if (ipVal[3] >= 0 && ipVal[3] <= 255) {
                    return true;
                }
            }
        }
    }
    if (ipVal[0] == 127) {
        if (ipVal[1] == 0) {
            if (ipVal[2] == 0) {
                if (ipVal[3] >= 0 && ipVal[3] <= 8) {
                    return true;
                }
            }
        }
    }
    return false;
}

3. 駝峯轉換

把一個由 - 或 _ 或 @ 鏈接的變量詞組轉換成駝峯寫法

樣例:
輸入:
content-type
輸出:
contentType
思路(100/100分):
function camel(str) {
    // TODO
    let ans = "";
    let upper = false;
    for (let index = 0; index < str.length; index++) {
        const element = str[index];
        if (element == '_' || element == '-' || element == '@') {
            upper = true;
        } else {
            if (upper) {
                ans += element.toUpperCase();
            } else {
                ans += element;
            }
            upper = false;
        }
    }
    return ans;
};

4.星球開會

企鵝星球上一天有N(<200000)個小時(時間不包含0點),對應N個時區,當第1時區一點的時候第2時區已經兩點了,以此類推
每一個時區有Ai我的,每一個時區上的人只有在[u,v)時間內有空,如今想要讓儘量多的人開會,給出開會時第一時區的時刻

樣例:
輸入:
3
2 5 6
1 3
輸出:
3
坑點:

時區的對應有一點繞,我一開始理解成後一個時區比前一個時區落後,其實是超前的,每後一個時區比前一個時區快1個小時,解決掉這個問題就沒有大問題了。
另外要考慮一下時間複雜度的問題,個人優化比較差,最壞複雜度是O(n2/2)

思路(80/100分):
int main() {
    int n, u, v, len, pos;
    long long ans, tmp;
    cin >> n;
    vector<int> a(n, 0);
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    cin >> u >> v;
    u--;
    v--;
    len = v - u;
    pos = 0;
    if (len < n / 2)
    {
        ans = 0;
        for (int i = 0; i < n; i++)
        {
            tmp = 0;
            for (int j = 0; j < len; j++)
            {
                tmp += a[(i + j) % n];
            }
            if (tmp > ans || (tmp == ans && ((n + u - pos) % n < (n + u - pos) % n)))
            {
                ans = tmp;
                pos = i;
            }
        }
    }
    else
    {
        ans = INF;
        for (int i = 0; i < n; i++)
        {
            tmp = 0;
            for (int j = 0; j < n - len; j++)
            {
                tmp += a[(i + j) % n];
            }
            if (tmp < ans || (tmp == ans && ((n + u - pos) % n < (n + u - pos) % n)))
            {
                ans = tmp;
                pos = i;
            }
        }
    }
    cout << (n + u - pos) % n + 1 << endl;
    return 0;
}

7.2 網易校招筆試

1.超大數和一個長整型的最大公約數。

第一題的思路比較簡單,就是展轉相除法,用字符串存儲大數,而後分段展轉相除

展轉相除法:

假若有兩個正整數p1,p2,其中p1>p2,那麼必然存在兩個天然數k,b,使得p1=k*p2。
若是p1,p2的最大公約數是p3,那麼p2,b的最大公約數也是p3。
例如gcb(55,30)=gcb(25,30)=gcb(25,5)

2.一個數組中長度從1到n的子序列中最大值的最小值。

題目:在一個最大長度200000的數組中,分別求出長度從1到n的子序列中最大值的最小值
樣例:
輸入:
6
1 8 7 5 4 2
輸出:
1 4 5 7 8 8

簡單來講,就是把一個數組進行連續子序列的劃分,從長度爲1的子序列開始劃分,每次劃分子序列後,求出每一個子序列的最大值,再求出全部這些最大值中最小的那個,一直到長度爲n的子序列(序列自己)。

這題一開始把我看繞了,其實就是一道標準的DP題,然而我最後作的這題,考完才寫出來。。。此次筆試基本是按照最差的答題順序來的,估計跪了。

狀態轉移方程能夠這樣想出來:

dp[j][i]是從數組第j個數字開始的長度爲i的子序列的最大值,當長度i=0(實際長度應該爲1,從0開始方便些)時,dp[j][0]等於數字自己num[j],從i=1開始,dpj的長度等於MAX(dp[j][i-1], dp[j+1][i-1])也就是先後相鄰的兩個長度爲i-1的子序列最大值中的最大值。

這題要求的是同一劃分長度下全部最大值的最小值,因此在計算dp數組的同時還要計算這個值是否爲當前劃分長度的最小值,因而定義一個min數組,長度100000,先初始化成最大數值,每次計算dp[j][i]的時候與min[i]比較哪一個值更小,一趟下來就能獲得最小值了。

思路:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <algorithm>
#define MAX(x,y) ((x) > (y) ? (x) : (y))
#define INF 0x7FFFFFFF
using namespace std;
int num[100000] = { 0 };
int (*dp)[100000];
int main()
{
    int n;
    int min[100000] = { 0 };
    scanf("%d", &n);
    dp = (int (*)[100000])malloc(n * 100000 * sizeof(int));
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &num[i]);
        min[i] = INF;
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++)
        {
            if (i == 0)
            {
                dp[j][0] = num[j];
            }
            else
            {
                dp[j][i] = MAX(dp[j][i - 1], dp[j + 1][i - 1]);
            }
            if (dp[j][i] < min[i])
            {
                min[i] = dp[j][i];
            }
            i = i;
        }
    }
    for (int i = 0; i < n; i++)
    {
        if (i>0)
        {
            printf(" ");
        }
        printf("%d", min[i]);
    }
    printf("\n");
    return 0;
}

3.奇偶互換

一個數組中,奇偶數可互換,求任意次互換後字典序最小的數組序列。

我的思路:沒有特別好的想法

4.數組減一

給定一個長度M(<=100000)的數組,而後輸入N(<=100000)個整數,每次將數組中全部大於等於該整數的元素減一,並輸出改變了多少個元素,要求時間性能小於1s。

我的思路:

用二分查找結果70%結果都TLE了,通過分析認爲主要是遍歷數組進行減一的操做太費時間(O(n^2)的複雜度)後來考慮用一個數組儲存更新過的下標分界位置來繞過遍歷減一的環節,然而沒寫完。

7.3 大疆校招筆試

1. 玩遊戲

給定暑假時間X天(<=1000),遊戲數量N個(<=11),接下來N行給定每種遊戲須要花費的天數(Ai),以及通關該遊戲帶來的成就點數(Bi),求:在暑假X天裏可以達成的最高成就點數。

我的思路:
#include <iostream>
#include <vector>
#include <cassert>
#include <algorithm>
using namespace std;
 
// 須要填充一個容量爲X的揹包,使得成就點數最大
class Knapsack01 {
 
private:
    vector<vector<int>> memo;
 
    // 用 [0...index]的物品,填充容積爲c的揹包的最大價值
    int bestValue(const vector<int> &w, const vector<int> &v, int index, int c) {
 
        if (c <= 0 || index < 0)
            return 0;
 
        if (memo[index][c] != -1)
            return memo[index][c];
 
        int res = bestValue(w, v, index - 1, c);
        if (c >= w[index])
            res = max(res, v[index] + bestValue(w, v, index - 1, c - w[index]));
        memo[index][c] = res;
        return res;
    }
 
public:
    int knapsack01(const vector<int> &w, const vector<int> &v, int C) {
        assert(w.size() == v.size() && C >= 0);
        int n = w.size();
        if (n == 0 || C == 0)
            return 0;
 
        memo.clear();
        for (int i = 0; i < n; i++)
            memo.push_back(vector<int>(C + 1, -1));
        return bestValue(w, v, n - 1, C);
    }
};
 
int main() {
 
    // X爲暑假天數,N爲遊戲數量
    int X, N;
    cin >> X >> N;
 
    int w, v;
    // vs存的是價值(成就點數)
    // ws存的是每一件物品的重量(天數)
    vector<int> vs, ws;
    for (int i = 0; i < N; i++) {
        cin >> w >> v;
        vs.push_back(v);
        ws.push_back(w);
    }
 
    cout << Knapsack01().knapsack01(ws, vs, X) << endl;
 
    return 0;
}

PS.這題我特麼寫成徹底揹包了,實際上是01揹包,結果只對50%。

2.輸入指令:

輸入指令集長度M和指令操做長度N 接下來輸入M個指令(字符串)=》指令值(字符串)的映射關係 而後隨機輸入N個指令,要求輸出對應指令值。

我的思路:

最簡單的用c++ map容器,然而忘記map寫法,耽誤大量時間,超級遺憾。

#include <iostream>
#include <string>
#include <map>
using namespace std;

int main()
{
    map<string, string> ops;
    int x, y;
    cin >> x >> y;
    for (int i = 0; i < x; i++)
    {
        string a, b;
        cin >> a >> b;
        ops[a] = b;
    }
    for (int i = 0; i < y; i++)
    {
        string op;
        cin >> op;
        cout << ops[op] << endl;
    }
}

3. 買水果

給定N塊錢,M種水果,每種水果價格Pi,其中有X種特別喜歡的水果,給定不一樣水果喜歡程度的排序,並要求排序靠前的水果購買量不得小於靠後的,求全部把錢花光的可能性,結果對10000007取模。

我的思路:

跪了...

7.4 字節跳動校招筆試

1. 上學鬧鐘O(nlogn)

小明定了n個鬧鐘,他只能在鬧鐘響起時出發去學校,每一個鬧鐘時間分別爲hi點mi分,小明家到學校要x分鐘,學校上課時間a點b分 (0-24小時,0-59分鐘),求他最晚幾點起

輸入:
3 //定了幾個鬧鐘
5 0 //第1個鬧鐘的小時數和分鐘數
6 0 //第2個鬧鐘的小時數和分鐘數
7 0 //第3個鬧鐘的小時數和分鐘數
59 //到學校要多少分鐘
6 59 //上課的小時數和分鐘數
輸出:
6 0 //最晚的起牀時間
思路(80/100分):

純智障思路,自定義結構體存儲鬧鐘時間,所有輸入後對鬧鐘時間從晚到早排序,接下來從前日後遍歷鬧鐘時間,計算從當前時刻出發到學校的時間,輸出第一個可以到達學校的,因爲算法很粗劣,很明顯被卡邊界了,沒時間管了直接看下一題。

代碼:
struct Time
{
    int h;
    int m;
    friend bool operator < (Time a, TIme b){
        if(a.h == b.h){
            return a.m > b.m;
        }
        return a.h > b.h;
    }
}
int main()
{
    int n, x, a, b, rest;
    cin >> n;
    Time* time = (Time*)malloc(n * sizeof(Time));
    for (int i = 0; i < n; i++)
    {
        cin >> time[i].h >> time[i].m;
    }
    sort(time, time + n);
    cin >> x;
    cin >> a >> b;
    for (int i = 0; i < n; i++)
    {
        rest = 0;
        if (time[i].h < a || time[i].h == a && time[i].m < b)
        {
            rest = (a - time[i].h) * 60 + b - time[i].m;
            if (rest >= x)
            {
                cout << time[i].h << ' ' << time[i].m << endl;
                break;
            }
        }
    }
    return 0;
}

2. 加密通訊 O(n)

小明和小紅採用密碼加密通訊,每次通訊有固定的明文長度n和加密次數k。
好比:密碼二進制明文是1001010,加密次數是4,則每次將密文右移1位與明文作異或操做,總共位移3次(k=4, 因此k - 1 = 3)

輸入:
7 4 // n k
1110100110 //密文
輸出:
1001010 //明文

解釋:
1001010---
-1001010--
--1001010-
---1001010

加密次數爲4,故對於明文右移4-1=3輪,每輪與當前密文進行一次異或,故1001010對應密文爲1110100110

思路(100/100分):

一道標準的異或數學題,不知道該怎麼歸類,有一點考數學的感受,看幾眼就能看出規律了直接上代碼

簡單講一下思路:

首先密文和明文第1位是同樣的,看一下上方樣例裏的解釋就懂了。
而後考慮第2到k-1位,能夠發現這一段的每一位都是由前一位密文的異或結果再與當前位明文異或獲得的。

接下來考慮第k到n-1位,觀察規律能夠發現這一段的每一位都是由前一位密文與第i-k位明文異或獲得的結果再與當前位明文異或獲得的。
如何消除異或影響你們應該都能理解,所以只要把參與異或的部分再與密文異或一下便可獲得明文。

int main() {
    int n, k, tmp;
    string s,ans="";
    cin >> n >> k;
    cin >> s;
    ans += s[0];
    for (int i = 1; i < k; i++)
    {
        tmp = (int)(s[i] - '0') ^ (int)(s[i - 1] - '0');
        ans += tmp + '0';
    }
    for (int i = k; i < n; i++)
    {
        ans += (int)(s[i] - '0') ^ (int)(s[i - 1] - '0') ^ (int)(ans[i - k] - '0') + '0';
    }
    cout << ans;
    return 0;
}

3.發工資O(n)

王大錘要給員工發工資,員工從左到右坐成一排,每一個員工知道彼此的資歷,每一個員工只知道本身左右員工的工資,若是某員工比左邊或右邊的人資歷老,那他必定比這我的工資高100元,每一個人最低工資100元,求王大錘最低給多少工資。

樣例
輸入:
4 //幾個員工
3 9 2 7 //員工順序以及對應的資歷
輸出:
600 //100元,200元,100元,200元

6
1 2 3 4 5 6
2100 //100,200,300,400,500,600

5
1 1 1 1 1
500 //100,100,100,100,100

8
1 2 3 4 3 2 3 4
1800 //100 200 300 400 200 100 200 300
8
3 4 3 4 3 4 3 4
1200 //100 200 100 200 100 200 100 200
5
1 2 3 4 1 
1100 //100 200 300 400 500
思路(100/100分):

廣度優先搜索,能夠把員工序列看做一棵多根樹,每一個工資最低的員工就是根節點,一個員工的工資其實就是他在多根樹裏的深度,

首先在輸入的時候找到比左右資歷都年輕的員工入隊,每次從隊列pop一個員工,而後判斷該員工的最小工資,而後判斷左右員工是否能夠入隊,直到全部員工出隊

int main() {
    int n, now;
    long long ans = 0;
    cin >> n;
    if (n == 0)
    {
        cout << 0 << endl;
        return 0;
    }
    vector<int> epy(n, 0), depth(n, 0);
    queue<int> sal;
    for (int i = 0; i < n; i++)
    {
        cin >> epy[i];
        if (i > 1 && epy[i - 1] <= epy[i - 2] && epy[i - 1] <= epy[i])
        {
            depth[i - 1] = 1;
            sal.push(i - 1);
        }
    }
    if (epy[0] <= epy[1])
    {
        depth[0] = 1;
        sal.push(0);
    }
    if (epy[n - 1] <= epy[n - 2])
    {
        depth[n - 1] = 1;
        sal.push(n - 1);
    }
    while (!sal.empty())
    {
        now = sal.front();
        int left = (now > 0 && epy[now-1] < epy[now]) ? depth[now - 1] : 0;
        int right = (now < n - 1 && epy[now + 1] < epy[now]) ? depth[now + 1] : 0;
        sal.pop();
        if (depth[now] == 0)
        {
            depth[now] = max(left, right) + 1;
        }
        //left
        if (now > 0 && depth[now - 1] == 0 && (now == 1 || epy[now - 2] > epy[now - 1] || depth[now - 2] > 0))
        {
            sal.push(now - 1);
        }
        //right
        if (now < n - 1 && (depth[now + 1] == 0) && (now == n - 2 || epy[now + 2] > epy[now + 1] || depth[now + 2] > 0))
        {
            sal.push(now + 1);
        }
    }
    for (auto salary : depth) {
        ans += salary;
    }
    cout << ans * 100 << endl;
}

附錄3:個人簡歷

前端開發工程師-北理工-軟件工程-楊珏成

相關文章
相關標籤/搜索