关于java:常见Linux面试题

5次阅读

共计 10001 个字符,预计需要花费 26 分钟才能阅读完成。

1、罕用的 Linux 命令

1)文件操作

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

查找是否存在该文件名:

find / -name mysql 

cat:一次性显示文件内容

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 -zxvf filename.tar.gz

4)查找过程

ps -aux|grep java

5) 零碎、内存、磁盘、网络相干

​ top 查看内存、cpu 状况

​ du、df 查看磁盘、文件大小

du -s -h /data/

​ ping、curl 查看网络是否失常

6)权限相干

chmod:批改文件的权限

chown:即change owner,批改文件和目录的所有者权限

chattr:chmod 的底层操作,锁定文件

2、零碎迟缓的起因,或者忽然很卡

  • Full GC 次数过多
  • CPU 过高
  • 接口耗时、HTTP 申请过多,响应慢。(比拟经典)
  • 死锁(Blocke)
  • 某个线程进入 WAITTING,sleep、wait 工夫过长,假死。

CPU 过高、Full GC 次数过多、内存应用过多、硬盘空间有余等问题,都会带来零碎忽然运行迟缓的问题,也是面试特地容易被问到的,上面针对零碎运行迟缓等问题进行开展。

这又引申出两个问题:

CPU 利用率和负载的问题。

CPU 利用率 显示的是程序在运行期间实时占用的 CPU 百分比;cpu 使用率反映的是以后 cpu 的忙碌水平,忽高忽低的起因在于占用 cpu 解决工夫的过程可能处于 io 期待状态但却还未开释进入 wait。

CPU 负载 是指某段时间内占用 cpu 工夫的过程和期待 cpu 工夫的过程数,这里期待 cpu 工夫的过程是指期待被唤醒的过程,不包含处于 wait 状态过程。

CPU 利用率高,并不意味着 CPU 的负载大。两者之间没有必然的关系。

CPU 负载很高怎么办?

能够通过 ps -axjf查看 STAT 这一列是否存在 D 状态过程

比方:

[root@VM-8-8-centos proc]# ps -axjf
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     2     0     0 ?           -1 D        0   0:00 [kthreadd]
    2     4     0     0 ?           -1 S<       0   0:00  \_ [kworker/0:0H]
    2     6     0     0 ?           -1 D        0   0:10  \_ [ksoftirqd/0]
    2     7     0     0 ?           -1 S        0   0:00  \_ [migration/0]

D 状态是指不可中断的睡眠状态。该状态的过程无奈被 kill,也无奈自行退出。只能通过复原其依赖的资源或者重启零碎来解决。

负载高,好比节假日的高速公路堵车,马路都是车,曾经阻塞了,收费站里面还有很多车在等着,解决办法就是多建一条高速公路,晋升服务器的硬件性能,或者找出 I / O 期待的工作,手动解决。

负载高常见的起因有:

  • 磁盘读写申请过多
  • MySQL 死锁或者查问返回慢
  • 硬盘故障,读写申请获取不到资源

如果 CPU 很高,请看上面:

3、线上 CPU 爆高 靠近 100%,怎么排查?

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: 1.73, 1.70, 1.71

load average前面的三个数别离是 1 分钟、5 分钟、15 分钟的负载状况。指的是处于可运行状态和不可中断状态的均匀过程数。数字越大,CPU 负载越大。

如果 小于 CPU 数 * 每个 CPU 的外围数,则示意负载是正当的,比方下面我的服务器 CPU 是 1 个,只有 1 个外围,那么当初 1.7 的负载大于 1,就很不合理了,证实有很多工作在期待中。

如何查 CPU 和 CPU 外围?

查看 CPU 数目:

cat /proc/cpuinfo | grep "model name" 

查看 CPU 外围:

cat /proc/cpuinfo | grep "cpu cores"

演示:

[root@VM-8-8-centos ~]# cat /proc/cpuinfo | grep "model name"
model name      : AMD EPYC 7K62 48-Core Processor
[root@VM-8-8-centos ~]# cat /proc/cpuinfo | grep "cpu cores"
cpu cores       : 1

2)键盘按下 x

按下 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)开释内存

  • 先 执行 sync
[root@VM_0_12_centos ~]# sync

(形容:sync 命令运行 sync 子例程。如果必须进行零碎,则运行 sync 命令以确保文件系统的完整性。sync 命令将所有未写的零碎缓冲区写到磁盘中,蕴含已批改的 i-node、已提早的块 I/O 和读写映射文件)

  • 批改drop_caches 参数

drop_caches 的具体文档如下:

