前端面試八股文

来源:https://www.cnblogs.com/yingzi1028/archive/2022/09/21/16715273.html
-Advertisement-
Play Games

1.HTTP和HTTPS的基本概念 http:是一個客戶端和服務端請求和應答的標準(TCP),用於從www伺服器傳輸超文本到本地瀏覽器的超文本傳輸協議。 https:是以安全為目標的HTTP通道,即HTTP下加入SSL層進行加密。其作用是:建立一個信息安全通道,確保數據的傳輸,確保網站的真實性。 補 ...


1.HTTP和HTTPS的基本概念

http:是一個客戶端和服務端請求和應答的標準(TCP),用於從www伺服器傳輸超文本到本地瀏覽器的超文本傳輸協議。

https:是以安全為目標的HTTP通道,即HTTP下加入SSL層進行加密。其作用是:建立一個信息安全通道,確保數據的傳輸,確保網站的真實性。

補充:SSL是洋文“Secure Sockets Layer”的縮寫,中文叫做“安全套接層”。

2.HTTP和HTTPS的區別及優缺點?

  1. HTTPS 協議需要 CA 證書,費用較高;而HTTP 協議不需要;
  2. HTTP是超文本傳輸協議,信息是明文傳輸;HTTPS協議要比HTTP協議安全,HTTPS是具有安全性的SSL加密傳輸協議,可防止數據在傳輸過程中被竊取、改變,確保數據的完整性(當然這種安全性並非絕對的,低於更深的Web安全問題,次數暫且不表);
  3. HTTP協議的預設埠為80;HTTPS預設埠為443;
  4. HTTP 協議連接很簡單,是無狀態的;HTTPS 協議是有SSL 和HTTP協議構建的可進行加密傳輸、身份認證的網路協議,比HTTP 更加安全;

3.HTTPS協議工作原理

如何保證信息的安全性:對稱加密、非對稱加密、數字證書與數字簽名

  1. 客戶端申請HTTPS通信,建立SSL鏈接
  2. 伺服器響應並向客戶端傳遞證書(證書中包含了密鑰)
  3. 客戶端驗證證書,獲取公鑰生成對稱加密密鑰,用公鑰加密後傳給伺服器
  4. 伺服器收到消息,用私鑰解密,拿出對稱密鑰,並通知客戶端,SSL通道建立完成,HTTPS通道也建立完成。
  5. 共用密鑰交換成功,HTTPS通信建立後,客戶端和服務端利用共用密鑰加密通信
  6. 客戶端斷開鏈接

一定要用https嗎?

https那麼的安全,是不是我們在什麼場景下都要去使用https進行通信呢?答案是否定的。

1)https雖然提供了消息安全傳輸的通道,但是每次消息的加解密十分耗時,消息系統資源。所以,除非在一些對安全性比較高的場景下,比如銀行系統,購物系統中我們必須要使用https進行通信,其他一些對安全性要求不高的場景,我們其實沒必要使用https。

2)使用https需要使用到數字證書,但是一般權威機構頒發的數字證書都是收費的,而且價格也是不菲的,所以對於一些個人網站特別是學生來講,如果對安全性要求不高,也沒必要使用https。

參考:https的工作原理

4.TCP三次握手

第一次握手:建立連接,客戶端發送SYN包(syn=j)(是TCP/IP建立連接時使用的握手信號。),隨後客戶端進入SYN-SENT階段,等待服務端確認。

第二次握手:服務端收到syn包並確認客戶的SYN,同時也發送一個自己的SYN包,隨後伺服器端進入SYN-RCVD階段。

第三次握手:客戶端接收到來自伺服器端的確認收到數據的SYN+ACK包,明確了從客戶端到伺服器的數據傳輸是正常的,結束SYN-SENT階段,並向伺服器發送確認包ACK。隨後客戶端進入ESTABLISHED階段。伺服器收到來自客戶端的“確認收到伺服器數據”的TCP報文之後,明確了從伺服器到客戶端的數據傳輸是正常的。完成三次握手。

為什麼要進行第三次握手?

為了防止伺服器端開啟一些無用的連接增加伺服器開銷以及防止已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。

