10 道常見的 Linux 面試題

1、 常用的 Linux 命令

1)文件操作

cat、vi、vim、ls、mkdir、touch 、cp、mv

查找是否存在該文件名:

find / -name mysql

2)日誌

tail -f /var/www/MOB_logs/catalina.2018-05-18.out

抓取關鍵字:

cat catalina.2019-03-20.out | grep "返回respData"
grep -i "返回respData" catalina.2018-06-11.out

3)解壓

tar

tar -zxvf filename.tar.gz

4)查找進程

ps

ps -aux|grep java
  1. 系統、內存、磁盤、網絡相關

top 查看內存、cpu 情況

du、df 查看磁盤、文件大小

du -s -h /data/

ping、curl 查看網絡是否正常

整理一個思維導圖給大家:

Linux 常用命令

2、 系統緩慢的原因,或者突然很卡

CPU 過高、Full GC 次數過多、內存使用過多、硬盤空間不足等問題,都會帶來系統突然運行緩慢的問題,也是面試特別容易被問到的,下面針對系統運行緩慢等問題進行展開。

3、 線上 CPU 爆高,怎麼排查?

1)使用 top 命令,然後按 1  表示進入第 1 個 CPU(如果是多核需要分別查看不同的 CPU)

演示:

[root@VM-8-8-centos ~]# top
top - 23:17:16 up  7:54,  1 user,  load average: 1.73, 1.70, 1.71
Tasks:  95 total,   1 running,  94 sleeping,   0 stopped,   0 zombie
%Cpu(s): 50.0 us, 50.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  1882056 total,    69588 free,  1255116 used,   557352 buff/cache
KiB Swap:        0 total,        0 free,        0 used.   478816 avail Mem

  PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
 1953 root      20   0  101080   2248   1732 S  0.3  0.1   0:01.89 YDLive
 2310 root      20   0 2369316 246988  13760 S  0.3 13.1   0:22.47 java
 5082 root      20   0  154808  10500   3248 S  0.3  0.6   0:11.14 YDService
    1 root      20   0   43444   3872   2580 S  0.0  0.2   0:01.27 systemd
    2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 kthreadd
    4 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 kworker/0:0H
    5 root      20   0       0      0      0 S  0.0  0.0   0:00.07 kworker/u2:0
    6 root      20   0       0      0      0 S  0.0  0.0   0:00.02 ksoftirqd/0
    7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 migration/0
load average: 0.00, 0.01, 0.05

— load average後面的三個數分別是 1 分鐘、5 分鐘、15 分鐘的負載情況。

2)按 x,CPU 使用情況排序,找到 CPU 過高的pid,以pid 19505爲例,

然後看一下這個 pid 的線程情況:

ps -mp 19505 -o THREAD,tid,time

演示:

[root@VM_0_12_centos ~]# ps -mp 19505 -o THREAD,tid,time   
USER     %CPU PRI SCNT WCHAN  USER SYSTEM   TID     TIME
root      0.0   -    - -         -      -     - 04:03:21
root      0.0  19    - futex_    -      - 19505 00:00:00
root      0.0  19    - futex_    -      - 19507 00:00:08
root      0.0  19    - futex_    -      - 19508 00:00:01
root      0.0  19    - futex_    -      - 19509 00:47:56
root      0.0  19    - futex_    -      - 19510 00:00:00
root      0.0  19    - futex_    -      - 19511 00:00:00
root      0.0  19    - futex_    -      - 19512 00:00:00
root      0.0  19    - futex_    -      - 19513 00:07:45
root      0.0  19    - futex_    -      - 19514 00:00:00
root      0.0  19    - futex_    -      - 19515 00:00:00
root      0.0  19    - futex_    -      - 19516 00:00:00
root      0.0  19    - futex_    -      - 19517 00:00:00
root      0.0  19    - futex_    -      - 19518 00:01:33
root      0.0  19    - futex_    -      - 19519 00:01:21
root      0.0  19    - futex_    -      - 19520 00:00:00
root      0.0  19    - futex_    -      - 19521 02:23:05
root      0.0  19    - futex_    -      - 19539 00:00:00
root      0.0  19    - futex_    -      - 19540 00:00:00
root      0.0  19    - futex_    -      - 19576 00:05:10

或者使用

top -Hp 19505 -d 1 -n 1

都是一樣的

3)把 tid (線程 id) 轉成  16 進制 ,以 tid 19507 爲例

printf "%x\n" tid

演示:

[root@VM_0_12_centos ~]# printf "%x\n" 19507
4c33

4)查看 tid 4c31 線程堆棧情況:

只查看前 30 行

jstack 19505 |grep tid -A 30

演示:

