web開(kāi)發(fā)面試題及答案_第1頁(yè)
web開(kāi)發(fā)面試題及答案_第2頁(yè)
web開(kāi)發(fā)面試題及答案_第3頁(yè)
web開(kāi)發(fā)面試題及答案_第4頁(yè)
web開(kāi)發(fā)面試題及答案_第5頁(yè)
已閱讀5頁(yè),還剩27頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

web開(kāi)發(fā)面試題及答案Q:請(qǐng)解釋JavaScript中事件循環(huán)(EventLoop)的運(yùn)行機(jī)制,說(shuō)明宏任務(wù)(MacroTask)和微任務(wù)(MicroTask)的區(qū)別,并舉例說(shuō)明常見(jiàn)的任務(wù)類(lèi)型。A:事件循環(huán)是JavaScript處理異步代碼的核心機(jī)制,負(fù)責(zé)協(xié)調(diào)執(zhí)行棧、任務(wù)隊(duì)列(宏任務(wù)隊(duì)列和微任務(wù)隊(duì)列)之間的交互。其運(yùn)行流程大致為:執(zhí)行棧中的同步代碼執(zhí)行完畢后,會(huì)依次檢查微任務(wù)隊(duì)列,清空所有微任務(wù);隨后檢查宏任務(wù)隊(duì)列,取出一個(gè)宏任務(wù)執(zhí)行,執(zhí)行過(guò)程中可能產(chǎn)生新的微任務(wù)或宏任務(wù),重復(fù)此流程。宏任務(wù)和微任務(wù)的核心區(qū)別在于執(zhí)行時(shí)機(jī):微任務(wù)會(huì)在當(dāng)前宏任務(wù)執(zhí)行完畢、渲染之前立即執(zhí)行,而宏任務(wù)需要等待當(dāng)前所有微任務(wù)執(zhí)行完成后才會(huì)被處理。常見(jiàn)的宏任務(wù)包括:script整體代碼(首次執(zhí)行時(shí))、setTimeout/setInterval、I/O操作(如AJAX響應(yīng))、UI渲染事件;微任務(wù)包括:Promise.then()/catch()/finally()、MutationObserver(DOM變化監(jiān)聽(tīng))、process.nextTick(Node.js特有)。例如,以下代碼的執(zhí)行順序?yàn)椋?.輸出同步代碼中的"start";2.執(zhí)行setTimeout(宏任務(wù)),將回調(diào)加入宏任務(wù)隊(duì)列;3.執(zhí)行Promise.resolve().then()(微任務(wù)),將回調(diào)加入微任務(wù)隊(duì)列;4.同步代碼執(zhí)行完畢,檢查微任務(wù)隊(duì)列,執(zhí)行then回調(diào),輸出"microtask";5.進(jìn)入下一輪事件循環(huán),執(zhí)行宏任務(wù)隊(duì)列中的setTimeout回調(diào),輸出"macrotask"。最終輸出順序:start→microtask→macrotask。Q:React中useEffect的依賴(lài)數(shù)組有什么作用?如果依賴(lài)數(shù)組為空或包含函數(shù)會(huì)發(fā)生什么?如何避免因依賴(lài)數(shù)組錯(cuò)誤導(dǎo)致的閉包陷阱?A:useEffect的依賴(lài)數(shù)組用于控制副作用函數(shù)的執(zhí)行時(shí)機(jī)。React通過(guò)比較依賴(lài)數(shù)組中變量的引用或值是否變化,決定是否重新執(zhí)行副作用函數(shù)。若依賴(lài)數(shù)組為空([]),副作用僅在組件掛載時(shí)執(zhí)行一次(類(lèi)似class組件的componentDidMount);若依賴(lài)數(shù)組包含變量(如[count]),則當(dāng)count變化時(shí)重新執(zhí)行;若省略依賴(lài)數(shù)組(即不傳遞),副作用會(huì)在每次組件渲染后執(zhí)行(類(lèi)似componentDidUpdate)。若依賴(lài)數(shù)組包含函數(shù)(如自定義的handleClick),需注意函數(shù)是在組件作用域內(nèi)定義的,每次渲染時(shí)函數(shù)引用會(huì)變化(除非使用useCallback包裹),可能導(dǎo)致副作用頻繁重新執(zhí)行。例如,未用useCallback的函數(shù)作為依賴(lài)時(shí),每次渲染都會(huì)提供新的函數(shù)引用,觸發(fā)useEffect重新執(zhí)行。閉包陷阱通常發(fā)生在副作用函數(shù)中使用了舊狀態(tài)的情況。例如,在setTimeout中訪問(wèn)state變量,若未將state加入依賴(lài)數(shù)組,setTimeout回調(diào)會(huì)捕獲渲染時(shí)的舊state值。解決方法是:將依賴(lài)項(xiàng)正確加入依賴(lài)數(shù)組,或使用函數(shù)式更新(如setState(prev=>prev+1))確保獲取最新?tīng)顟B(tài);若副作用需要訪問(wèn)最新?tīng)顟B(tài)但不想觸發(fā)重執(zhí)行,可使用useRef存儲(chǔ)可變值,通過(guò)ref.current獲取最新值。Q:如何實(shí)現(xiàn)一個(gè)支持無(wú)限滾動(dòng)(InfiniteScroll)的列表組件?需要考慮哪些性能優(yōu)化點(diǎn)?A:實(shí)現(xiàn)無(wú)限滾動(dòng)的核心是檢測(cè)用戶(hù)是否滾動(dòng)到列表底部,觸發(fā)數(shù)據(jù)加載。步驟如下:1.監(jiān)聽(tīng)滾動(dòng)事件(或使用IntersectionObserverAPI),檢測(cè)列表容器或“加載更多”占位元素是否進(jìn)入視口;2.當(dāng)檢測(cè)到滾動(dòng)到底部時(shí),觸發(fā)數(shù)據(jù)請(qǐng)求(需添加防抖,避免頻繁請(qǐng)求);3.加載新數(shù)據(jù)后,將數(shù)據(jù)合并到現(xiàn)有列表狀態(tài)中,觸發(fā)組件重新渲染;4.添加加載狀態(tài)(如“加載中...”)和加載完成/無(wú)更多數(shù)據(jù)的提示。性能優(yōu)化點(diǎn):虛擬滾動(dòng)(VirtualScrolling):僅渲染視口內(nèi)的可見(jiàn)項(xiàng),超出視口的項(xiàng)用占位div填充,減少DOM節(jié)點(diǎn)數(shù)量(可使用react-virtualized或react-window庫(kù));滾動(dòng)事件防抖:使用lodash的debounce或自定義防抖函數(shù),減少滾動(dòng)事件處理頻率;數(shù)據(jù)緩存:對(duì)已加載的數(shù)據(jù)進(jìn)行緩存,避免重復(fù)請(qǐng)求;漸進(jìn)式渲染:新數(shù)據(jù)加載后,通過(guò)key的穩(wěn)定化(如使用唯一id)減少不必要的重渲染;IntersectionObserver替代滾動(dòng)監(jiān)聽(tīng):避免直接監(jiān)聽(tīng)scroll事件導(dǎo)致的性能問(wèn)題,ObserverAPI由瀏覽器優(yōu)化,更高效。Q:MySQL中索引的作用是什么?解釋聚集索引(ClusteredIndex)和非聚集索引(SecondaryIndex)的區(qū)別,并說(shuō)明何時(shí)選擇覆蓋索引(CoveringIndex)。A:索引通過(guò)建立數(shù)據(jù)的快速查找結(jié)構(gòu)(如B+樹(shù)),減少查詢(xún)時(shí)的全表掃描,提升查詢(xún)效率。但索引會(huì)增加寫(xiě)操作(插入、更新、刪除)的開(kāi)銷(xiāo),需權(quán)衡使用。聚集索引決定了表中數(shù)據(jù)的物理存儲(chǔ)順序,一張表只能有一個(gè)聚集索引(通常是主鍵)。聚集索引的葉子節(jié)點(diǎn)存儲(chǔ)了該行的全部數(shù)據(jù)。非聚集索引(輔助索引)的葉子節(jié)點(diǎn)存儲(chǔ)的是索引列的值和對(duì)應(yīng)的聚集索引鍵(主鍵值),通過(guò)主鍵值回表查詢(xún)完整數(shù)據(jù)。覆蓋索引指查詢(xún)所需的所有列都包含在索引中,無(wú)需回表。例如,若查詢(xún)?yōu)镾ELECTname,ageFROMuserWHEREid=1,且存在索引(id,name,age),則該索引即為覆蓋索引,查詢(xún)時(shí)直接從索引中獲取數(shù)據(jù),避免回表。選擇覆蓋索引的場(chǎng)景包括:高頻查詢(xún)的字段組合、減少回表帶來(lái)的I/O消耗(尤其是大表)、優(yōu)化COUNT()等聚合查詢(xún)(通過(guò)覆蓋索引快速統(tǒng)計(jì))。Q:Node.js中如何處理未捕獲的異常(UncaughtException)和未處理的Promise拒絕(UnhandledRejection)??jī)烧叩奶幚矸绞接泻尾煌??A:未捕獲的異常通常指同步代碼中拋出但未被try/catch捕獲的錯(cuò)誤,會(huì)導(dǎo)致進(jìn)程崩潰??赏ㄟ^(guò)監(jiān)聽(tīng)process對(duì)象的'uncaughtException'事件進(jìn)行捕獲:```javascriptprocess.on('uncaughtException',(err)=>{console.error('UncaughtException:',err);//執(zhí)行必要的清理操作(如關(guān)閉數(shù)據(jù)庫(kù)連接)后退出進(jìn)程process.exit(1);});```注意:該事件監(jiān)聽(tīng)?wèi)?yīng)在代碼最頂層注冊(cè),且不建議在事件處理中繼續(xù)執(zhí)行后續(xù)業(yè)務(wù)邏輯(因進(jìn)程可能處于不穩(wěn)定狀態(tài))。未處理的Promise拒絕指異步Promise中reject但未被catch處理的錯(cuò)誤,可能導(dǎo)致內(nèi)存泄漏或不可預(yù)測(cè)的行為??赏ㄟ^(guò)監(jiān)聽(tīng)'unhandledRejection'事件處理:```javascriptprocess.on('unhandledRejection',(reason,promise)=>{console.error('UnhandledRejectionat:',promise,'reason:',reason);//可選擇記錄日志,或針對(duì)特定promise進(jìn)行處理});```與'uncaughtException'不同,'unhandledRejection'不會(huì)直接導(dǎo)致進(jìn)程崩潰,但Node.js在v15+版本中若未處理會(huì)觸發(fā)警告,多次未處理可能導(dǎo)致進(jìn)程退出。兩者的核心區(qū)別:同步異常會(huì)直接中斷當(dāng)前執(zhí)行流程,必須通過(guò)監(jiān)聽(tīng)事件避免進(jìn)程崩潰;而Promise拒絕是異步的,可在事件中記錄并處理,允許程序繼續(xù)運(yùn)行(但需及時(shí)修復(fù)未catch的Promise)。Q:HTTP緩存策略中,強(qiáng)緩存(Cache-Control)和協(xié)商緩存(Last-Modified/ETag)的工作流程是怎樣的?如何結(jié)合使用兩者提升緩存效率?A:強(qiáng)緩存通過(guò)Cache-Control頭部控制,瀏覽器在請(qǐng)求資源時(shí),若緩存未過(guò)期(根據(jù)max-age或s-maxage判斷),直接使用本地緩存,無(wú)需向服務(wù)器發(fā)送請(qǐng)求。常見(jiàn)指令包括:max-age=3600(緩存1小時(shí))、no-cache(需協(xié)商緩存驗(yàn)證)、no-store(禁用緩存)。協(xié)商緩存用于強(qiáng)緩存失效時(shí)(如緩存過(guò)期),瀏覽器發(fā)送請(qǐng)求到服務(wù)器,攜帶Last-Modified(資源最后修改時(shí)間)或ETag(資源哈希值)頭部,服務(wù)器對(duì)比請(qǐng)求中的值:若一致(資源未修改),返回304NotModified,瀏覽器使用本地緩存;若不一致,返回200OK及新資源。結(jié)合使用時(shí),建議設(shè)置合理的max-age(如1天)作為強(qiáng)緩存,同時(shí)添加ETag或Last-Modified頭部。這樣大部分情況下瀏覽器直接使用強(qiáng)緩存,減少請(qǐng)求;緩存過(guò)期后通過(guò)協(xié)商緩存驗(yàn)證,避免重復(fù)下載未修改的資源。例如,靜態(tài)資源(如圖片、JS、CSS)可設(shè)置較長(zhǎng)的max-age,并通過(guò)文件名哈希(如app.abc123.js)實(shí)現(xiàn)版本控制,修改時(shí)文件名變化,強(qiáng)制加載新資源;動(dòng)態(tài)資源(如用戶(hù)數(shù)據(jù))可設(shè)置較短的max-age或no-cache,依賴(lài)協(xié)商緩存保證數(shù)據(jù)新鮮度。Q:Vue3中組合式API(Composables)與選項(xiàng)式API(OptionsAPI)的主要區(qū)別是什么?使用組合式API有哪些優(yōu)勢(shì)?A:選項(xiàng)式API通過(guò)data、methods、computed、watch等選項(xiàng)組織代碼,邏輯按類(lèi)型(狀態(tài)、方法、計(jì)算屬性)拆分;組合式API基于setup函數(shù)和自定義組合函數(shù)(如useFetchData),將相關(guān)邏輯(如數(shù)據(jù)獲取、加載狀態(tài)、錯(cuò)誤處理)封裝在一起,按功能拆分。組合式API的優(yōu)勢(shì):1.邏輯復(fù)用更靈活:通過(guò)組合函數(shù)(Composables)提取可復(fù)用邏輯,避免選項(xiàng)式API中mixin的命名沖突和邏輯來(lái)源不清晰問(wèn)題;2.類(lèi)型推導(dǎo)更友好:基于TS的組合式API能更準(zhǔn)確地推導(dǎo)類(lèi)型,提升代碼可維護(hù)性;3.代碼結(jié)構(gòu)更清晰:相關(guān)聯(lián)的邏輯(如數(shù)據(jù)獲取和對(duì)應(yīng)的加載狀態(tài))集中在一個(gè)組合函數(shù)中,減少跨選項(xiàng)查找代碼的成本;4.更好的Tree-shaking支持:組合式API中未使用的邏輯可被打包工具(如Vite/Webpack)移除,減少包體積;5.適應(yīng)復(fù)雜組件:選項(xiàng)式API在處理復(fù)雜組件時(shí),邏輯分散在多個(gè)選項(xiàng)中(如data中的state、methods中的函數(shù)、watch中的監(jiān)聽(tīng)),組合式API通過(guò)邏輯分組降低復(fù)雜度。Q:如何設(shè)計(jì)一個(gè)高并發(fā)場(chǎng)景下的用戶(hù)登錄接口?需要考慮哪些安全和性能問(wèn)題?A:高并發(fā)登錄接口的設(shè)計(jì)需從以下維度考慮:安全層面:身份驗(yàn)證:使用HTTPS防止中間人攻擊,密碼傳輸前前端進(jìn)行哈希(如SHA-256)+鹽值處理(避免明文傳輸);防暴力破解:限制登錄失敗次數(shù)(如5分鐘內(nèi)失敗5次鎖定賬號(hào)),使用圖形驗(yàn)證碼或滑動(dòng)驗(yàn)證(如GoogleReCAPTCHA);會(huì)話(huà)管理:使用JWT(需設(shè)置合理的exp過(guò)期時(shí)間)或Redis存儲(chǔ)會(huì)話(huà)令牌(如UUID),避免JWT被劫持后的長(zhǎng)期有效風(fēng)險(xiǎn);CSRF防護(hù):若使用Cookie存儲(chǔ)令牌,需設(shè)置HttpOnly、SameSite=Strict屬性;敏感信息脫敏:返回給前端的響應(yīng)中不包含密碼、密鑰等敏感數(shù)據(jù)。性能層面:接口限流:使用Nginx或Redis實(shí)現(xiàn)IP級(jí)別的請(qǐng)求限流(如每分鐘100次),防止惡意請(qǐng)求耗盡資源;異步處理:登錄成功后的日志記錄、用戶(hù)狀態(tài)更新等非核心操作,通過(guò)消息隊(duì)列(如RabbitMQ/Kafka)異步處理;緩存優(yōu)化:用戶(hù)信息(如角色、權(quán)限)在登錄后緩存到Redis(設(shè)置合理過(guò)期時(shí)間),減少數(shù)據(jù)庫(kù)查詢(xún)壓力;數(shù)據(jù)庫(kù)優(yōu)化:用戶(hù)表的用戶(hù)名/手機(jī)號(hào)字段添加唯一索引,加速查詢(xún);分庫(kù)分表(若用戶(hù)量超1億),按用戶(hù)ID哈希分庫(kù);負(fù)載均衡:使用Nginx或K8s進(jìn)行流量分發(fā),避免單臺(tái)服務(wù)器過(guò)載。Q:解釋CSS中BFC(塊格式化上下文)的概念,列舉觸發(fā)BFC的常見(jiàn)條件,并說(shuō)明BFC在布局中的實(shí)際應(yīng)用場(chǎng)景。A:BFC(BlockFormattingContext)是Web頁(yè)面中塊級(jí)盒子的布局環(huán)境,內(nèi)部的塊級(jí)元素按垂直方向排列,與外部區(qū)域互不影響。BFC的邊界不會(huì)與浮動(dòng)元素的margin重疊,可視為一個(gè)獨(dú)立的容器。觸發(fā)BFC的常見(jiàn)條件:根元素(html);float值不為none(left/right);overflow值不為visible(hidden/auto/scroll);display為inline-block、table-cell、table-caption、flex、grid;position為absolute或fixed。BFC的實(shí)際應(yīng)用:1.清除浮動(dòng):父元素觸發(fā)BFC后,會(huì)包含內(nèi)部的浮動(dòng)子元素,解決父元素高度塌陷問(wèn)題(如父元素設(shè)置overflow:hidden);2.防止邊距重疊:兩個(gè)相鄰的塊級(jí)元素的margin會(huì)發(fā)生重疊,將其中一個(gè)元素放入BFC容器中,可避免margin合并;3.實(shí)現(xiàn)兩欄/三欄布局:左側(cè)元素浮動(dòng),右側(cè)元素觸發(fā)BFC(如設(shè)置overflow:hidden),右側(cè)內(nèi)容不會(huì)被浮動(dòng)元素覆蓋,而是圍繞其布局;4.隔離內(nèi)容:BFC內(nèi)部的布局不會(huì)影響外部元素,可用于封裝獨(dú)立組件(如彈窗、卡片)的樣式。Q:在Node.js中,如何實(shí)現(xiàn)一個(gè)中間件(Middleware)來(lái)記錄HTTP請(qǐng)求的耗時(shí)、URL、狀態(tài)碼等信息?需要考慮哪些異常情況?A:中間件本質(zhì)是一個(gè)函數(shù),接收req、res、next三個(gè)參數(shù),通過(guò)監(jiān)聽(tīng)res的finish事件或close事件來(lái)記錄日志。實(shí)現(xiàn)步驟如下:1.在中間件中記錄請(qǐng)求開(kāi)始時(shí)間(如process.hrtime());2.監(jiān)聽(tīng)res的'finish'事件(請(qǐng)求正常結(jié)束時(shí)觸發(fā))或'close'事件(客戶(hù)端斷開(kāi)連接時(shí)觸發(fā));3.計(jì)算耗時(shí)(結(jié)束時(shí)間開(kāi)始時(shí)間),獲取req.url、req.method、res.statusCode等信息;4.將日志寫(xiě)入文件或發(fā)送到日志服務(wù)(如ELK)。示例代碼:```javascriptfunctionlogMiddleware(req,res,next){conststartTime=process.hrtime();const{method,url}=req;res.on('finish',()=>{const[seconds,nanoseconds]=process.hrtime(startTime);constduration=seconds1000+nanoseconds/1e6;//轉(zhuǎn)換為毫秒console.log(`[${newDate().toISOString()}]${method}${url}${res.statusCode}${duration.toFixed(2)}ms`);});res.on('close',()=>{if(!res.finished){console.log(`[${newDate().toISOString()}]${method}${url}Clientdisconnected`);}});next();}```需考慮的異常情況:客戶(hù)端在請(qǐng)求過(guò)程中斷開(kāi)連接(觸發(fā)'close'事件但未觸發(fā)'finish'),需記錄斷開(kāi)狀態(tài);中間件順序問(wèn)題:確保日志中間件在路由處理之前注冊(cè),否則可能無(wú)法捕獲到正確的statusCode;錯(cuò)誤處理:若后續(xù)中間件或路由拋出錯(cuò)誤(如未處理的Promise拒絕),需在錯(cuò)誤處理中間件中捕獲并設(shè)置正確的statusCode(如500);大流量下的性能:頻繁的日志寫(xiě)入可能成為瓶頸,可使用異步寫(xiě)入(如fs.createWriteStream)或批量寫(xiě)入(如每100條日志批量提交)。Q:簡(jiǎn)述TCP三次握手和四次揮手的過(guò)程,說(shuō)明TIME_WAIT狀態(tài)的作用及常見(jiàn)優(yōu)化方法。A:三次握手是TCP連接建立的過(guò)程:1.客戶(hù)端發(fā)送SYN包(seq=x),進(jìn)入SYN_SENT狀態(tài);2.服務(wù)器收到后發(fā)送SYN+ACK包(seq=y,ack=x+1),進(jìn)入SYN_RCVD狀態(tài);3.客戶(hù)端發(fā)送ACK包(seq=x+1,ack=y+1),服務(wù)器進(jìn)入ESTABLISHED狀態(tài),連接建立。四次揮手是TCP連接關(guān)閉的過(guò)程:1.客戶(hù)端發(fā)送FIN包(seq=u),進(jìn)入FIN_WAIT_1狀態(tài);2.服務(wù)器發(fā)送ACK包(seq=v,ack=u+1),進(jìn)入CLOSE_WAIT狀態(tài);3.服務(wù)器處理完剩余數(shù)據(jù)后發(fā)送FIN+ACK包(seq=w,ack=u+1),進(jìn)入LAST_ACK狀態(tài);4.客戶(hù)端發(fā)送ACK包(seq=u+1,ack=w+1),進(jìn)入TIME_WAIT狀態(tài),等待2MSL(最大報(bào)文段生存時(shí)間)后關(guān)閉連接。TIME_WAIT狀態(tài)的作用:確保最后一個(gè)ACK包能到達(dá)服務(wù)器(若丟失,服務(wù)器會(huì)重發(fā)FIN包,客戶(hù)端可再次發(fā)送ACK);避免舊連接的報(bào)文段被新連接接收(等待2MSL可讓網(wǎng)絡(luò)中所有舊報(bào)文段過(guò)期)。TIME_WAIT過(guò)多可能導(dǎo)致端口耗盡(客戶(hù)端)或資源占用(服務(wù)器),優(yōu)化方法:服務(wù)器端調(diào)整內(nèi)核參數(shù):增大net.ipv4.tcp_max_tw_buckets(TIME_WAIT數(shù)量限制),啟用net.ipv4.tcp_tw_reuse(允許重用TIME_WAIT連接);客戶(hù)端使用長(zhǎng)連接(HTTPKeep-Alive),減少頻繁的連接建立/關(guān)閉;避免短時(shí)間內(nèi)大量創(chuàng)建/關(guān)閉連接(如壓測(cè)時(shí)控制并發(fā)量)。Q:在React中,如何實(shí)現(xiàn)組件的性能優(yōu)化?請(qǐng)列舉至少5種常見(jiàn)方法并說(shuō)明原理。A:React組件性能優(yōu)化可從減少重新渲染、優(yōu)化渲染邏輯、降低計(jì)算復(fù)雜度等方面入手:1.使用React.memo包裹函數(shù)組件:默認(rèn)淺比較props的前后值,若props未變化則跳過(guò)渲染。適用于純組件(相同props輸出相同UI),需注意props包含對(duì)象/數(shù)組時(shí),可能因引用變化導(dǎo)致失效(可配合useMemo/useCallback優(yōu)化)。2.shouldComponentUpdate(類(lèi)組件)或useMemo/useCallback(函數(shù)組件):類(lèi)組件中通過(guò)shouldComponentUpdate返回false阻止更新;函數(shù)組件中useMemo緩存計(jì)算結(jié)果,useCallback緩存函數(shù)引用,避免子組件因父組件函數(shù)重新提供而不必要渲染。3.虛擬列表(VirtualizedList):僅渲染視口內(nèi)的可見(jiàn)項(xiàng),通過(guò)計(jì)算滾動(dòng)位置動(dòng)態(tài)更新渲染項(xiàng),減少DOM節(jié)點(diǎn)數(shù)量(如使用react-window庫(kù))。4.代碼分割(CodeSplitting):通過(guò)React.lazy和import()動(dòng)態(tài)加載組件,結(jié)合Suspense設(shè)置加載占位符,減少首屏加載時(shí)間(如將非首屏組件延遲加載)。5.避免在渲染過(guò)程中執(zhí)行高計(jì)算量操作:將復(fù)雜計(jì)算移至useMemo中緩存,或通過(guò)useEffect在依賴(lài)變化時(shí)計(jì)算,避免每次渲染都重新計(jì)算(如列表排序、數(shù)據(jù)過(guò)濾)。6.使用useRef替代useState存儲(chǔ)非響應(yīng)式數(shù)據(jù):若數(shù)據(jù)僅用于DOM操作或內(nèi)部狀態(tài)(如定時(shí)器ID),無(wú)需觸發(fā)重新渲染,使用useRef存儲(chǔ)可減少不必要的渲染。Q:MySQL中事務(wù)的ACID特性分別指什么?如何通過(guò)隔離級(jí)別解決臟讀、不可重復(fù)讀、幻讀問(wèn)題?A:ACID是事務(wù)的四個(gè)基本特性:原子性(Atomicity):事務(wù)中的操作要么全部完成,要么全部回滾;一致性(Consistency):事務(wù)執(zhí)行前后數(shù)據(jù)庫(kù)狀態(tài)保持一致(如轉(zhuǎn)賬后總金額不變);隔離性(Isolation):多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),彼此互不干擾;持久性(Durability):事務(wù)提交后,修改永久保存到數(shù)據(jù)庫(kù)。隔離級(jí)別通過(guò)控制事務(wù)間的可見(jiàn)性來(lái)解決并發(fā)問(wèn)題,MySQL默認(rèn)隔離級(jí)別為可重復(fù)讀(REPEATABLEREAD):讀未提交(READUNCOMMITTED):允許事務(wù)讀取其他事務(wù)未提交的修改,會(huì)導(dǎo)致臟讀(讀取到未提交的臨時(shí)數(shù)據(jù));讀已提交(READCOMMITTED):僅讀取已提交的數(shù)據(jù),解決臟讀,但可能出現(xiàn)不可重復(fù)讀(同一事務(wù)內(nèi)兩次查詢(xún)結(jié)果不同);可重復(fù)讀(REPEATABLEREAD):同一事務(wù)內(nèi)多次查詢(xún)結(jié)果一致,解決不可重復(fù)讀,但可能出現(xiàn)幻讀(查詢(xún)范圍時(shí),其他事務(wù)插入新數(shù)據(jù)導(dǎo)致結(jié)果集變化);串行化(SERIALIZABLE):事務(wù)串行執(zhí)行,解決所有并發(fā)問(wèn)題,但性能最差。MySQL通過(guò)MVCC(多版本并發(fā)控制)在可重復(fù)讀級(jí)別下避免幻讀:查詢(xún)時(shí)讀取事務(wù)開(kāi)始時(shí)的歷史版本,其他事務(wù)的插入操作不影響當(dāng)前事務(wù)的查詢(xún)結(jié)果。對(duì)于需要嚴(yán)格避免幻讀的場(chǎng)景(如庫(kù)存扣減),可使用SELECT...FORUPDATE加行鎖或表鎖。Q:如何解決前端跨域問(wèn)題?請(qǐng)列舉至少4種方案并說(shuō)明適用場(chǎng)景。A:跨域是瀏覽器同源策略(協(xié)議、域名、端口相同)限制的結(jié)果,常見(jiàn)解決方案:1.CORS(跨域資源共享):服務(wù)器端設(shè)置響應(yīng)頭Access-Control-Allow-Origin(允許的源)、Access-Control-Allow-Methods(允許的方法)、Access-Control-Allow-Headers(允許的請(qǐng)求頭)。適用于前后端分離項(xiàng)目(如React/Vue調(diào)用Node.js/Java后端),需后端配合設(shè)置。2.JSONP(JSONwithPadding):利用script標(biāo)簽無(wú)同源限制的特性,前端定義回調(diào)函數(shù),后端返回包裹在函數(shù)調(diào)用中的JSON數(shù)據(jù)。僅支持GET請(qǐng)求,適用于兼容舊瀏覽器或簡(jiǎn)單數(shù)據(jù)獲取場(chǎng)景(如獲取第三方公開(kāi)API數(shù)據(jù))。3.Nginx反向代理:前端請(qǐng)求發(fā)送到同域的Nginx服務(wù)器,Nginx配置代理規(guī)則將請(qǐng)求轉(zhuǎn)發(fā)到目標(biāo)后端服務(wù)器。適用于生產(chǎn)環(huán)境,避免前端直接處理跨域,同時(shí)可利用Nginx的負(fù)載均衡、緩存等功能。4.WebSocket:WebSocket協(xié)議(ws/wss)不受同源策略限制,通過(guò)建立長(zhǎng)連接實(shí)現(xiàn)雙向通信。適用于實(shí)時(shí)通信場(chǎng)景(如聊天、監(jiān)控),需后端支持WebSocket協(xié)議(如使用Socket.io)。5.postMessage(窗口間通信):適用于同瀏覽器不同窗口(如主頁(yè)面與iframe)之間的通信,通過(guò)window.postMessage發(fā)送數(shù)據(jù),目標(biāo)窗口監(jiān)聽(tīng)message事件接收。6.服務(wù)端中間件代理:前端開(kāi)發(fā)時(shí)使用Webpack-dev-server或Vite的代理配置(如vite.config.js中的proxy選項(xiàng)),將本地請(qǐng)求代理到后端服務(wù)器,解決開(kāi)發(fā)環(huán)境跨域。Q:在Node.js中,如何正確使用async/await處理多個(gè)異步操作?對(duì)比Promise.all()、Promise.race()、Promise.allSettled()的適用場(chǎng)景。A:async/await通過(guò)將異步代碼寫(xiě)成同步風(fēng)格,提升可讀性。處理多個(gè)異步操作時(shí),需根據(jù)需求選擇并行或串行執(zhí)行:串行執(zhí)行:依次執(zhí)行每個(gè)異步操作,前一個(gè)完成后再執(zhí)行下一個(gè)(適用于依賴(lài)前一個(gè)結(jié)果的場(chǎng)景):```javascriptasyncfunctionserial(){constres1=awaitfetch('/api1');constres2=awaitfetch('/api2');//依賴(lài)res1的結(jié)果return[res1,res2];}```并行執(zhí)行:同時(shí)啟動(dòng)所有異步操作,等待全部完成(適用于無(wú)依賴(lài)關(guān)系的場(chǎng)景):```javascriptasyncfunctionparallel(){const[res1,res2]=awaitPromise.all([fetch('/api1'),fetch('/api2')]);return[res1,res2];}```Promise.all()、Promise.race()、Promise.allSettled()的區(qū)別:Promise.all():等待所有Promise完成,若其中一個(gè)reject,立即拋出錯(cuò)誤(適合需要所有結(jié)果的場(chǎng)景,如批量請(qǐng)求數(shù)據(jù));Promise.race():返回第一個(gè)完成(resolve或reject)的Promise(適合超時(shí)控制,如設(shè)置請(qǐng)求超時(shí):Promise.race([fetch(url),timeout(5000)]));Promise.allSettled():等待所有Promise完成(無(wú)論成功或失?。?,返回包含每個(gè)結(jié)果狀態(tài)({status:'fulfilled',value}或{status:'rejected',reason})的數(shù)組(適合需要統(tǒng)計(jì)所有操作結(jié)果的場(chǎng)景,如批量上傳文件,需知道哪些成功、哪些失敗)。Q:CSS中Flex布局的常用屬性有哪些?如何實(shí)現(xiàn)一個(gè)水平垂直居中的容器?A:Flex布局通過(guò)設(shè)置父容器為display:flex或display:inline-flex,子元素成為Flex項(xiàng)。常用屬性分為容器屬性和項(xiàng)屬性:容器屬性:flex-direction:決定主軸方向(row/row-reverse/column/column-reverse);flex-wrap:控制換行(nowrap/wrap/wrap-reverse);justify-content:主軸對(duì)齊方式(flex-start/flex-end/center/space-between/space-around);align-items:交叉軸對(duì)齊方式(flex-start/flex-end/center/stretch/baseline);align-content:多根軸線(xiàn)對(duì)齊方式(僅當(dāng)flex-wrap=wrap時(shí)有意義)。項(xiàng)屬性:flex:flex-grow(放大比例)、flex-shrink(縮小比例)、flex-basis(基準(zhǔn)長(zhǎng)度)的簡(jiǎn)寫(xiě)(如flex:1等價(jià)于flex:110);order:調(diào)整項(xiàng)的排列順序(數(shù)值越小越靠前);align-self:覆蓋容器的align-items,單獨(dú)設(shè)置交叉軸對(duì)齊方式。實(shí)現(xiàn)水平垂直居中的容器(子元素居中):```css.container{display:flex;justify-content:center;/水平居中(主軸為row時(shí))/align-items:center;/垂直居中(交叉軸為column時(shí))/width:100%;height:100vh;/假設(shè)容器占滿(mǎn)視口高度/}.container.child{/子元素內(nèi)容/}```若主軸為column(垂直方向),則justify-content控制垂直對(duì)齊,align-items控制水平對(duì)齊。Q:簡(jiǎn)述JWT(JSONWebToken)的結(jié)構(gòu)和工作流程,說(shuō)明其與Session認(rèn)證的區(qū)別及適用場(chǎng)景。A:JWT由三部分組成,用點(diǎn)(.)分隔:頭部(Header):包含令牌類(lèi)型(如JWT)和算法(如HS256),Base64Url編碼;有效載荷(Payload):包含聲明(如用戶(hù)ID、過(guò)期時(shí)間exp),Base64Url編碼(非加密,勿存放敏感信息);簽名(Signature):使用頭部指定的算法,對(duì)前兩部分?jǐn)?shù)據(jù)和密鑰進(jìn)行簽名,防止數(shù)據(jù)篡改。工作流程:1.用戶(hù)登錄成功,服務(wù)器提供JWT并返回給客戶(hù)端;2.客戶(hù)端后續(xù)請(qǐng)求在請(qǐng)求頭(如Authorization:Bearer<token>)中攜帶JWT;3.服務(wù)器驗(yàn)證JWT簽名有效性,解析有效載荷獲取用戶(hù)信息;4.若JWT過(guò)期(exp超時(shí))或簽名無(wú)效,返回401Unauthorized。與Session認(rèn)證的區(qū)別:存儲(chǔ)位置:Session數(shù)據(jù)存儲(chǔ)在服務(wù)器(如Redis),JWT存儲(chǔ)在客戶(hù)端(如localStorage/cookie);無(wú)狀態(tài):JWT無(wú)需查詢(xún)服務(wù)器存儲(chǔ)的Session,服務(wù)器通過(guò)簽名驗(yàn)證即可,適合分布式系統(tǒng);安全性:JWT一旦泄露,可被冒用(需設(shè)置短過(guò)期時(shí)間,配合RefreshToken刷新);Session需防止Session劫持(如使用HTTPS、設(shè)置HttpOnlyCookie);擴(kuò)展性:JWT可包含用戶(hù)角色、權(quán)限等信息,減少服務(wù)器查詢(xún)數(shù)據(jù)庫(kù)次數(shù);Session需每次查詢(xún)服務(wù)器獲取用戶(hù)信息。適用場(chǎng)景:JWT適合前后端分離、分布式系統(tǒng)(如微服務(wù))、移動(dòng)應(yīng)用(無(wú)Cookie支持);Session適合傳統(tǒng)Web應(yīng)用(依賴(lài)Cookie)、需要頻繁更新用戶(hù)狀態(tài)的場(chǎng)景(如購(gòu)物車(chē)實(shí)時(shí)更新)。Q:如何優(yōu)化Web應(yīng)用的首屏加載時(shí)間?請(qǐng)從前端和后端兩個(gè)角度列舉具體措施。A:首屏加載時(shí)間(FCP)是用戶(hù)體驗(yàn)的關(guān)鍵指標(biāo),優(yōu)化需前后端協(xié)同:前端優(yōu)化措施:資源壓縮與合并:JS/CSS使用Terser/PostCSS壓縮,圖片使用WebP/AVIF格式(比JPEG小25%-50%),雪碧圖合并小圖標(biāo);代碼分割與懶加載:使用React.lazy/Vue異步組件拆分非首屏代碼,路由級(jí)分割(如將管理端路由單獨(dú)打包);預(yù)加載與預(yù)渲染:通過(guò)<linkrel="preload">預(yù)加載關(guān)鍵資源,<linkrel="prerender">預(yù)渲染重要頁(yè)面;減少關(guān)鍵渲染路徑(CRP):內(nèi)聯(lián)首屏所需的CSS(避免外部CSS阻塞渲染),使用媒體查詢(xún)將非首屏CSS標(biāo)記為print(不阻塞渲染);使用CDN加速:將靜態(tài)資源(JS、CSS、圖片)部署到CDN,利用邊緣節(jié)點(diǎn)降低訪問(wèn)延遲;緩存策略:設(shè)置Cache-Control頭部,對(duì)靜態(tài)資源添加長(zhǎng)緩存(如一年),通過(guò)文件名哈希實(shí)現(xiàn)版本更新。后端優(yōu)化措施:服務(wù)端渲染(SSR)或靜態(tài)站點(diǎn)提供(SSG):SSR在服務(wù)器端提供HTML,直接返回首屏內(nèi)容,減少客戶(hù)端JS執(zhí)行時(shí)間(如Next.js/Nuxt.js);SSG預(yù)提供靜態(tài)HTML(如Gatsby),適合內(nèi)容固定的頁(yè)面;接口優(yōu)化:合并首屏所需的多個(gè)接口(如通過(guò)GraphQL一次性獲取所有數(shù)據(jù)),減少HTTP請(qǐng)求次數(shù);開(kāi)啟Gzip/Brotli壓縮:服務(wù)器對(duì)返回的HTML/JS/CSS啟用壓縮(如Nginx設(shè)置gzipon),減少傳輸體積;數(shù)據(jù)庫(kù)查詢(xún)優(yōu)化:首屏數(shù)據(jù)查詢(xún)添加索引,使用緩存(如Redis)存儲(chǔ)高頻數(shù)據(jù),避免慢查詢(xún)阻塞接口響應(yīng);負(fù)載均衡與CDN回源優(yōu)化:通過(guò)負(fù)載均衡器(如Nginx)分散流

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論