1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        一行代碼,把項(xiàng)目搞崩潰了!

        共 3494字,需瀏覽 7分鐘

         ·

        2024-05-15 13:48

        最近我們團(tuán)隊(duì)的同學(xué)在開(kāi)發(fā)中發(fā)生了一件 “有意思” 的事情,那就是通過(guò)一行代碼,讓網(wǎng)站卡死了,真的是離了大譜。團(tuán)隊(duì)同學(xué)寫了一篇記錄,希望能長(zhǎng)個(gè)記性吧~

        背景

        今天下午,老魚簡(jiǎn)歷告警群里突然提示了幾個(gè)下載簡(jiǎn)歷失敗的提示。


        我看到后,心里一緊,趕緊打開(kāi)頁(yè)面看看我能不能下載,結(jié)果我這里下載是正常的。于是我就感覺(jué)事情不簡(jiǎn)單,趕緊本地啟動(dòng)項(xiàng)目調(diào)試,我本以為本地啟動(dòng)后控制臺(tái)會(huì)有報(bào)錯(cuò),但是實(shí)際上并沒(méi)有,沒(méi)辦法,只能使用絕招:二分法先定位到出問(wèn)題代碼。漫長(zhǎng)的縮短問(wèn)題代碼后,最后問(wèn)題代碼找到了

        /**
         * 判斷是否為鏈接
         * @param urlString 接受一個(gè)字符串
         * @returns 一個(gè) boolean 值,true 表示是鏈接,false 表示不是鏈接
         */

        export const isLink = (urlString: string) => {
          const regex = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
          return regex.test(urlString);
        };


        說(shuō)實(shí)話看到是因?yàn)檫@段代碼的我是這樣的:


        我本來(lái)是不會(huì)正則的,這個(gè)是 AI 幫我寫的判斷鏈接的方法。我當(dāng)時(shí)就光測(cè)試它是否能判斷出一個(gè)字符串是否是鏈接,而忽略了特殊字符串是否會(huì)有性能問(wèn)題。最后,我給大家復(fù)現(xiàn)一下這個(gè)bug 最小代碼示例:

        /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test('https://www.suse.com/nbswebapp/createSummary.jsp?')


        只要你在游覽器控制臺(tái)輸入這個(gè),這個(gè)頁(yè)面立馬卡死。

        問(wèn)題原因分析

        那這是為什么呢?聽(tīng)聽(tīng)萬(wàn)能的 AI 這么說(shuō)的:在JavaScript中使用正則表達(dá)式時(shí),如果正則表達(dá)式的設(shè)計(jì)不當(dāng),特別是在處理復(fù)雜的字符串或者特定的模式時(shí),可能會(huì)導(dǎo)致性能問(wèn)題,甚至使瀏覽器卡死。這種現(xiàn)象通常稱為“災(zāi)難性回溯”(Catastrophic Backtracking)。在你提供的正則表達(dá)式中:

        /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/


        這個(gè)表達(dá)式用于匹配URL,其中包含了幾個(gè)可選的組件和量詞(如*?),這些都可能導(dǎo)致正則表達(dá)式引擎進(jìn)行大量的回溯嘗試,尤其是當(dāng)輸入字符串在某些位置上與模式不匹配時(shí)。具體來(lái)說(shuō),問(wèn)題可能出現(xiàn)在([\/\w \.-]*)*這部分。這里使用了兩個(gè)嵌套的量詞(*外面還有一個(gè)*),這種嵌套的量詞是造成災(zāi)難性回溯的常見(jiàn)原因。當(dāng)輸入的URL在最后一部分(即[\/\w \.-]*應(yīng)該匹配的部分)稍有不符時(shí),正則表達(dá)式引擎可能會(huì)嘗試所有可能的分割方式來(lái)匹配整個(gè)模式,這會(huì)導(dǎo)致處理時(shí)間急劇增加。為了避免這種問(wèn)題,可以嘗試優(yōu)化正則表達(dá)式的結(jié)構(gòu),避免使用嵌套的量詞,或者使用更具體的字符類匹配來(lái)減少潛在的回溯。例如,可以修改為:

        /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]+)?\/?$/


        這里,我將內(nèi)部的*修改為+,使得這部分至少匹配一次,減少了嵌套量詞的使用,這應(yīng)該可以幫助減輕瀏覽器的負(fù)擔(dān)。總之,設(shè)計(jì)正則表達(dá)式時(shí)需要注意避免復(fù)雜的嵌套和過(guò)度的通配符使用,特別是在處理可能非常長(zhǎng)或復(fù)雜的字符串時(shí)。這樣不僅可以避免瀏覽器卡死的問(wèn)題,還可以提高應(yīng)用的響應(yīng)速度和用戶體驗(yàn)。實(shí)測(cè),。這個(gè)正則是有問(wèn)題的:


        我現(xiàn)在是用新的檢測(cè)字符串是否是鏈接的方法,充足測(cè)試下來(lái)沒(méi)有問(wèn)題:

        /**
         * 判斷字符串是否為鏈接
         */

        export function isLink(urlString: string): boolean {
          const pattern = new RegExp(
            '^(https?:\\/\\/)?' + // 協(xié)議
              '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|' + // 域名
              '((\\d{1,3}\\.){3}\\d{1,3}))' + // 或IP(v4)地址
              '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*' + // 端口和路徑
              '(\\?[;&a-z\\d%_.~+=-]*)?' + // 查詢參數(shù)
              '(\\#[-a-z\\d_]*)?$',
            'i',
          ); // 錨點(diǎn)
          return !!pattern.test(urlString);
        }

        怎么避免?

        這次出現(xiàn)這個(gè)問(wèn)題的原因有兩個(gè)

        1. 經(jīng)驗(yàn)不足:如果我知道,不好的正則出導(dǎo)致災(zāi)難性回溯的話,我在拿到 AI 給我寫的正則,我就會(huì)問(wèn)它給我的正則是否會(huì)導(dǎo)致災(zāi)難性回溯。
        2. 沒(méi)有充足的測(cè)試:如果我的項(xiàng)目有對(duì)這種工具方法的充足的測(cè)試,應(yīng)該也不會(huì)產(chǎn)生這個(gè) bug 了。

        總結(jié)

        遇到 bug 不要慌,從簡(jiǎn)單到難的使用排查問(wèn)題的方法。先定位到問(wèn)題。例如:我遇到bug,先定位前端問(wèn)題還是后端問(wèn)題,再定位問(wèn)題的大的位置,逐漸縮小范圍,最終找到問(wèn)題的位置。然后解決問(wèn)題。有沒(méi)有覺(jué)得這其實(shí)就是使用二分法的思想來(lái)定位問(wèn)題。找到問(wèn)題的代碼了,那其實(shí)就勝利一大半了,剩下的就是寫出正確的代碼,做充足的測(cè)試,最后復(fù)盤這次 bug,以后不要再犯同樣的錯(cuò)就好了!



        ???? 點(diǎn)擊下方閱讀原文,獲取魚皮往期編程干貨。

        往期推薦

        我的編程學(xué)習(xí)小圈子

        我做了個(gè)網(wǎng)站,幫你寫出滿分簡(jiǎn)歷

        我學(xué)計(jì)算機(jī)的四年,共勉

        雙非本,投遞4000+份簡(jiǎn)歷,上岸了!

        我開(kāi)源了一套 RPC 框架,學(xué)爆它!

        耗時(shí)幾個(gè)月,我們做的小工具上線啦!

        升級(jí)了項(xiàng)目的部署方式,坑死我了!

        瀏覽 444
        2點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        2點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            六月天av | 日日摸夜夜添夜夜添精品视频 | 长泽梓黑人初解禁bdd07 | 性无码一区二区三区在线观看 | 男男h双腿涨灌play慎入动漫 | 亚洲三级片网站 | 自慰网址 | 久久午夜无码鲁丝片午夜精品 | 亚洲精品国产AV | 小雪被房东的好爽文 |