本文介紹了我 HTML、CSS谬运、JavaScript 兩天速成的方法,以及騰訊廣州微信 Web 前端組三次技術面試并通過的經歷爬骤。
- 2020-04-10 17:11: 廣州微信 Web 前端組 @Molunerfinn (PiEgg) 通過郵箱聯(lián)系我骡湖,邀請我向他們部門投遞簡歷贱纠。
- 2020-04-10 17:36: 我投遞了簡歷
- 2020-04-10 19:33: 人事部門打電話給我約面試時間
- 2020-04-13 15:00: 技術第一次面試
- 2020-04-14 21:00: 技術第二次面試(組長面)
- 2020-04-16 20:00: 技術第三次面試(總監(jiān)面)
- 2020-04-18 14:30: HR 面試
- 待定: 最終結果
此外,之前我掛過一次后端的一面:
- 2020-03-21 10:30: 北京后端開發(fā)第一次面試
目錄
前期準備
先說說我的基礎响蕴。初三開始接觸 Web 前端谆焊,HTML、JavaScript浦夷、CSS 等原生的語法比較熟悉辖试,DOM 操作、事件監(jiān)聽劈狐、AJAX 都有了解罐孝,知道一小點 HTML5 和 CSS3 特性。網絡相關比較熟悉肥缔,畢竟爬蟲寫了不少莲兢,也沒少寫過后端(PHP)。但是最近一次寫 Web 項目是一年多前了辫继,已經忘了不少怒见。但前端框架 Vue.js、React.js姑宽、Angular.js 一個不會 遣耍,JavaScript 的繼承、閉包不了解炮车。
我第一次面騰訊是在 2020-03-21舵变,面的是北京騰訊的后臺開發(fā)。當時直接掛掉了瘦穆,面試官的評語是 “C++ STL 不熟悉纪隙,多線程基礎為 0”,描述的沒有問題扛或。因為我這些跟學校學的绵咱,期末也拿了非常高的分數(shù)(前 3%),但畢竟國內計算機課的教學水平有待提升熙兔。這是由于高考篩選制度悲伶,把大多數(shù)不喜歡編程,不會編程的人招到了計算機專業(yè)住涉。學校內沒有編程氛圍麸锉,老師講課也只能照顧大多數(shù)人,無可厚非舆声。
前端就不一樣了花沉,這個不是跟著學校學的。我初三開始自學寫網站,接觸了域名碱屁、DNS磷脯、Jekyll 靜態(tài)網頁生成器、VPS忽媒、Nginx争拐、PHP腋粥、寫過 WordPress 插件(并發(fā)布)晦雨,大一還做過前端開發(fā)的外包,也可以說是有點項目經歷了隘冲。
我當時也并非從頭準備闹瞧。我買了本適合有一定基礎的開發(fā)閱讀的張容銘的《前端程序員面試秘籍》。由于是周一面試展辞,我周五晚上下的單奥邮,周末兩天看了看,一共就翻了前一半罗珍。知道了很多 CSS3 和 HTML5 特性洽腺,問到這個不至于答不上來。第一次聽說 JavaScript 的閉包覆旱、鏈式調用蘸朋、對象的繼承、事件冒泡扣唱。面試中考到了不少藕坯,可以說這是我的救命稻草了。
掛掉的后臺開發(fā)面試
后臺開發(fā)的投遞錄用比例是 6:1噪沙。問了這幾個問題:
- CDN 的工作原理
- DNS 的工作原理
- C++ 多態(tài)
- C++ 繼承時構造函數(shù)和析構函數(shù)的執(zhí)行順序
- C++ 繼承時析構函數(shù)要額外注意哪一點
- C++ 多線程(不會)
- 數(shù)據庫的 Transaction(一對一轉賬炼彪,會;二對一轉賬正歼,不會)
- 說說數(shù)據庫的 “鎖”(不會)
- C++ map 迭代器辐马,去除某值的元素(沒寫出來)
- 寫一下檢查鏈表有無環(huán)的程序(一開始答錯,后改正)
評語如下:
可能是他面試經驗不足得原因吧局义,好幾個筆試題都沒回答出來喜爷。他很難過其他人面試的,他才大二旭咽,后面再練習練習多掌握點基本功會后會很好的贞奋。
不過關于 “很難過其他人面試” 后來被證明打臉,因為我成功被前端組撈走了穷绵。不過這也和我 前期面試 準備有關:這次掛掉的面試基本上就沒準備轿塔。
前端面試經歷
前端的投遞錄用比例是 7:1,貌似比后臺開發(fā)要難一點點。
技術第一次面試
第一次面試話不多說勾缭,上來發(fā)了個短信揍障,在線寫代碼(俗稱:機試/筆試)。當時給我了四道編程題俩由,第一題是閉包毒嫡、第二題是鏈式調用、三四題是算法幻梯。我頭鐵兜畸,寫了閉包和兩道算法。
四選三碘梢,限時 1 小時咬摇,但最后給我延長到 1.25 小時了。
編程第一題:閉包
第一題:實現(xiàn) multiply
要求:
multiply(1,2).result == 2
multiply(1,2)(3).result == 6
multiply(1,2)(3,4).result == 24
multiply(1,2)(3,4)(5).result == 120
這個機試是有反饋的:
時不時貼出來煞躬。我看看你的思路
我立即發(fā)現(xiàn)這題試閉包肛鹏。我第一次提交了個有問題的代碼(但能實現(xiàn)要求樣例)。其實這是我第一次寫這種題恩沛,有些生疏在扰,實在慘不忍睹:
var multiply = function (a, b) {
var multiply = function (c, d) {
if(typeof d === 'undefined'){
return {'result': a * b * c};
}
var e1 = 1;
var multiply = function (e) {
if(typeof e !== 'undefined'){
e1 = e;
}
return {'result': a * b * c * d * e};
};
multiply.result = a * b * c * d * e1;
return multiply;
};
multiply.result = a * b;
return multiply;
};
面試官指出了問題:
第一題希望是,可以傳無限參數(shù)雷客,以及是調用任意次數(shù)的芒珠。
即 multiply(1,2,3,4,5,6,7,…)(…)(…)(…)(…)(…).result 都是可以的
我想了想,發(fā)現(xiàn)這樣反而簡單了:
function multiplyHelper(arguments, base) {
let result = 1;
for (let i = 0; i < arguments.length; i++){
result *= arguments[i];
}
var multiply = function () {
return multiplyHelper(arguments, result * base);
};
multiply.result = result * base;
return multiply;
}
function multiply() {
return multiplyHelper(arguments, 1);
}
就愉快的通過了佛纫。
編程第二題:鏈式調用
這題我知道考點妓局,但我畢竟沒寫過,我就給跳過了呈宇。
第二題:實現(xiàn)一個 superBaby:
要求:
輸入:
superBaby("tom")
輸出:
I am tom
輸入:
superBaby("tom").sleep(10).eat("apple").sleep(4).eat("cake")
輸出:
I am tom
(等待10秒)
Eating apple
(等待4秒)
Eating cake
輸入:
superBaby("tom").eat("banana").sleepFirst(5).eat("apple")
輸出:
(等待5秒后)
I am tom
Eating banana
Eating apple
編程第三題:動態(tài)規(guī)劃
第三題:給定一個代表每個房屋存放金額的非負整數(shù)數(shù)組好爬,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額
你是一個專業(yè)的小偷甥啄,計劃偷竊沿街的房屋存炮。每間房內都藏有一定的現(xiàn)金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統(tǒng)蜈漓,如果兩間相鄰的房屋在同一晚上被小偷闖入穆桂,系統(tǒng)會自動報警。
示例 1:
輸入: [1,2,3,1]
輸出: 4
解釋: 偷竊 1 號房屋 (金額 = 1) 融虽,然后偷竊 3 號房屋 (金額 = 3)享完。 偷竊到的最高金額 = 1 + 3 = 4 。
示例 2:
輸入: [2,7,9,3,1]
輸出: 12
解釋: 偷竊 1 號房屋 (金額 = 2), 偷竊 3 號房屋 (金額 = 9)有额,接著偷竊 5 號房屋 (金額 = 1)般又。偷竊到的最高金額 = 2 + 9 + 1 = 12 彼绷。
我給出的解:
// Dynamic Programming (Recursive + Cache)
// Complexity O(n)
function robHelper(houses, index, cache) {
if (index >= houses.length) {
return 0;
}
if (typeof cache[index] !== 'undefined') {
return cache[index];
}
let a = houses[index] + robHelper(houses, index + 2, cache);
let b = houses[index] + robHelper(houses, index + 3, cache);
let c = houses[index + 1] + robHelper(houses, index + 3, cache);
let d = houses[index + 1] + robHelper(houses, index + 4, cache);
let r = a > b ? a : b;
r = c > r ? c : r;
r = d > r ? d : r;
cache[index] = r;
return r;
}
function rob(houses) {
let cache = [];
let a = robHelper(houses, 0, cache);
let b = robHelper(houses, 1, cache);
return a > b ? a : b;
}
面試官追問如果連環(huán)會怎么樣(不能同時取第一個和最后一個)。當時想了想茴迁,但答的比較糊涂寄悯,說出了個大概。現(xiàn)在發(fā)現(xiàn)其實就分兩種情況討論就行堕义。第一種是去除數(shù)組最后一項計算猜旬,第二種是去除數(shù)組第一項計算,然后取最大值就行了倦卖。
編程第四題:常規(guī)算法題
3 Sum
第四題:微信負責企業(yè)文化的 HR 經常會舉辦各種活動洒擦,去年微信年會的時候, HR 趙組織了一堆的程序員玩起了集卡游戲糖耸。
游戲規(guī)則非常有意思秘遏,每個人會被分配一張卡片丘薛,卡片上會有一個整數(shù)嘉竟,每個人需要找到兩位同伴(即三個人成組),組成一個小組去領取獎品洋侨,要求是這個小組中所有的人的數(shù)字相加起來的結果為 0 舍扰。
此時 HR 趙,拿出了一個隨機數(shù)組了希坚,需要你吧所有可以分組的答案輸出出來边苹。
舉個例子:
例如生成的數(shù)組是 [ -100, -200, 0, 300, 0, 4,96, 96]裁僧,
那么答案是:
[
[-200, -100, 300],
[-100, 4, 96]
]
需要注意的是 活動要求組隊中大家是平等的个束,沒有先后順序,答案不可以重復聊疲,例如 [-100, 4, 96], [4, 96, -100] 會被認同為同一個答案,因為所包含的數(shù)字是一樣的
要求:答案不能出錯茬底,運行速度盡量的快。
這個我以前做過获洲,但我沒看過題解阱表,面試時也沒敢上網搜(誠信做人)。就寫了個復雜度為平方階的垃圾算法:
/**
* 計算組合情況
* 3sum
* Complexity: O(n ^ 2)
* TODO: skip 0, 0, 0; convert to integer
* @param nums 隨機數(shù)組
* @return array 可以分組在一起的情況
*/
function gameAnswer(nums) {
let rawAnswer = [];
for (let i = 0; i < nums.length; i++){
let two = twoSum(nums, -nums[i], i);
for (let j = 0; j < two.length; j++){
rawAnswer.push([two[j], -nums[i] - two[j], nums[i]]);
}
}
let answerDict = {};
for (let i = 0; i < rawAnswer.length; i++){
rawAnswer[i].sort();
answerDict[rawAnswer[i].join('_')] = true;
}
let answer = [];
for (let key in answerDict){
answer.push(key.split('_'));
}
return answer;
}
function twoSum(nums, target, skip) {
let twoSumDict = {};
let answer = [];
for (let i = 0; i < nums.length; i++){
twoSumDict[nums[i].toString()] = i;
}
for (let i = 0; i < nums.length; i++){
if(typeof twoSumDict[(target - nums[i]).toString()] !== 'undefined' && twoSumDict[i] > i && i !== skip && twoSumDict[i] !== skip) {
answer.push(nums[i]);
}
}
return answer;
}
后來面試官提醒我正負數(shù)贡珊,我說確實必須要有正有負才能湊出 0(三個 0 例外)最爬,我說可以分成正負兩個數(shù)組尊剔,能提升性能隘蝎、降低常數(shù),但我補充道復雜度似乎不變智嚷。
問答題匯總
問答題都比較基礎寒随,并且比較開放糠悯。這里不給出我的解答胯努。這次問答基本都答上來了。
1.事件代理(沒答上來)
2.HTTP 狀態(tài)碼
3.緩存 Expires逢防、E-Tag叶沛、Cache-Conrtol 的區(qū)別
4.常見攻擊類型
5.XSS 防范
6.跨域防范
7.HTTPS
8.對稱加密和非對稱加密
9.HTTP2
10.用過什么前端框架?(沒答上來)
11.TypeScript 工作原理
12.性能優(yōu)化
13.冒泡忘朝、如何阻止繼續(xù)冒泡
14.聊了聊之前做過的項目
這次一共一個半小時左右灰署,掛電話前,面試官告訴我一面就給我過了局嘁,讓我等二面溉箕。
后來 PiEgg 跟我說我是他推薦的第一個過一面的,有點小開心悦昵。然后看到了他之前分享的面試經驗里有第二題鏈式調用肴茄,早知道早點問問了,現(xiàn)在想起來有點不甘心但指。
技術第二次面試
第二次是組長面的寡痰。感覺組長很 Friendly,以我自我介紹開始棋凳,說到哪里可以展開了拦坠,他就打斷,深入談到剩岳。我第一次掛掉的面試評語也是他給我念的贞滨。他最常說的是 “嗯,這個項目還是蠻有意思的拍棕∠” 、“既然你說到了……绰播,那我考考你啊……” 以及 “你還做過什么有意思的東西骄噪?”。
中間講項目的時候聊到了很多知識點幅垮,基本都是我說到哪里他問到哪里腰池,不問我沒說過的,也沒有故意難為我忙芒,這里列舉一下:
1.REST API 鑒權示弓,Cookie 原理
2.WebView 與安卓互通原理
3.通過本地監(jiān)聽 HTTP 服務器實現(xiàn)互通,如何實現(xiàn)同步請求(沒答上來)
4.安卓端通知推送
5.網頁端通知推送
6.Application Cache 實現(xiàn)原理呵萨,具體機制
7.Application Cache 有哪些問題奏属,為什么沒流行起來
8.數(shù)據存儲,數(shù)據沖突
9.遇到過哪些反爬蟲技術
10.爬蟲如何通過圖形驗證碼認證
一共聊了半小時潮峦,是最開心的一次面試囱皿,面試完就覺得自己穩(wěn)了勇婴。果然,很快嘱腥,一面的面試官就發(fā)微信告訴我過了耕渴,準備等三面。
中期準備
一開始那邊通知我說預計三面會安排在周五齿兔。我一看還有兩天時間橱脸,打算趁這兩天提升一下自己,就開始學 Vue.js分苇,這樣三面的時候問我會什么前端框架添诉,我還能答上來。當時買了本劉漢偉的《Vue.js 從入門到項目實戰(zhàn)》医寿。但最終第三次面試提前了一天栏赴,我就只看完了重點的部分。若說有什么用靖秩,也不過就是提升了一點自信须眷,第三次面試時并沒有真正考到這一點。
技術第三次面試
第三次技術面試和第一次流程類似盆偿,也是先做一小時編程題柒爸,然后電話問答。不過這次面試題更偏向算法層面事扭,而不是 JavaScript 語言層面。就連編程語言都是可以自選的乐横,以至于我前兩道題選的 C++求橄,秀了一手多態(tài)。
編程一共兩道必做題葡公,一道加分題罐农,限時 60min。
編程第一題:常規(guī)算法題
環(huán)形隊列
一催什、環(huán)形緩沖區(qū)涵亏,又稱為環(huán)形隊列,是一種定長為 N 的先進先出的數(shù)據結構蒲凶。它在進程間的異步數(shù)據傳輸或記錄日志文件時十分有用气筋。環(huán)形緩沖區(qū)通常有一個讀指針和一個寫指針,讀指針指向環(huán)形緩沖區(qū)中可讀的數(shù)據旋圆,寫指針指向環(huán)形緩沖區(qū)中可寫的緩沖區(qū)宠默,通過移動讀指針和寫指針就可以實現(xiàn)緩沖區(qū)的數(shù)據讀取和寫入。
請用數(shù)組實現(xiàn)一個環(huán)形緩沖區(qū)灵巧,支持以下操作:
1. 環(huán)形緩沖區(qū)初始化時支持指定緩沖區(qū)最大容量
2. int take(): 從緩沖區(qū)讀指針位置讀取數(shù)據(總為正數(shù))搀矫,如果沒有數(shù)據可讀返回 -1
3. boolean put(int value): 寫入數(shù)據(總為正數(shù))到緩沖區(qū)抹沪,容量不足無法寫入返回 false,寫入成功返回 true
基礎題瓤球,我也不知道當時為何不用 STL 的 vector 融欧。可能是為了秀秀自己的 C++ 基礎語法(構造函數(shù)卦羡、析構函數(shù)蹬癌、深拷貝的重載)?我當時的解答如下:
template
<class t="">
// T must can compare with int and can cast from int
class Queue {
public:
Queue(int len=20);
~Queue();
T take();
bool put(T value);
// Deep copy
Queue(const Queue & queue1);
Queue & operator= (const Queue & queue1);
protected:
int size{}; // Maximum Size
int length{};
T * queue{};
int begin{};
int end{};
};
template
<class t="">
Queue
<t>
::Queue(int len) {
begin = end = length = 0;
size = len;
if(len < 1) {
throw "Error size";
}
queue = new int[len];
for (int i = 0; i < len; ++i) {
queue[i] = -1;
}
}
template
<class t="">
Queue
<t>
::~Queue() {
delete [] queue;
}
template
<class t="">
T Queue
<t>
::take() {
if(length == 0) {
return -1;
}
int index = (size + begin) % size;
begin = (begin + 1) % size;
length--;
return queue[index];
}
template
<class t="">
bool Queue
<t>
::put(T value) {
if(value <= 0) {
throw "Error put value size";
}
if(length == size) {
return false;
}
length++;
queue[end] = value;
end = (end + 1) % size;
return true;
}
template
<class t="">
Queue
<t>
::Queue(const Queue
<t>
&queue1) {
this->operator=(queue1); // Use the Queue::operator= explicitly
}
template
<class t="">
Queue
<t>
& Queue
<t>
::operator=(const Queue
<t>
& queue1) {
if(this == &queue1){
return *this;
}
this->size = queue1.size;
this->length = queue1.length;
this->begin = queue1.size;
this->end = queue1.size;
queue = new int[size];
for (int i = 0; i < size; ++i) {
queue[i] = queue1.queue[i];
}
return *this;
}
</t>
</t>
</t>
</class>
</t>
</t>
</class>
</t>
</class>
</t>
</class>
</t>
</class>
</t>
</class>
</class>
事實證明學校的 “數(shù)據結構與算法” 這門課并沒有白學:環(huán)形隊列這個東西在我自學算法的時候沒有學到虹茶,即便有逝薪,我可能也不屑于學。但之后面試官的這個問題蝴罪,如果沒專門學過環(huán)形隊列董济,可能就答不上來了:
追問:你這里是使用 length 變量來判斷隊列是否滿的,請問有沒有別的方法要门?
我當時的解答:由于表空和表滿均是 begin == end 虏肾,所以不能直接通過這個條件判斷』端眩可以使用一個 bool 類型的 full 變量封豪,標記是否為滿〕次粒或者在創(chuàng)建數(shù)組的時候多創(chuàng)建一位吹埠,表滿時有一位是空的。
追問:你的 C++ 基礎不錯疮装,說說計算機內存中的堆和棧的區(qū)別缘琅。
一開始我以為是數(shù)據結構,之后在意識到這是計算機底層實現(xiàn)的問題廓推。然而我已經混淆堆和棧了刷袍,我就說一個是存儲 new 創(chuàng)建的變量的,一個是存儲局部變量的樊展。全局變量和 static 變量存在另一個地方呻纹。
編程第二題:常規(guī)算法題
LRU 緩存
二、設計和實現(xiàn)一個 LRU(最近最少使用)緩存機制专缠,支持以下操作:
1. LRUCache 初始化時支持指定緩存最大容量
2. 獲取數(shù)據 int get(int key):如果 key 存在于緩存中雷酪,則返回緩存值(總為正數(shù)),沒有對應緩存則返回 -1
3. 設置數(shù)據 void put(int key, int value): 如果 key 不存在藤肢,寫入數(shù)據值太闺。當緩存容量達到上限時,需淘汰最近最少使用的緩存嘁圈。
我當時復用了第一題的類省骂,但寫完后發(fā)現(xiàn)可能錯了蟀淮,但也沒改。當時解答如下:
#include <unordered_map>
template <class K, class V> // K must can compare with int and can cast from int
class LRUCache {
public:
LRUCache(int len=20): queue(len){};
V get(K key);
void put(K key, V value);
protected:
Queue<K> queue;
std::unordered_map<K, V> table;
};
template<class K, class V>
V LRUCache<K, V>::get(K key) {
auto it = table.find(key);
if(it != it.end()) {
return it->second;
}
return -1;
}
template<class K, class V>
void LRUCache<K, V>::put(K key, V value) {
auto it = table.find(key);
if(it == it.end()) { // Not find. Then it is a new key
int check = queue.put(key);
if(!check) { // Queue is full
K pop = queue.take();
table.erase(pop); // Remove the oldest one
}
check = queue.put(key);
}
table[key] = value;
}
編程第三題:附加題
可信域名列表
三钞澳、(加分題)有一個可信域名列表配置怠惶,如['http://mp.weixin.qq.com', 'https://*.xx.com']
//本題只考慮通配符為 * 的情況
實現(xiàn)函數(shù)
function isValidDomain(url, allowPort) {
return boolean
}
判斷輸入的url是否為可信域名,allowPort為true時轧粟,url中可以帶端口
一開始理解錯了策治,我給的解答如下:
let urls = ['https://*.qq.com'];
function isValidDomain(url, allowPort) {
let result = true;
let wildcard = "[a-zA-Z0-9-.]*";
for (let i = 0; i < urls.length; i++) {
let str = urls[i].replace("*", wildcard);
let append = "";
if (allowPort) {
append = "(:[0-9]{1,5})?"; //
}
let re = new RegExp("^" + str + append + "($|/)");
if(!re.test(url)) {
result = false;
}
}
return result;
}
// https://example.com/.qq.com -> false
// https://sub.qq.com -> true
// https://sub1.sub2.qq.com -> true
// https://www.qq.com -> true
// https://www.qq.coma -> false
// https://www.qq.com/ -> true
// https://www.qq.com/path -> true
問答題匯總
iframe
這里面試交流的感覺不如第二次面試順暢,自我介紹的時候尤其尷尬兰吟。而且我也無法從他的語氣中聽出來我能不能過通惫。不過第二天(周五)下午,還是收到了面試通過的通知混蔼。
最終結果
待更新
前端學習推薦
前端需要掌握最基礎的 HTML履腋、CSS、JavaScript惭嚣。請問這三個中哪個是編程語言遵湖?回答正確,是 JavaScript 沒錯(HTML晚吞、CSS 不配擁有姓名)延旧。HTML 和 CSS 相對簡單,不會有人不會吧槽地?不會的話就多看看現(xiàn)有網站和項目迁沫,然后遇到不懂的就去 W3C 或者 Mozilla 上查一查文檔就好(確信)。這兩個也不是主要考點闷盔,重點還是 JavaScript弯洗。
JavaScript 入門推薦 Jeremy Keith 的《JavaScript DOM 編程藝術》,原版名稱是 DOM Scripting: Web Design With Javascript and the Document Object Model 逢勾。這本書不但講了使用 JavaScript 操作原生 DOM,也講了 JavaScript 的基本語法藐吮。
一般我用的 IDE 是 PhpStorm溺拱,因為它包含了 WebStorm 的所有功能,此外還能寫 PHP谣辞。當然不寫 PHP 的話 WebStorm 就好迫摔,價格還更便宜。(沒錯泥从,我經常 HTML 和 PHP 混在一起寫句占,高度耦合,請見諒)
其實學好前端還是很有用的躯嫉,在學習前端過程中最有用的就是你瀏覽器中的 Console(F12)纱烘。你可以寫寫 JavaScript 腳本杨拐,上網課實現(xiàn)自動翻頁,播放視頻改 16 倍速什么的(逃)擂啥,通過這個你就學會了 CSS 選擇器和循環(huán)什么的哄陶。再分析分析瀏覽器 Console 中 Networks 標簽頁的各個請求,篩選有效請求然后再模擬發(fā)請求哺壶,一鍵刷課屋吨,豈不美滋滋(別跟別人說這是我教的)。這個過程還能學會 HTTP山宾、Cookie至扰、Session、XMLHttpRequest 等相關技術资锰,JSON敢课、URL encode 等各種編碼基礎,還是很實用的台妆。
最重要的還是多多實踐翎猛,可以自己做個網站,一次性踩遍域名接剩、DNS切厘、HTTPS 證書、HTTP 服務器等各種坑懊缺。
還有想了解更多的小伙伴可以加Q群鏈接里面看一下疫稿,應該對你們能夠有所幫助。