aTo free pagecache: 清空 页面 高速缓存

echo 1 > /proc/sys/vm/drop_caches

bTo free dentries and inodes: 清空 目录项 和 索引节点

echo 2 > /proc/sys/vm/drop_caches

cTo 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
0  0      0 131104 199740 1341608    0    0     0     0  137  301  0  0 99  0  0
0  0      0 131104 199740 1341612    0    0     0    26  162  342  0  0 99  1  0
0  0      0 131140 199740 1341612    0    0     0     0  135  301  0  0 99  0  0
0  0      0 130892 199740 1341616    0    0     0     0  188  463  1  1 99  0  0
0  0      0 130912 199740 1341620    0    0     0    68  145  284  1  0 99  0  0

解释:

procs 列

r: 运行队列长度和正在运行的线程数;

b: 示意睡眠过程的数量,即阻塞的过程数;

swpd: 虚拟内存已应用的大小,如果大于 0,示意你的机器物理内存不足了,如果不是程序内存泄露的起因,那么你该降级内存了或者把耗内存的工作迁徙到其余机器;

memory 列

free: 闲暇的物理内存的大小;

buff: 存储,目录外面的内容、权限等的缓存大小;

cache: 缓冲大小,值越大,命中缓冲几率越大,就不会常常读写磁盘;

swap 列

si: 每秒从磁盘读入虚拟内存的大小,如果这个值大于 0,示意物理内存不够用或者内存泄露了,要查找耗内存过程解决掉。我的机器内存富余,一切正常。

so: 每秒虚拟内存写入磁盘的大小,同上;

io 列

bi: 块设施每秒接管的块数量,这里的块设施是指零碎上所有的磁盘和其余块设施,默认块大小是 1024byte;

bo: 块设施每秒发送的块数量,例如咱们读取文件,bo 就要大于 0。bi 和 bo 个别都要靠近 0,不然就是 IO 过于频繁,IO 等待时间也长,须要调整;

system 列

in: 每秒 CPU 的中断次数,包含工夫中断;

cs: 每秒上下文切换次数 ;

这两个值越大,内核耗费的 CPU 工夫会越大

CPU 列

us: 用户过程执行工夫(user time),us 的值比拟高时,阐明用户过程耗费的 CPU 工夫多,长期高应检查程序

sy: 零碎过程执行工夫(system time),sy 的值高时,阐明零碎内核耗费的 CPU 资源多,长期高因查看零碎

id: 闲暇工夫(包含 IO 等待时间),中央处理器的闲暇工夫。以百分比示意。

wa: 期待 CPU 的过程占用百分比

st: cpu 在虚拟化环境上在其余占用的开销,能够了解为被抽走了多少 cpu 资源

2) 端口

只用关怀 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 个参数:

1) net.ipv4.tcp_syncookies = 1 示意开启 SYN Cookies, 当呈现 SYN 期待队列溢出时, 启用 cookies 来解决, 可防备大量 SYN 攻打;默认为 0, 示意敞开

2) net.ipv4.tcp_tw_reuse = 1 示意开启重用, 容许将 TIME-WAIT sockets 从新用于新的 TCP 连贯, 默认为 0, 示意敞开

3) net.ipv4.tcp_tw_recycle = 1 示意开启 TCP 连贯中 TIME-WAIT sockets 的疾速回收, 默认为 0, 示意敞开

查看可用端口范畴:

[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

[root@VM-8-8-centos ~]# find /home -mtime +365
/home
/home/HaC
/home/HaC/HaC.pub
/home/HaC/HaC

10、Linux 的目录构造

常见的:

  • /bin
    bin 是 Binaries (二进制文件) 的缩写, 这个目录寄存着最常常应用的命令。
  • /boot:
    这里寄存的是启动 Linux 时应用的一些外围文件,包含一些连贯文件以及镜像文件。
  • /dev:
    dev 是 Device(设施) 的缩写, 该目录下寄存的是 Linux 的外部设备,在 Linux 中拜访设施的形式和拜访文件的形式是雷同的。
  • /etc:
    etc 是 Etcetera(等等) 的缩写, 这个目录用来寄存所有的系统管理所须要的配置文件和子目录。
  • /home
    用户的主目录,在 Linux 中,每个用户都有一个本人的目录,个别该目录名是以用户的账号命名的,如上图中的 alice、bob 和 eve。
  • /lib
    lib 是 Library(库) 的缩写这个目录里寄存着零碎最根本的动静连贯共享库,其作用相似于 Windows 里的 DLL 文件。简直所有的应用程序都须要用到这些共享库。
正文完
 0