由於網路傳輸是有延時的(要通過網路光纖和各種中間代理伺服器),在傳輸的過程中,比如客戶端發起了SYN=1創建連接的請求(第一次握手)。如果伺服器端就直接創建了這個連接並返回包含SYN、ACK和Seq等內容的數據包給客戶端,這個數據包因為網路傳輸的原因丟失了,丟失之後客戶端就一直沒有接收到伺服器返回的數據包。客戶端可能設置了一個超時時間,時間到了就關閉了連接創建的請求。再重新發出創建連接的請求,而伺服器端是不知道的,如果沒有第三次握手告訴伺服器端客戶端收的到伺服器端傳輸的數據的話,伺服器端是不知道客戶端有沒有接收到伺服器端返回的信息的。

5.TCP四次揮手

  • 首先客戶端想要釋放連接,向伺服器端發送一段TCP報文,隨後客戶端進入FIN-WAIT-1階段,即半關閉階段,並且停止在客戶端到伺服器端方向上發送數據,但是客戶端仍然能接收從伺服器端傳輸過來的數據。
  • 伺服器端接收到從客戶端發出的連接釋放報文之後,確認了客戶端想要釋放連接,發出確認報文,表示“接收到客戶端發送的釋放連接的請求”。

前"兩次揮手"既讓伺服器端知道了客戶端想要釋放連接,也讓客戶端知道了伺服器端瞭解了自己想要釋放連接的請求。於是,可以確認關閉客戶端到伺服器端方向上的連接了

  • 伺服器端自從發出ACK確認報文之後,經過CLOSED-WAIT階段,做好了釋放伺服器端到客戶端方向上的連接準備,向客戶端發出釋放報文,等待客戶端的確認,隨後伺服器端結束CLOSE-WAIT階段,進入LAST-ACK階段。並且停止在伺服器端到客戶端的方向上發送數據,但是伺服器端仍然能夠接收從客戶端傳輸過來的數據。
  • 客戶端收到伺服器的連接釋放報文後,向伺服器端發送確認報文,伺服器端收到從客戶端發出的TCP報文之後結束LAST-ACK階段,進入CLOSED階段。由此正式確認關閉伺服器端到客戶端方向上的連接。

簡單來說

第一次揮手:客戶端告訴服務端我要斷開連接了

第二次揮手:服務端告訴客戶端我知道你要斷開連接了,並告訴客戶端你可以斷開了

第三次揮手:服務端做好了斷開準備,並想客戶端發送斷開請求,等到客戶端確認

第四次揮手:客戶端接收到服務端的可以釋放的信號,向服務端發送確認斷開的信號,服務端收到後就關閉連接。

參考:詳解 TCP 連接的“ 三次握手 ”與“ 四次揮手

6.cookie、sessionStorage、localStorage的區別

相同點:都是在開發中用到的臨時存儲客戶端會話信息或者數據的方法

不同點:

1.存儲的時間有效期不同

  • cookie的有效期是可以設置的,預設的情況下是關閉瀏覽器後失效
  • sessionStorage的有效期是僅保持在當前頁面,關閉當前會話頁或者瀏覽器後就會失效
  • localStorage的有效期是在不進行手動刪除的情況下是一直有效的

2.存儲的大小不同

  • cookie的存儲是4kb左右,存儲量較小,一般頁面最多存儲20條左右信息
  • localStorage和sessionStorage的存儲容量是5Mb(官方介紹,可能和瀏覽器有部分差異性)

3.與服務端的通信

  • cookie會參與到與服務端的通信中,一般會攜帶在http請求的頭部中,例如一些關鍵密匙驗證等。
  • localStorage和sessionStorage是單純的前端存儲,不參與與服務端的通信

參考:cookie、localStorage和sessionStorage三者的區別

7.Vuex 和 localStorage 的區別

  1. 最重要的區別:vuex 存儲在記憶體中localstorage 則以文件的方式存儲在本地,只能存儲字元串類型的數據,存儲對象需要 JSON 的 stringify 和parse 方法進行處理。讀取記憶體比讀取硬碟速度要快。
  2. 應用場景 Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vuex 用於組件之間的傳值。localstorage 是本地存儲,是將數據存儲到瀏覽器的方法,一般是在跨頁面傳遞數據時使用 。 Vuex 能做到數據的響應式,localstorage 不能。
  3. 永久性 刷新頁面時 vuex 存儲的值會丟失,localstorage 不會。註意:對於不變的數據確實可以用 localstorage 可以代替vuex,但是當兩個組件共用一個數據源(對象或數組)時,如果其中一個組件改變了該數據源,希望另一個組件響應該變化時,localstorage無法做到,原因就是區別 1。