[root@VM_0_12_centos ~]# jstack 19505 |grep 4c33 -A 30 
"DestroyJavaVM" #36 prio=5 os_prio=0 tid=0x00007fbb3800a000 nid=0x4c33 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"http-nio-8848-Acceptor-0" #34 daemon prio=5 os_prio=0 tid=0x00007fbb3820e800 nid=0x4cb2 runnable [0x00007fbaff268000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
        at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
        - locked <0x00000000f2a67c30> (a java.lang.Object)
        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:448)
        at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:70)
        at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8848-ClientPoller-0" #33 daemon prio=5 os_prio=0 tid=0x00007fbb38f21000 nid=0x4cb1 runnable [0x00007fbaff369000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
        at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
        at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000f2a67e60> (a sun.nio.ch.Util$3)
        - locked <0x00000000f2a67e70> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000f2a67e18> (a sun.nio.ch.EPollSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:743)
        at java.lang.Thread.run(Thread.java:748)

"http-nio-8848-exec-10" #32 daemon prio=5 os_prio=0 tid=0x00007fbb38229800 nid=0x4cb0 waiting on condition [0x00007fbaff46a000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000f2a68030> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)

4、 查看垃圾回收 GC 的情況,包括 fullGC 次數和耗時

1)查看

ps -aux|grep java

假如 pid 是 19505

2)使用jstat -gc或者 jstat -gcutil 查看空間使用情況

[root@VM_0_12_centos ~]# jstat  -gc 19505
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
 0.0   1024.0  0.0   1024.0 72704.0   8192.0   57344.0    45449.8   73168.0 70119.8 8708.0 8169.9    214    7.855   0      0.000    7.855
[root@VM_0_12_centos ~]# jstat  -gcutil 19505
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
  0.00 100.00  12.68  79.26  95.83  93.82    214    7.855     0    0.000    7.855

參數解析

S0  — Heap 上的 Survivor space 0 區已使用空間的百分比
S1  — Heap 上的 Survivor space 1 區已使用空間的百分比
E  — Heap 上的 Eden space 區已使用空間的百分比
O  — Heap 上的 Old space 區已使用空間的百分比
P  — Perm space 區已使用空間的百分比
YGC — 從應用程序啓動到採樣時發生 Young GC 的次數
YGCT– 從應用程序啓動到採樣時 Young GC 所用的時間 (單位秒)
FGC — 從應用程序啓動到採樣時發生 Full GC 的次數
FGCT– 從應用程序啓動到採樣時 Full GC 所用的時間 (單位秒)
GCT — 從應用程序啓動到採樣時用於垃圾回收的總時間 (單位秒)

上下文切換

頻繁上下文,會帶來性能問題

5、查內存使用情況

於 Linux/Unix 系統內存佔用的百分比,無須過於關心,一般大於 90% 都是屬於正常情況~

1)使用 free 查看內存使用情況

[root@VM_0_12_centos ~]#  free -h
              total        used        free      shared  buff/cache   available
Mem:           1.8G        862M         69M        600K        906M        806M
Swap:            0B          0B          0B

2)釋放內存

[root@VM_0_12_centos ~]# sync

(描述:sync 命令運行 sync 子例程。如果必須停止系統,則運行 sync 命令以確保文件系統的完整性。sync 命令將所有未寫的系統緩衝區寫到磁盤中,包含已修改的 i-node、已延遲的塊 I/O 和讀寫映射文件)

drop_caches 的詳細文檔如下:

a、To free pagecache:     清空 頁面 高速緩存

echo 1 > /proc/sys/vm/drop_caches

b、To free dentries and inodes:    清空 目錄項 和 索引節點

echo 2 > /proc/sys/vm/drop_caches

c、To free pagecache, dentries and inodes:    清空以上兩項

echo 3 > /proc/sys/vm/drop_caches

試一下執行

echo 3 > /proc/sys/vm/drop_caches

然後再查看內存情況:

[root@VM_0_12_centos ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:           1.8G        862M        904M        600K         71M        856M
Swap:            0B          0B          0B

結果:free 和 available 變大了,buff/cache 變小了,有效的釋放了 buffer 和 cache。

6、 查硬盤使用情況

df

[root@VM_0_12_centos ~]# df -hl
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        50G   14G   34G  29% /
devtmpfs        909M     0  909M   0% /dev
tmpfs           920M     0  920M   0% /dev/shm
tmpfs           920M  620K  919M   1% /run
tmpfs           920M     0  920M   0% /sys/fs/cgroup
tmpfs           184M     0  184M   0% /run/user/0

du

[root@VM_0_12_centos ~]# du -h heap 
147M    heap

非遞歸查目錄大小

[root@VM_0_12_centos ~]#  du -s -h /root
1.3G    /root

7、 怎麼殺死進程?

一般情況下,終止一個前臺進程使用 Ctrl + C 就可以了。對於一個後臺進程就需要用 kill 命令來終止。
我們會先使用 ps、top 等命令獲得進程的 PID,然後使用 kill 命令來殺掉該進程。

例如:

 ps -aux|grep java

找到 java 的線程 id

kill -9 3827

8、linux vm 內核參數優化設置

1)CPU

