典問(wèn)題深度解析與實(shí)戰(zhàn)排查指南)
1. 面試官視角為什么這十個(gè)問(wèn)題經(jīng)久不衰在技術(shù)面試的戰(zhàn)場(chǎng)上Linux 問(wèn)題就像一道繞不開(kāi)的“家常菜”。無(wú)論你是應(yīng)聘后端開(kāi)發(fā)、運(yùn)維、SRE、還是嵌入式工程師面試官總會(huì)在某個(gè)環(huán)節(jié)看似隨意地拋出一兩個(gè) Linux 命令或概念。很多人覺(jué)得不就是幾個(gè)命令嗎背一背就好了。但根據(jù)我這些年面試別人和被面試的經(jīng)驗(yàn)來(lái)看面試官問(wèn)這些問(wèn)題絕不僅僅是想聽(tīng)你復(fù)述命令手冊(cè)。他們真正想考察的是你對(duì)操作系統(tǒng)底層邏輯的理解、問(wèn)題排查的系統(tǒng)性思維以及將理論知識(shí)應(yīng)用于實(shí)際生產(chǎn)環(huán)境的能力。這十個(gè)被問(wèn)得最多的問(wèn)題之所以能成為“經(jīng)典”是因?yàn)樗鼈兿褚话寻谚€匙能打開(kāi)通往不同技術(shù)深度的門(mén)。從最基礎(chǔ)的“如何查看進(jìn)程”到復(fù)雜的“系統(tǒng)負(fù)載高如何排查”每一個(gè)問(wèn)題背后都串聯(lián)著文件系統(tǒng)、進(jìn)程管理、內(nèi)存管理、網(wǎng)絡(luò)等核心子系統(tǒng)。面試官通過(guò)你的回答能快速判斷出你是一個(gè)只會(huì)敲命令的“腳本小子”還是一個(gè)能理解系統(tǒng)行為、能獨(dú)立解決問(wèn)題的工程師。比如問(wèn)top和htop的區(qū)別表面是工具對(duì)比實(shí)則可能是在考察你對(duì)進(jìn)程狀態(tài)S、R、D、Z等的理解以及你是否有關(guān)注用戶(hù)體驗(yàn)和效率的工具意識(shí)。所以在準(zhǔn)備這些問(wèn)題時(shí)我們的目標(biāo)不是死記硬背十個(gè)答案而是構(gòu)建一個(gè)以這些問(wèn)題為線(xiàn)索的知識(shí)網(wǎng)絡(luò)。接下來(lái)我將結(jié)合最常見(jiàn)的面試場(chǎng)景和踩坑經(jīng)驗(yàn)為你逐一拆解這十個(gè)問(wèn)題告訴你面試官期待的“標(biāo)準(zhǔn)答案”是什么以及如何通過(guò)回答展現(xiàn)你的技術(shù)深度和廣度。2. 問(wèn)題一如何查看當(dāng)前系統(tǒng)有哪些進(jìn)程除了ps和top你還知道哪些方法這通常是 Linux 面試的開(kāi)胃菜但答得好能立刻建立良好的第一印象。大多數(shù)候選人會(huì)脫口而出ps aux或top。這沒(méi)錯(cuò)但如果你只說(shuō)到這里就只是及格水平。2.1 基礎(chǔ)命令的深度解讀首先我們得把ps和top吃透。ps aux這是靜態(tài)快照。關(guān)鍵在于理解每一列的含義。USER,PID,%CPU,%MEM這些都好說(shuō)但STAT進(jìn)程狀態(tài)和COMMAND才是容易出彩的點(diǎn)。你能解釋S睡眠、R運(yùn)行、D不可中斷睡眠、Z僵尸分別對(duì)應(yīng)什么場(chǎng)景嗎比如D狀態(tài)通常發(fā)生在進(jìn)程等待 I/O如磁盤(pán)讀寫(xiě)時(shí)此時(shí)進(jìn)程不響應(yīng)任何信號(hào)這是排查系統(tǒng)無(wú)響應(yīng)時(shí)的一個(gè)重要線(xiàn)索。top這是動(dòng)態(tài)視圖。除了看排序更要關(guān)注頂部匯總區(qū)的信息load average1, 5, 15分鐘的平均負(fù)載、Tasks各種狀態(tài)進(jìn)程數(shù)、%Cpu(s)用戶(hù)態(tài)、內(nèi)核態(tài)、等待IO等時(shí)間的占比。面試官可能會(huì)追問(wèn)“平均負(fù)載達(dá)到多少算高” 標(biāo)準(zhǔn)答案是如果負(fù)載數(shù)持續(xù)高于 CPU 核心數(shù)就需要警惕了。但更專(zhuān)業(yè)的回答是需要結(jié)合%Cpu(s)中waI/O等待的數(shù)值來(lái)看如果負(fù)載高且wa也高很可能是磁盤(pán)瓶頸。2.2 進(jìn)階工具與場(chǎng)景化回答這才是展現(xiàn)你經(jīng)驗(yàn)的地方。你可以這樣補(bǔ)充 “除了ps和top根據(jù)不同的排查場(chǎng)景我還會(huì)用一些其他工具h(yuǎn)top這是top的增強(qiáng)版支持鼠標(biāo)操作、樹(shù)狀視圖查看進(jìn)程父子關(guān)系、更直觀的顏色標(biāo)識(shí)。在需要快速定位某個(gè)進(jìn)程家族時(shí)非常有用。pgrep和pkill用于根據(jù)進(jìn)程名或其他屬性精確查找或發(fā)送信號(hào)。比如pgrep -f java查找所有包含 ‘java’ 字符串的進(jìn)程比ps aux | grep java更簡(jiǎn)潔且避免 grep 進(jìn)程自身干擾。直接查看/proc文件系統(tǒng)這是最底層的方法。每個(gè)進(jìn)程在/proc下都有一個(gè)以其 PID 命名的目錄如/proc/1234。里面的status、cmdline、io等文件包含了進(jìn)程的詳細(xì)信息。例如cat /proc/1234/status可以查看進(jìn)程的詳細(xì)狀態(tài)、內(nèi)存映射等。這能體現(xiàn)你對(duì) Linux 內(nèi)核抽象的理解——‘一切皆文件’。系統(tǒng)化工具如systemctl status用于查看 systemd 管理的服務(wù)進(jìn)程狀態(tài)docker ps/kubectl get pods用于容器化環(huán)境?!?.3 一個(gè)常見(jiàn)的坑ps aux | grep process_name的陷阱這里可以分享一個(gè)實(shí)操心得當(dāng)你用ps aux | grep java時(shí)輸出結(jié)果里往往會(huì)包含grep java這個(gè)進(jìn)程本身干擾判斷。老手通常會(huì)這樣處理ps aux | grep [j]ava。因?yàn)間rep [j]ava匹配的是包含 ‘[j]ava’ 字符串的行而ps aux輸出的命令行是 ‘grep [j]ava’并不包含 ‘java’這樣就巧妙地過(guò)濾掉了 grep 進(jìn)程自身。這個(gè)小技巧能立刻讓面試官覺(jué)得你有實(shí)戰(zhàn)經(jīng)驗(yàn)。3. 問(wèn)題二如何查看一個(gè)文件的末尾或?qū)崟r(shí)增長(zhǎng)的內(nèi)容這個(gè)問(wèn)題考察你對(duì)文本處理工具鏈的熟悉程度。tail命令是核心但同樣有深淺之分。3.1tail命令的核心參數(shù)tail -f filename這是經(jīng)典答案實(shí)時(shí)跟蹤文件末尾的新增內(nèi)容。常用于監(jiān)控日志文件。tail -n number filename查看文件最后 number 行。例如tail -n 100 app.log看最后100行。tail -F filename這是-f的增強(qiáng)版。它不僅能跟蹤文件內(nèi)容增長(zhǎng)還能在文件被輪轉(zhuǎn)rotate或刪除重建后自動(dòng)重新打開(kāi)文件。這是生產(chǎn)環(huán)境監(jiān)控日志的必備選項(xiàng)因?yàn)槿罩疚募?jīng)常會(huì)被 logrotate 切割。如果你只答了-f面試官可能會(huì)追問(wèn)“如果日志文件被切割了你的tail -f會(huì)怎樣” 答案是它會(huì)繼續(xù)跟蹤已經(jīng)被重命名的舊文件看不到新日志了。而-F解決了這個(gè)問(wèn)題。3.2 組合技與高級(jí)用法單獨(dú)說(shuō)tail還不夠結(jié)合其他命令才能解決復(fù)雜問(wèn)題tail -f | grep實(shí)時(shí)監(jiān)控并過(guò)濾關(guān)鍵字。例如tail -F application.log | grep -i error實(shí)時(shí)抓取錯(cuò)誤日志。這里要注意管道緩沖可以使用grep --line-buffered選項(xiàng)來(lái)強(qiáng)制行緩沖確保實(shí)時(shí)性。less命令的實(shí)時(shí)查看在less打開(kāi)文件后按ShiftF可以進(jìn)入類(lèi)似tail -f的跟隨模式同時(shí)還能利用less的搜索、翻頁(yè)功能非常強(qiáng)大。查看大文件頭部和尾部head -n 20 file tail -n 30 file可以快速查看文件的“一頭一尾”。multitail工具這是一個(gè)高級(jí)工具可以同時(shí)監(jiān)控多個(gè)文件的尾部并且支持顏色高亮、過(guò)濾等是運(yùn)維人員的神器。提到這個(gè)工具能表明你的工具鏈很豐富。3.3 實(shí)戰(zhàn)場(chǎng)景日志排查的完整思路你可以借此機(jī)會(huì)展示排查思路“比如線(xiàn)上服務(wù)報(bào)錯(cuò)我通常會(huì)這樣做首先用tail -F -n 500 app.log查看最近的日志定位錯(cuò)誤發(fā)生的時(shí)間點(diǎn)。然后如果錯(cuò)誤是周期性的我可能會(huì)用grep -n ‘Error’ app.log | tail -20找到最近20次錯(cuò)誤發(fā)生的行號(hào)。接著用sed -n ‘行號(hào)-10,行號(hào)10p’ app.log查看錯(cuò)誤上下文。對(duì)于持續(xù)增長(zhǎng)的日志結(jié)合awk進(jìn)行實(shí)時(shí)統(tǒng)計(jì)比如tail -F app.log | awk ‘/ERROR/ {count} END {print count}’當(dāng)然這個(gè) END 塊在持續(xù)流中不會(huì)執(zhí)行需要調(diào)整。”4. 問(wèn)題三如何查找一個(gè)特定的文件或目錄find命令是文件查找的瑞士軍刀但它的參數(shù)繁多容易記混。面試官希望聽(tīng)到你不僅知道命令還知道如何高效使用。4.1find命令的語(yǔ)法骨架基本語(yǔ)法find 路徑 表達(dá)式-name按文件名查找支持通配符*,?,[]。例如find /home -name “*.log”。-type按類(lèi)型查找f普通文件d目錄l符號(hào)鏈接等。find . -type d -name “target”查找名為 target 的目錄。-mtime/-atime/-ctime按修改/訪(fǎng)問(wèn)/狀態(tài)改變時(shí)間查找。-mtime 7表示7天前修改的-mtime -1表示1天內(nèi)修改的。這里是個(gè)易錯(cuò)點(diǎn)n表示大于 n 天-n表示小于 n 天沒(méi)有符號(hào)表示正好 n 天。-size按文件大小查找。-size 10M表示大于10MB-size -1G表示小于1GB。-exec/-ok對(duì)查找到的文件執(zhí)行命令。這是find命令威力最大的地方。4.2 高級(jí)用法與性能考量組合條件-a(and默認(rèn))-o(or)!(not)。例如查找當(dāng)前目錄下不是目錄且以.txt結(jié)尾的文件find . ! -type d -name “*.txt”。-exec的妙用與陷阱標(biāo)準(zhǔn)形式find . -name “*.tmp” -exec rm {} \;。{}是占位符\;是命令結(jié)束符。與\;的區(qū)別這是高頻考點(diǎn)。\;會(huì)對(duì)每個(gè)找到的文件執(zhí)行一次命令而會(huì)將所有找到的文件一次性傳遞給命令。例如find . -name “*.txt” -exec cat {} 會(huì)比-exec cat {} \;高效得多因?yàn)楹笳邥?huì)為每個(gè)文件啟動(dòng)一次cat進(jìn)程。但rm命令通常用\;因?yàn)閞m本身支持多個(gè)參數(shù)用也可以find . -name “*.tmp” -exec rm {} 。使用xargs作為替代find . -name “*.log” | xargs ls -lh。xargs解決了參數(shù)列表過(guò)長(zhǎng)的問(wèn)題并且通常比-exec更高效。但要注意處理文件名中的空格等特殊字符更安全的寫(xiě)法是find . -name “*.log” -print0 | xargs -0 ls -lh。查找內(nèi)容的grep與查找文件區(qū)分開(kāi)。grep -r “pattern” /path遞歸查找文件內(nèi)容。-r遞歸-n顯示行號(hào)-i忽略大小寫(xiě)-l只顯示包含匹配項(xiàng)的文件名。4.3 避坑指南權(quán)限與搜索路徑在權(quán)限受限的目錄使用find可能會(huì)遇到很多 “Permission denied” 錯(cuò)誤干擾輸出。可以使用2/dev/null重定向錯(cuò)誤信息find / -type f -name “something” 2/dev/null。但要注意這也會(huì)隱藏真正的錯(cuò)誤。避免在根目錄/下進(jìn)行全盤(pán)無(wú)限制查找這非常消耗 I/O。盡量縮小路徑范圍。5. 問(wèn)題四如何查看磁盤(pán)使用情況和剩余空間磁盤(pán)空間問(wèn)題是線(xiàn)上故障的常見(jiàn)原因之一?;卮疬@個(gè)問(wèn)題要從整體到局部從靜態(tài)到動(dòng)態(tài)。5.1 基礎(chǔ)命令df與dudf -h查看文件系統(tǒng)級(jí)別的磁盤(pán)使用情況。-h參數(shù)使輸出人類(lèi)可讀以 K, M, G 為單位。關(guān)鍵列Filesystem設(shè)備Size總大小Used已用Avail可用Use%使用率Mounted on掛載點(diǎn)。面試官可能會(huì)問(wèn)“/dev/sda1使用率 95% 了怎么辦” 這引出了下一個(gè)命令。du -sh 目錄查看具體目錄的磁盤(pán)使用情況。-s匯總-h人類(lèi)可讀。例如du -sh /var/log查看日志目錄總大小。要找出大文件常用du -h --max-depth1 /path | sort -hr逐層深入。5.2 進(jìn)階分析與排查思路知道命令只是第一步面試官更想聽(tīng)你的排查思路定位問(wèn)題分區(qū)首先用df -h找到使用率異常如 80%的掛載點(diǎn)。定位大目錄進(jìn)入該掛載點(diǎn)用du -sh * | sort -hr查看哪個(gè)目錄最大。定位具體文件進(jìn)入大目錄重復(fù)du和sort命令層層遞進(jìn)。也可以使用find命令直接找大文件find /path -type f -size 100M -exec ls -lh {} \;。分析文件類(lèi)型是日志文件緩存文件還是用戶(hù)上傳的文件這決定了處理方式。動(dòng)態(tài)監(jiān)控df和du是靜態(tài)的。對(duì)于空間增長(zhǎng)過(guò)快的問(wèn)題可能需要?jiǎng)討B(tài)監(jiān)控??梢杂脀atch -n 5 df -h每5秒刷新一次或者用ncdu一個(gè)交互式的磁盤(pán)使用分析器進(jìn)行更直觀的分析。5.3 特殊文件系統(tǒng)與inode問(wèn)題這里有一個(gè)高級(jí)考點(diǎn)磁盤(pán)空間未滿(mǎn)但系統(tǒng)報(bào) “No space left on device”。這很可能是inode用盡了。df -i查看inode的使用情況。每個(gè)文件包括目錄、設(shè)備文件等都會(huì)消耗一個(gè)inode。如果創(chuàng)建了大量小文件例如郵件隊(duì)列、Docker 容器日志、臨時(shí)文件就可能耗盡inode。排查inode耗盡的方法和排查空間用盡類(lèi)似但用的是find命令的-xdev參數(shù)防止跨文件系統(tǒng)并結(jié)合統(tǒng)計(jì)文件數(shù)量find /mount-point -xdev -type f | wc -l或者用find . -printf “%h\n” | sort | uniq -c | sort -rn來(lái)統(tǒng)計(jì)哪個(gè)目錄包含的文件數(shù)最多。6. 問(wèn)題五如何查看系統(tǒng)的內(nèi)存使用情況內(nèi)存問(wèn)題比磁盤(pán)問(wèn)題更復(fù)雜因?yàn)樗婕拔锢韮?nèi)存、交換分區(qū)、緩存和緩沖區(qū)。free命令是入口但理解其輸出是關(guān)鍵。6.1 解讀free -h的輸出total used free shared buff/cache available Mem: 7.6G 2.1G 1.2G 345M 4.3G 4.9G Swap: 2.0G 0B 2.0Gtotal總物理內(nèi)存。used已使用的內(nèi)存。注意這個(gè)值包含了buff/cache。所以直接看這個(gè)值判斷內(nèi)存是否緊張是不準(zhǔn)確的。free完全未被使用的內(nèi)存。這個(gè)值通常很小因?yàn)?Linux 會(huì)充分利用空閑內(nèi)存做緩存。buff/cache緩存和緩沖區(qū)使用的內(nèi)存。這部分內(nèi)存在應(yīng)用程序需要時(shí)可以被快速回收。所以它不是被浪費(fèi)的內(nèi)存。available這是最重要的指標(biāo)。它表示系統(tǒng)估計(jì)的、可供啟動(dòng)新應(yīng)用程序而無(wú)需交換的內(nèi)存大小。它包含了free內(nèi)存和可回收的緩存/緩沖區(qū)。如果available內(nèi)存很小系統(tǒng)就真的面臨內(nèi)存壓力了。Swap交換分區(qū)使用情況。如果used持續(xù)增長(zhǎng)說(shuō)明物理內(nèi)存不足系統(tǒng)開(kāi)始頻繁使用硬盤(pán)交換性能會(huì)急劇下降。6.2 更詳細(xì)的視圖top與/proc/meminfotop命令在top界面中看頭部匯總行有KiB Mem和KiB Swap信息與free類(lèi)似。更重要的是看每個(gè)進(jìn)程的%MEM和RES常駐內(nèi)存列找出內(nèi)存消耗大戶(hù)。/proc/meminfo這是最詳細(xì)的內(nèi)存信息源。free和top的數(shù)據(jù)都來(lái)源于此。面試時(shí)可以說(shuō)“如果想看最原始最全的數(shù)據(jù)我會(huì)直接cat /proc/meminfo比如里面的MemTotal,MemFree,Buffers,Cached,SwapCached,Active(file),Inactive(file)等字段能更細(xì)致地分析內(nèi)存使用構(gòu)成?!?.3 排查內(nèi)存泄漏的思路如果available持續(xù)降低Swap開(kāi)始使用就需要排查用top或ps aux --sort-%mem按內(nèi)存使用率排序找到嫌疑進(jìn)程。分析進(jìn)程詳情對(duì)于 Java 應(yīng)用可以用jmap,jstat對(duì)于其他進(jìn)程可以用pmap -x PID查看進(jìn)程的內(nèi)存映射或者cat /proc/PID/smaps查看更詳細(xì)的內(nèi)存段信息。監(jiān)控趨勢(shì)使用vmstat 5每5秒采樣一次關(guān)注siswap in和soswap out列如果非零且持續(xù)說(shuō)明正在發(fā)生交換。sar -r 5命令也能提供歷史內(nèi)存使用數(shù)據(jù)。7. 問(wèn)題六如何查看網(wǎng)絡(luò)連接和端口監(jiān)聽(tīng)狀態(tài)網(wǎng)絡(luò)問(wèn)題是分布式系統(tǒng)的生命線(xiàn)。netstat和ss是核心命令但后者正在成為新的標(biāo)準(zhǔn)。7.1netstat與它的繼任者ssnetstat -tunlp經(jīng)典組合。-tTCP 連接-uUDP 連接-n以數(shù)字形式顯示地址和端口不進(jìn)行域名解析更快-l僅顯示監(jiān)聽(tīng)LISTEN狀態(tài)的套接字-p顯示進(jìn)程ID和程序名需要 sudo 權(quán)限ss -tunlp功能幾乎相同但速度更快顯示的信息更詳細(xì)。ss是iproute2軟件包的一部分旨在取代netstat。在較新的系統(tǒng)上建議優(yōu)先使用ss。7.2 理解輸出關(guān)鍵列以ss -tlnp為例State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 *:22 *:* users:((sshd,pid123,fd3))State套接字狀態(tài)。LISTEN監(jiān)聽(tīng)ESTAB已建立連接TIME-WAITCLOSE-WAIT等。理解 TCP 狀態(tài)機(jī)對(duì)排查網(wǎng)絡(luò)問(wèn)題至關(guān)重要。Recv-Q,Send-Q接收和發(fā)送隊(duì)列的長(zhǎng)度。如果ESTAB連接的Recv-Q或Send-Q持續(xù)有較大數(shù)值可能意味著應(yīng)用處理數(shù)據(jù)過(guò)慢或網(wǎng)絡(luò)擁塞。Local Address:Port本地監(jiān)聽(tīng)的地址和端口。*:22表示監(jiān)聽(tīng)所有網(wǎng)卡的22端口。Peer Address:Port對(duì)端地址和端口。監(jiān)聽(tīng)狀態(tài)下是*:*。7.3 常見(jiàn)排查場(chǎng)景端口占用sudo ss -tlnp | grep :8080查找誰(shuí)在監(jiān)聽(tīng) 8080 端口。連接數(shù)統(tǒng)計(jì)ss -tan | grep ESTAB | wc -l統(tǒng)計(jì)當(dāng)前所有 TCP 連接數(shù)。ss -tan state ESTABLISHED | awk ‘{print $(NF-1)}’ | cut -d: -f1 | sort | uniq -c | sort -rn可以統(tǒng)計(jì)出連接到本機(jī)的各個(gè)客戶(hù)端 IP 的連接數(shù)用于分析是否遭到連接攻擊。查看 TIME-WAIT 連接ss -tan state TIME-WAIT。大量的TIME-WAIT是正常的這是 TCP 四次揮手后的狀態(tài)會(huì)等待 2MSL 后消失。但如果過(guò)多可能需要調(diào)整內(nèi)核參數(shù)net.ipv4.tcp_tw_reuse或net.ipv4.tcp_tw_recycle注意tcp_tw_recycle在 NAT 環(huán)境下有問(wèn)題Linux 4.12 已移除。配合lsoflsof -i :8080也能查看占用端口的進(jìn)程有時(shí)比ss更直觀因?yàn)樗苯恿谐隽嗣蠲陀脩?hù)。8. 問(wèn)題七如何查看系統(tǒng)負(fù)載Load Average它代表什么系統(tǒng)負(fù)載是一個(gè)看似簡(jiǎn)單卻極易誤解的指標(biāo)。uptime或top命令的第一行都會(huì)顯示它load average: 1.05, 0.70, 0.658.1 負(fù)載的定義與計(jì)算系統(tǒng)負(fù)載平均值表示一段時(shí)間內(nèi)處于可運(yùn)行狀態(tài)和不可中斷睡眠狀態(tài)的進(jìn)程的平均數(shù)量??蛇\(yùn)行狀態(tài)就是正在使用 CPU 或等待 CPU 的進(jìn)程不可中斷睡眠狀態(tài)D 狀態(tài)通常是等待磁盤(pán) I/O 的進(jìn)程。 三個(gè)數(shù)字分別代表過(guò)去 1 分鐘、5 分鐘、15 分鐘的平均值。它不是CPU 使用率的百分比。8.2 如何解讀負(fù)載值核心原則負(fù)載值與 CPU 核心數(shù)比較。假設(shè)系統(tǒng)有 4 個(gè) CPU 核心。負(fù)載為 4.00意味著平均來(lái)看CPU 剛好被完全利用有4個(gè)進(jìn)程在跑或等CPU。負(fù)載為 8.00意味著平均有 8 個(gè)進(jìn)程在競(jìng)爭(zhēng) 4 個(gè)核心有一半的進(jìn)程在等待。此時(shí)系統(tǒng)已經(jīng)過(guò)載。負(fù)載為 2.00意味著平均有 2 個(gè)活躍進(jìn)程CPU 比較空閑。所以負(fù)載持續(xù)高于 CPU 核心數(shù)就表示系統(tǒng)可能過(guò)載。但要注意趨勢(shì)如果 1 分鐘負(fù)載遠(yuǎn)高于 15 分鐘負(fù)載說(shuō)明可能有突發(fā)的高負(fù)載反之則說(shuō)明高負(fù)載是持續(xù)性的。8.3 負(fù)載高但 CPU 使用率低—— I/O 瓶頸的典型信號(hào)這是面試的經(jīng)典坑。如果top顯示負(fù)載很高比如 10但%Cpu(s)那一行顯示id空閑還有 70%waI/O 等待卻很高比如 25%那么瓶頸很可能在磁盤(pán) I/O。wa高表示 CPU 在等待磁盤(pán) I/O。此時(shí)大量進(jìn)程處于不可中斷睡眠D 狀態(tài)它們被計(jì)入負(fù)載但不消耗 CPU。排查工具使用iostat -x 2查看磁盤(pán)的%util利用率、await平均等待時(shí)間、svctm服務(wù)時(shí)間。如果%util持續(xù)接近 100%await遠(yuǎn)高于svctm說(shuō)明磁盤(pán)已經(jīng)飽和。8.4 負(fù)載低就一定好嗎不一定。負(fù)載長(zhǎng)期為 0可能意味著系統(tǒng)過(guò)于空閑資源未被充分利用。對(duì)于線(xiàn)上服務(wù)負(fù)載維持在核心數(shù)的 0.7 倍左右通常被認(rèn)為是比較理想的狀態(tài)既有一定的冗余應(yīng)對(duì)突發(fā)流量又能充分利用資源。9. 問(wèn)題八如何查看一個(gè)進(jìn)程打開(kāi)了哪些文件或者如何查看哪個(gè)進(jìn)程打開(kāi)了某個(gè)文件這涉及到進(jìn)程與文件系統(tǒng)的交互是排查“文件被占用無(wú)法刪除”或“資源泄漏”問(wèn)題的利器。核心命令是lsoflist open files。9.1lsof的基本用法lsof功能強(qiáng)大參數(shù)也多記住幾個(gè)最常用的lsof -p PID查看指定進(jìn)程打開(kāi)的所有文件包括網(wǎng)絡(luò)套接字、管道、設(shè)備文件等。輸出信息非常詳細(xì)包括文件描述符FD、類(lèi)型、設(shè)備、大小、節(jié)點(diǎn)號(hào)等。lsof 文件名查看哪個(gè)進(jìn)程打開(kāi)了這個(gè)文件。例如刪除文件時(shí)提示Text file busy就可以用lsof /path/to/file找到罪魁禍?zhǔn)?。lsof -i :端口號(hào)查看占用特定端口的進(jìn)程。這是netstat/ss的另一種替代。lsof -u 用戶(hù)名查看指定用戶(hù)打開(kāi)的所有文件。lsof /path/to/directory查看誰(shuí)在使用這個(gè)目錄下的文件。9.2 理解lsof的輸出關(guān)鍵列COMMAND進(jìn)程名。PID進(jìn)程ID。USER進(jìn)程所有者。FD文件描述符。cwd是當(dāng)前工作目錄rtd是根目錄txt是程序代碼mem是內(nèi)存映射文件數(shù)字如3u是真正的文件描述符編號(hào)u表示可讀寫(xiě)。TYPE文件類(lèi)型。REG普通文件DIR目錄CHR字符設(shè)備IPv4網(wǎng)絡(luò)套接字等。DEVICE和SIZE/OFF設(shè)備號(hào)和文件大小/偏移量。NODE文件的 inode 號(hào)。NAME文件的全路徑名。9.3 實(shí)戰(zhàn)排查案例場(chǎng)景無(wú)法卸載/data磁盤(pán)提示device is busy。首先想到lsof可以查誰(shuí)在用這個(gè)設(shè)備上的文件lsof | grep /data。但更精準(zhǔn)的是先用df找到/data對(duì)應(yīng)的設(shè)備名比如/dev/sdb1。然后使用lsof | grep /dev/sdb1。這會(huì)列出所有打開(kāi)了/dev/sdb1上文件的進(jìn)程。找到進(jìn)程后判斷是否可以安全終止或者進(jìn)入該進(jìn)程的工作目錄cwd看看它正在做什么。另一個(gè)技巧fuser命令。fuser -v /data可以更簡(jiǎn)潔地顯示使用/data文件系統(tǒng)的進(jìn)程fuser -km /data可以殺死所有使用該文件系統(tǒng)的進(jìn)程慎用這在強(qiáng)制卸載時(shí)可能用到。10. 問(wèn)題九如何查看系統(tǒng)啟動(dòng)以來(lái)或某個(gè)進(jìn)程的運(yùn)行時(shí)間這個(gè)問(wèn)題考察你對(duì)系統(tǒng)運(yùn)行狀態(tài)和歷史信息的了解。uptime命令是查看系統(tǒng)運(yùn)行時(shí)間的標(biāo)準(zhǔn)答案。10.1 系統(tǒng)運(yùn)行時(shí)間uptimeuptime命令不僅顯示負(fù)載第一行還顯示了系統(tǒng)已經(jīng)運(yùn)行了多久。例如up 50 days, 12:30。長(zhǎng)時(shí)間運(yùn)行的系統(tǒng)通常意味著穩(wěn)定但也可能意味著積累了大量的內(nèi)核表項(xiàng)如TIME-WAIT連接或存在未修復(fù)的安全漏洞因?yàn)闆](méi)重啟過(guò)。面試官可能會(huì)由此引申到系統(tǒng)維護(hù)、內(nèi)核熱補(bǔ)丁等話(huà)題。10.2 進(jìn)程運(yùn)行時(shí)間ps與topps -eo pid,comm,lstart,etime這是查看進(jìn)程啟動(dòng)時(shí)間和運(yùn)行時(shí)間的強(qiáng)大命令。lstart進(jìn)程的啟動(dòng)具體日期和時(shí)間。etime進(jìn)程自啟動(dòng)以來(lái)已經(jīng)運(yùn)行的時(shí)長(zhǎng)格式為[[DD-]hh:]mm:ss。例如50-12:30:15表示50天12小時(shí)30分15秒。在top命令中按Shift E可以切換頂部?jī)?nèi)存顯示單位但進(jìn)程的運(yùn)行時(shí)間顯示在TIME列注意這個(gè)是進(jìn)程消耗的 CPU 時(shí)間總和不是實(shí)際的墻鐘時(shí)間。要看墻鐘時(shí)間還是需要用ps的etime。10.3 關(guān)聯(lián)信息who -b與last rebootwho -b查看系統(tǒng)最后一次啟動(dòng)的時(shí)間。last reboot查看歷史重啟記錄。這對(duì)于排查“系統(tǒng)是否在某個(gè)時(shí)間點(diǎn)意外重啟過(guò)”非常有用。輸出會(huì)顯示每次重啟的時(shí)間點(diǎn)和持續(xù)時(shí)間。10.4 一個(gè)綜合應(yīng)用的思路當(dāng)發(fā)現(xiàn)一個(gè)進(jìn)程消耗了大量 CPU 時(shí)間top中的TIME很高但ps查看其etime并不長(zhǎng)時(shí)說(shuō)明這個(gè)進(jìn)程在短時(shí)間內(nèi)非?;钴S。反之如果etime很長(zhǎng)但TIME很低則說(shuō)明它是一個(gè)常駐但很空閑的進(jìn)程如守護(hù)進(jìn)程。結(jié)合兩者分析可以更準(zhǔn)確地判斷進(jìn)程行為。11. 問(wèn)題十如何排查一個(gè)線(xiàn)上服務(wù)器 CPU 使用率過(guò)高的問(wèn)題這是壓軸題綜合考察命令熟練度、排查邏輯和系統(tǒng)知識(shí)。回答要有條理體現(xiàn)方法論。11.1 第一步定位是哪個(gè)進(jìn)程top/htop登錄服務(wù)器首先運(yùn)行top或htop。按Shift P按 CPU 使用率排序找到最耗 CPU 的進(jìn)程。記下其 PID 和命令。觀察是用戶(hù)態(tài) CPU 高%Cpu(s)行的us高還是內(nèi)核態(tài)高sy高。用戶(hù)態(tài)高通常是應(yīng)用代碼問(wèn)題內(nèi)核態(tài)高可能是系統(tǒng)調(diào)用頻繁或上下文切換過(guò)多。11.2 第二步深入分析該進(jìn)程ps,pidstat,/procps -Lp PID -o tid,pcpu,comm查看該進(jìn)程下的所有線(xiàn)程LWP并按 CPU 排序。很多時(shí)候CPU 高是由單個(gè)線(xiàn)程引起的。pidstat -p PID 2 5以2秒為間隔采樣5次詳細(xì)顯示該進(jìn)程的 CPU、內(nèi)存、IO 等統(tǒng)計(jì)信息。查看進(jìn)程狀態(tài)cat /proc/PID/status。關(guān)注voluntary_ctxt_switches自愿上下文切換和nonvoluntary_ctxt_switches非自愿上下文切換。如果非自愿切換非常多說(shuō)明進(jìn)程經(jīng)常被 CPU 強(qiáng)制調(diào)度出去可能因?yàn)闀r(shí)間片用完或更高優(yōu)先級(jí)進(jìn)程搶占這本身也是 CPU 競(jìng)爭(zhēng)激烈的表現(xiàn)。11.3 第三步使用性能剖析工具perf,stracestrace如果懷疑是系統(tǒng)調(diào)用頻繁導(dǎo)致可以用strace -cp PID動(dòng)態(tài)跟蹤并統(tǒng)計(jì)進(jìn)程的系統(tǒng)調(diào)用。但strace本身開(kāi)銷(xiāo)較大不適合長(zhǎng)時(shí)間在生產(chǎn)環(huán)境使用。perf這是 Linux 官方的性能剖析神器。sudo perf top -p PID可以實(shí)時(shí)查看該進(jìn)程內(nèi)部哪些函數(shù)消耗 CPU 最多。如果需要更詳細(xì)的分析可以記錄數(shù)據(jù)后離線(xiàn)分析sudo perf record -g -p PID sleep 30記錄30秒然后用sudo perf report查看火焰圖或調(diào)用鏈。這能直接定位到熱點(diǎn)代碼行。11.4 第四步結(jié)合日志和業(yè)務(wù)邏輯通過(guò)上述工具定位到可疑的函數(shù)或系統(tǒng)調(diào)用后需要結(jié)合應(yīng)用程序的日志用之前講的tail -F,grep和業(yè)務(wù)代碼進(jìn)行最終判斷。例如perf發(fā)現(xiàn)是某個(gè) JSON 解析函數(shù)耗時(shí)高那么就去查日志里是不是有異常大的報(bào)文或者代碼里是否存在循環(huán)解析。11.5 一個(gè)完整的排查示例“假設(shè)top看到 Java 進(jìn)程 CPU 200%。首先ps -Lp java_pid發(fā)現(xiàn)是 GC 線(xiàn)程占用高。然后用jstat -gcutil java_pid 2s查看 GC 情況發(fā)現(xiàn) Full GC 頻繁。接著用jmap -dump:live,formatb,fileheap.hprof java_pid導(dǎo)出堆快照需謹(jǐn)慎可能觸發(fā) Full GC 且文件大用 MAT 工具分析發(fā)現(xiàn)是某個(gè)緩存對(duì)象沒(méi)有設(shè)置過(guò)期時(shí)間無(wú)限增長(zhǎng)導(dǎo)致內(nèi)存泄漏進(jìn)而引發(fā)頻繁 Full GC 消耗 CPU。解決方案是修復(fù)緩存邏輯。” 這個(gè)例子展示了從系統(tǒng)層到應(yīng)用層的完整鏈路。掌握這十個(gè)問(wèn)題及其背后的原理和排查思路你不僅能應(yīng)對(duì)大多數(shù) Linux 面試更能建立起一套行之有效的線(xiàn)上問(wèn)題排查方法論。記住命令是工具思維才是核心。在面試中盡量將你的回答引向你熟悉的、有成功排查經(jīng)驗(yàn)的場(chǎng)景這比單純羅列命令參數(shù)要有力得多。