8.瀏覽器如何渲染網頁

  1. 解析HTML生成DOM樹 - 渲染引擎首先解析HTML文檔,生成DOM樹
  2. 構建Render樹 - 接下來不管是內聯式,外聯式還是嵌入式引入的CSS樣式會被解析生成CSSOM樹,根據DOM樹與CSSOM樹生成另外一棵用於渲染的樹-渲染樹(Render tree),
  3. 佈局Render樹 - 然後對渲染樹的每個節點進行佈局處理,確定其在屏幕上的顯示位置
  4. 繪製Render樹 - 最後遍歷渲染樹並用UI後端層將每一個節點繪製出來

解析HTML文件,創建DOM樹,自上而下,如果遇到樣式(link、style)與腳本(script)都會阻塞

補充1:輸入url後發生了什麼?

  1. DNS功能變數名稱解析
  2. 建立TCP連接(三次握手)
  3. 發送HTTP請求
  4. 伺服器處理請求,返迴響應結果
  5. 關閉TCP連接(四次揮手)
  6. 瀏覽器解析HTML渲染頁面,構建DOM樹

詳解:從輸入url到頁面載入完成發生了什麼?

補充2:避免JavaScript 阻塞JavaScript 腳本延遲載入的方式有哪些?

  1. defer 屬性:給 js 腳本添加 defer 屬性,這個屬性會讓腳本的載入與文檔的解析同步解析,然後在文檔解析完成後再執行這個腳本文件,這樣的話就能使頁面的渲染不被阻塞。多個設置了defer屬性 14 的腳本按規範來說最後是順序執行的,但是在一些瀏覽器中可能不是這樣。
  2. async 屬性:給 js 腳本添加 async 屬性,這個屬性會使腳本非同步載入,不會阻塞頁面的解析過程,但是當腳本載入完成後立即執行js腳本,這個時候如果文檔沒有解析完成的話同樣會阻塞。多個async屬性的腳本的執行順序是不可預測的,一般不會按照代碼的順序依次執行。
  3. 動態創建 DOM 方式:動態創建 DOM 標簽的方式,可以對文檔的載入事件進行監聽,當文檔載入完成後再動態的創建script 標簽來引入js 腳本。
  4. 使用 setTimeout 延遲方法:設置一個定時器來延遲載入js 腳本文件
  5. 讓 JS 最後載入:將 js 腳本放在文檔的底部,來使js 腳本儘可能的在最後來載入執行。

9.重繪與重排相關

重繪與重排的區別

重排:當渲染樹中部分或者全部元素的尺寸、結構或者屬性發生變化時,瀏覽器會重新渲染部分或者全部文檔的過程就稱為重排/迴流。

重繪:當頁面中某些元素的樣式發生變化,但是不會影響其在文檔流中的位置時,瀏覽器就會對元素進行重新繪製,這個過程就是重繪。

如何觸發重繪與重排

下麵這些操作會導致重排/迴流:

頁面的首次渲染 、瀏覽器的視窗大小發生變化 、元素的內容發生變化 、元素的尺寸或者位置發生變化、 元素的字體大小發生變化、 激活 CSS 偽類、 查詢某些屬性或者調用某些方法 、添加或者刪除可見的 DOM 元素

在觸發迴流(重排)的時候,由於瀏覽器渲染頁面是基於流式佈局的,所以當觸發迴流時,會導致周圍的 DOM 元素重新排列,它的影響範圍有兩種: 全局範圍:從根節點開始,對整個渲染樹進行重新佈局局部範圍:對渲染樹的某部分或者一個渲染對象進行重新佈局

下麵這些操作會導致重繪:

color、background 相關屬性:background-color、background-image等 outline 相 關 屬 性 : outline-color 、outline-width、text-decoration border-radius、visibility、box-shadow 註意: 當觸發重排/迴流時,一定會觸發重繪,但是重繪不一定會引發重排/迴流。