使用 uptime 查看 CPU 使用情況

[root@VM_0_12_centos ~]# uptime
 17:03:41 up 307 days,  1:31,  3 users,  load average: 0.00, 0.01, 0.05

使用vmstat查看 CPU 使用狀態

[root@VM_0_12_centos ~]# vmstat 2 10     #2秒打印一次,一共10次
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 902552   7748  88820    0    0    38    24    1    1  1  1 99  0  0
 0  0      0 902552   7748  88820    0    0     0     0  173  248  1  0 100  0  0

解釋:

     r: 運行隊列長度和正在運行的線程數;

  b: 表示阻塞的進程數;

  swpd: 虛擬內存已使用的大小,如果大於 0,表示你的機器物理內存不足了,如果不是程序內存泄露的原因,那麼你該升級內存了或者把耗內存的任務遷移到其他機器;

  si: 每秒從磁盤讀入虛擬內存的大小,如果這個值大於 0,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。我的機器內存充裕,一切正常。

  so: 每秒虛擬內存寫入磁盤的大小,如果這個值大於 0,同上;

  bi: 塊設備每秒接收的塊數量,這裏的塊設備是指系統上所有的磁盤和其他塊設備,默認塊大小是 1024byte,我本機上沒什麼 IO 操作,所以一直是 0,但是我曾在處理拷貝大量數據 (2-3T) 的機器上看過可以達到 140000/s,磁盤寫入速度差不多 140M 每秒;

  bo: 塊設備每秒發送的塊數量,例如我們讀取文件,bo 就要大於 0。bi 和 bo 一般都要接近 0,不然就是 IO 過於頻繁,需要調整;

  in: 每秒 CPU 的中斷次數,包括時間中斷;

  cs: 每秒上下文切換次數,例如我們調用系統函數,就要進行上下文切換,線程的切換,也要進程上下文切換,這個值要越小越好,太大了,要考慮調低線程或者進程的數目, 例如在 apache 和 nginx 這種 web 服務器中,我們一般做性能測試時會進行幾千併發甚至幾萬併發的測試,選擇 web 服務器的進程可以由進程或者線程的峯值一直下調,壓測,直到 cs 到一個比較小的值,這個進程和線程數就是比較合適的值了。系統調用也是,每次調用系統函數,我們的代碼就會進入內核空間,導致上下文切換,這個是很耗資源,也要儘量避免頻繁調用系統函數。上下文切換次數過多表示你的 CPU 大部分浪費在上下文切換,導致 CPU 幹正經事的時間少了,CPU 沒有充分利用,是不可取的。

  st: cpu 在虛擬化環境上在其他租戶上的開銷;

  1. 端口

只用關心 TIME_WAIT 的個數,Linux 下可用端口的數量只有 65535 個,佔用一個少一個,我們可以調整 Linux 的 TCP 內核參數,讓系統更快的釋放 TIME_WAIT 連接。

[root@VM_0_12_centos ~]# netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
CLOSE_WAIT 1
ESTABLISHED 5

修改:

vim /etc/sysctl.conf

修改 3 個參數:

查看可用端口範圍:

[root@VM_0_12_centos ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768   60999

修改 sysctl.conf 文件修改範圍:

net.ipv4.ip_local_port_range = 1024 65535

3)定時任務清理臨時目錄垃圾文件,日誌歸檔

4)鎖定關鍵系統文件,防止被提權篡改

5)清楚多餘的系統虛擬賬號

9、如何合理查找

換句話說就是 合理使用 find 參命令

1)在 /software 目錄下找出大小超過 10MB 的文件

find /software -type f -size +10240k

[root@VM_0_12_centos /]# find /software -type f -size +10240k
/software/mysql-5.6.33-linux-glibc2.5-x86_64.tar.gz
/software/mysql/lib/libmysqlclient.a
/software/mysql/lib/libmysqld-debug.a
/software/mysql/lib/libmysqld.a

2)目錄下找出 365 天之內未被訪問過的文件

find /software \! -atime -365

[root@VM_0_12_centos /]# find /software \! -atime -365
/software
/software/mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz

3) 目錄下找出 365 天之前被修改過的文件

find /home -mtime +365

10、Linux 的目錄結構

常見的:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/d0JiB7-4VUb7S6_7SBhL_Q