如何避免重繪或重排

  1. 用transform做形變和位移可以減少reflow
  2. 避免逐個修改節點樣式,儘量一次性修改
  3. 使用DocumentFragment將需要多次修改的DOM元素緩存,最後一次性append到真實DOM中渲染
  4. 可以將需要多次修改的DOM元素設置display:none,操作完再顯示。(因為隱藏元素不在render樹內,因此修改隱藏元素不會觸發迴流重繪)
  5. 避免多次讀取某些屬性
  6. 通過絕對位移將複雜的節點元素脫離文檔流,形成新的Render Layer,降低迴流成本
  7. 提升為合成層     將元素提升為合成層有以下優點:
    • 合成層的點陣圖,會交由 GPU 合成,比 CPU 處理要快
    • 當需要 repaint 時,只需要 repaint 本身,不會影響到其他的層
    • 對於 transform 和 opacity 效果,不會觸發 layout 和 paint

提升合成層的最好方式是使用 CSS 的 will-change 屬性:

#target{
  will-change: transform;
}

參考:什麼是重排(迴流)和重繪?如何避免他們?

註意:

  • 直接使用opacity即觸發重繪,又觸發重排(GPU底層設計如此!)。
  • opacity配合圖層使用,即不觸發重繪也不觸發重排。(原因:透明度的改變時,GPU在繪畫時只是簡單的降低之前已經畫好的紋理的alpha值來達到效果,並不需要整體的重繪。不過這個前提是這個被修改opacity本身必須是一個圖層。)
參考:圖層與重排重繪

 10.瀏覽器的緩存機制 強緩存、協商緩存

瀏覽器與伺服器通信的方式為應答模式,即是:瀏覽器發起HTTP請求-伺服器響應請求。那麼瀏覽器第一次向伺服器發起該請求後拿到請求結果,會根據響應報文中HTTP頭的緩存標識,決定是否緩存結果,是則將請求和緩存標識存入瀏覽器緩存中,簡單的過程如下圖:

由上圖我們可以知道:

  • 瀏覽器每次發起請求,都會先在瀏覽器緩存中查找該請求的結果以及緩存標識
  • 瀏覽器每次拿到返回的請求結果都會將該結果和緩存標識存入瀏覽器緩存中

以上兩點結論就是瀏覽器緩存機制的關鍵,他確保了每個請求的緩存存入與讀取,只要我們再理解瀏覽器緩存的使用規則,那麼所有的問題就迎刃而解了,本文也將圍繞著這點進行詳細分析。為了方便大家理解,這裡我們根據是否需要向伺服器重新發起HTTP請求將緩存過程分為兩個部分,分別是強制緩存和協商緩存 。

強制緩存

強制緩存就是向瀏覽器緩存查找該請求結果,並根據該結果的緩存規則來決定是否使用該緩存結果的過程,強制緩存的情況主要有三種(暫不分析協商緩存過程),如下:

  • 不存在該緩存結果和緩存標識,強制緩存失效,則直接向伺服器發起請求(跟第一次發起請求一致)
  • 存在該緩存結果和緩存標識,但該結果已失效,強制緩存失效,則使用協商緩存
  • 存在該緩存結果和緩存標識,且該結果尚未失效,強制緩存生效,直接返回該結果
那麼強制緩存的緩存規則是什麼?

當瀏覽器向伺服器發起請求時,伺服器會將緩存規則放入HTTP響應報文的HTTP頭中和請求結果一起返回給瀏覽器,控制強制緩存的欄位分別是Expires和Cache-Control,其中Cache-Control優先順序比Expires高。

協商緩存

 協商緩存就是強制緩存失效後,瀏覽器攜帶緩存標識向伺服器發起請求,由伺服器根據緩存標識決定是否使用緩存的過程,同樣,協商緩存的標識也是在響應報文的HTTP頭中和請求結果一起返回給瀏覽器的,控制協商緩存的欄位分別有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的優先順序比Last-Modified / If-Modified-Since高。其主要有以下兩種情況:

  • 協商緩存生效,返回304
  • 協商緩存失效,返回200和請求結果結果

參考:徹底理解瀏覽器的緩存機制

11.防抖和節流

防抖:是指在事件被觸發 n 秒後再執行回調,如果在這n 秒內事件又被觸發,則重新計時。這可以使用在一些點擊請求的事件上,避免因為用戶的多次點擊向後端發送多次請求。

節流:是指規定一個單位時間,在這個單位時間內,只能有一次觸發事件的回調函數執行,如果在同一個單位時間內某事件被觸發多次,只有一次能生效。節流可以使用在 scroll 函數的事件監聽上,通過事件節流來降低事件調用的頻率。

防抖和節流的應用場景

防抖
1.登錄、發簡訊等按鈕避免用戶點擊太快,以致於發送了多次請求,需要防抖。
2.調整瀏覽器視窗大小時,resize 次數過於頻繁,造成計算過多。
3.文本編輯器實時保存,當無任何更改操作一秒後進行保存。
4.DOM 元素的拖拽功能實現。
5.計算滑鼠移動的距離。
6.Canvas 模擬畫板功能。
7.搜索聯想。
節流
1.scroll 事件,每隔一秒計算一次位置信息等。
2.瀏覽器播放事件,每個一秒計算一次進度信息等。
3.input框實時搜索併發送請求展示下拉列表,每隔一秒發送一次請求 (也可做防抖)。

實現節流函數和防抖函數

函數防抖的實現:

        function debounce(fn, wait) {
            var timer = null;
            return function () {
                var context = this,
                    args = [...arguments];
                // arguments是function里特定的對象之一,指的是function的參數對象,按題意里的,當然對應的就是它所在的那一層function。即return function(){};
                //如果此時存在定時器的話,則取消之前的定時器重新計時
                if (timer) {
                    clearTimeout(timer)
                    timer = null
                }
                //設計定時器,使事件間隔指定時間後執行
                timer = setTimeout(() => {
                    fn.apply(context, args);
                }, wait)
            }
        }

        function sayHi() {
            console.log("防抖成功");
        }
        var inp = document.getElementById("inp");
        inp.addEventListener("input", debounce(sayHi, 2000)); //防抖

函數節流的實現:

        //時間戳版
        function throttle(fn, delay) {
            var preTime = Date.now();
            return function () {
                var context = this, args = [...arguments], nowTime = Date.now();
                //如果兩次時間間隔超過了指定時間,則執行函數。
                if (nowTime - preTime >= delay) {
                    preTime = Date.now();
                    return fn.apply(context, args);
                }
            }
        }

        //定時器版
        function throttle2(fun, awit) {
            let timeOut = null;
            return function () {
                let context = this, args = [...arguments];
                if (!timeOut) {
                    timeOut = setTimeout(() => {
                        fun.apply(context, args);
                        timeOut = null
                    }, awit)
                }
            }
        }

        function sayHi() {
            console.log(e.target.innerWidth,e.target.innerHeight);
        }

        window.addEventListener('resize',throttle2(sayHi,1000))

 

作者:愛喝酸奶的吃貨出處:http://www.cnblogs.com/yingzi1028/ 本博客文章大多為原創,轉載請請在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 現如今,人們在網上聊天、發帖時越來越愛用表情包,表情包一方面是一種個性化的表達方式,另一方面更能傳達出當下的心理活動,可以說在網路社交中表情包是一個不可或缺的存在。加上近年來元宇宙的興起,3D虛擬形象廣泛應用,用戶可以通過自己的表情來控制虛擬形象的表情,做一系列專屬的表情包,更加生動形象。 那麼,如 ...
  • ##vue+element-ui後臺管理系統模板 前端:基於vue2.0+或3.0+加上element-ui組件框架 後端:springboot+mybatis-plus寫介面 通過Axios調用介面完成數據傳遞 通過router路由完成各頁面的跳轉 ###全局配置 App.vue <templat ...
  • 好家伙,繼續優化, 好家伙,我把我的飛機大戰發給我的小伙伴們玩 期待著略微的贊賞之詞,然後他們用手機打開我的給他們的網址 然後點一下飛機就炸了。 游戲體驗零分 (滑鼠點擊在移動端依舊可以生效) 好了所以我們來優化一下這個觸屏移動事件 由於沒有參考,就去翻文檔了 觸摸事件分三個:touchstart、 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1. 定義整體結構 先寫出構造函數,將Promise向外暴露 /* 自定義Promise函數模塊:IIFE */ (function (window) { /* Promise構造函數 executor:執行器函數 */ function ...
  • 一.分類 1.1 頁面佈局 首先創建cate的分支 定義基本結構,因為是兩個需要滾動的區域,所以這裡要用到組件 ==scroll== 這個組件如果是y scroll那就要固定高度,x scroll那就要固定寬度 這裡有個問題就是,我們應該把高度限定在整個屏幕高度 這裡用到uniapp一個api == ...
  • 每日3題 1 以下代碼執行後,控制臺中的輸出內容為? class A { static a = "123"; } class B extends A {} console.log(B.a); 2 以下3句語句,哪句是合法的 1.toString(); 1..toString(); 1...toStr ...
  • 1. 安裝sass 較新的版本不需要配置sass-loader等一系列插件,安裝即用。 npm install --save-dev sass 2. 編寫App.tsx中的基本DOM 更改app.css為app.scss,並刪除其中全部內容 使用如下代碼替換app.tsx中的內容 import ". ...
  • 1 微信小程式原生推拉流組件功能簡介 本文將介紹如何使用微信小程式原生推拉流組件 <live-pusher> 和 <live-player> 進行推拉流,快速實現一個簡單的實時音視頻通話。 由於微信小程式原生推拉流組件使用起來比較複雜,推薦開發者使用即構封裝的音視頻SDK <zego-push> 和 ...
一周排行
    -Advertisement-
    Play Games
  • Github / Gitee QQ群(1群) : 813100564 / QQ群(2群) : 579033769 視頻教學 介紹 MiniWord .NET Word模板引擎,藉由Word模板和數據簡單、快速生成文件。 Getting Started 安裝 nuget link : https:// ...
  • Array.Sort Array類中相當實用的我認為是Sort方法,相比起冗長的冒泡排序,它的出現讓排序更加的簡化 結果如下: 還可以聲明一個靜態方法用來專門調用指定數組排序,從名為 array 的一維數組中 a 索引處開始,到 b 元素 從小到大排序。 註意: a + b 不能大於 array 的 ...
  • 前言 在上一篇文章CLR類型系統概述里提到,當運行時掛起時, 垃圾回收會執行堆棧遍歷器(stack walker)去拿到堆棧上值類型的大小和堆棧根。這裡我們來翻譯BotR里一篇專門介紹Stackwalking的文章,希望能加深理解。 順便說一句,StackWalker在中文里似乎還沒有統一的翻譯,J ...
  • 使用過 nginx 的小伙伴應該都知道,這個中間件是可以設置跨域的,作為今天的主角,同樣的 反向代理中間件的 YARP 毫無意外也支持了跨域請求設置。 有些小伙伴可能會問了,怎樣才算是跨域呢? 在 HTML 中,一些標簽,例如 img、a 等,還有我們非常熟悉的 Ajax,都是可以指向非本站的資源的 ...
  • 什麼是Git Git 是一個開源的分散式版本控制系統,用於敏捷高效地處理任何或小或大的項目。 Git 是 Linus Torvalds 為了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟體。 Git 與常用的版本控制工具 CVS, Subversion 等不同,它採用了分散式版本庫的 ...
  • 首先CR3是什麼,CR3是一個寄存器,該寄存器內保存有頁目錄表物理地址(PDBR地址),其實CR3內部存放的就是頁目錄表的記憶體基地址,運用CR3切換可實現對特定進程記憶體地址的強制讀寫操作,此類讀寫屬於有痕讀寫,多數驅動保護都會將這個地址改為無效,此時CR3讀寫就失效了,當然如果能找到CR3的正確地址... ...
  • 說明 onlyoffice為一款開源的office線上編輯組件,提供word/excel/ppt編輯保存操作 以下操作均基於centos8系統,officeonly鏡像版本7.1.2.23 鏡像下載地址:https://yunpan.360.cn/surl_y87CKKcPdY4 (提取碼:1f92 ...
  • 二叉樹查找指定的節點 前序查找的思路 1.先判斷當前節點的no是否等於要查找的 2.如果是相等,則返回當前節點 3.如果不等,則判斷當前節點的左子節點是否為空,如果不為空,則遞歸前序查找 4.如果左遞歸前序查找,找到節點,則返回,否繼續判斷,當前的節點的右子節點是否為空,如果不為空,則繼續向右遞歸前 ...
  • ##Invalid bound statement (not found)出現原因和解決方法 ###前言: 想必各位小伙伴在碼路上經常會碰到奇奇怪怪的事情,比如出現Invalid bound statement (not found),那今天我就來分析以下出現此問題的原因。 其實出現這個問題實質就是 ...
  • ###一、背景知識 爬蟲的本質就是一個socket客戶端與服務端的通信過程,如果我們有多個url待爬取,只用一個線程且採用串列的方式執行,那隻能等待爬取一個結束後才能繼續下一個,效率會非常低。 需要強調的是:對於單線程下串列N個任務,並不完全等同於低效,如果這N個任務都是純計算的任務,那麼該線程對c ...