面试6——Linux基础知识及应用编程

1.如何查看进程打开的文件

主要有lsof与fuser:
1. ps -a :查看当前系统下的所有进程,包括其他用户的进程

格式:ps [选项] fname
在这里插入图片描述

2.lsof -p pid :查看pid进程中打开的所有文件,包括普通文件、目录、网络连接、硬件等

格式:lsof [选项]
在这里插入图片描述

3. fuser -a pid :fuser可以看作是轻量级的lsof。默认只给出系统中打开文件的进程PID

格式:fuser [选项] fname
在这里插入图片描述

2.介绍下nm与ldd命令

nm 和 ldd 命令是Linux中的程序分析命令ldd是用来分析程序运行时需要依赖的动态库的工具;nm是用来查看指定程序中的符号表相关内容的工具nm/ldd命令详解
在这里插入图片描述
在这里插入图片描述

3.shell命令查内存,端口 ,io访问量,读写速率

4.awk grep具体应用

find 和 grep 命令异同
find 命令:主要用于查找文件
grep 命令:主要用来在某个文件中查找具体文字内容 ,

  1. 查找所有".h"文件
find /PATH -name "*.h"
# 查找所有".h"文件中的含有"helloworld"字符串的文件
find /PATH -name "*.h" -exec grep -in "helloworld" {} \;
find /PATH -name "*.h" | xargs grep -in "helloworld"
#查找所有".h"和".c"文件中的含有"helloworld"字符串的文件
find /PATH /( -name "*.h" -or -name "*.c" /) -exec grep -in "helloworld" {} \;

注:/PATH为查找路径,默认为当前路径。带-exec参数时必须以;结尾,否则会提示“find: 遗漏“-exec”的参数”。

Linux 三剑客 grep / sed / awk
grep: 强大的文本’搜索’工具

grep [OPTIONS] PATTERN [FILE...]
grep   -n   'word'  file_name

sed:实现数据的替换,删除,增加,选取等(以行为单位进行处理)

sed [option] 'script' inputfile
#删除file_name文件的2到4行
sed    '2,4d'    file_name

awk: 以字段为单位进行处理(其实就是把一行的数据分割,然后进行处理)

awk [options] 'program' file…
#把file_name 文件中的前五行的第一列,第二列的数据列出来 (以[tab]或空格键分隔)
 awk      'NR<6{print   $1  "\t"  $2 }'     file_name  

详细的操作Linux 三剑客 grep/sed/awk

5.硬链接与软连接,目录可不可以用硬链接

软连接相当于快捷方式,它的大小和源文件不一样。硬连接相当于指针,具有和源文件同步更新的特点。
目录是不能使用硬链接的,如果引入了对目录的硬连接就有可能在目录中引入循环,那么在目录遍历的时候系统就会陷入无限循环当中。也许您会说,符号连接不也可以引入循环吗,那么为什么不限制目录的符号连接呢?原因就在于在linux系统中,每个文件(目录也是文件)都对应着一个inode结构,其中inode数据结构中包含了文件类型(目录,普通文件,符号连接文件等等)的信息,也就是说操作系统在遍历目录时可以判断出符号连接,既然可以判断出符号连接当然就可以采取一些措施来防范进入过大的循环了,系统在连续遇到8个符号连接后就停止遍历,这就是为什么对目录符号连接不会进入死循环的原因了。但是对于硬连接,由于操作系统中采用的数据结构和算法限制,目前是不能防范这种死循环的。

6.常用网络方面管理维护命令netstat、 iptable、 tcpdump、 top

1.netstat 用于显示网络状态

netstat [选项]
netstat -a 显示所有连线中的 socket
在这里插入图片描述

2. top 监控Linux的系统状况

top [选项]
-d:指定每两次屏幕信息刷新之间的时间间隔
-p:监控指定PID的进程
-q:top没有任何延迟的进行刷新
-S:指定累计模式
-s:在安全模式下运行top
-i:不显示僵死进程
-c:显示进程执行的全路径
在这里插入图片描述

3.tcpdump root权限下使用的抓包工具,只能抓取流经本机的数据包

tcpdump [选项]
-c:指定要抓取包的数量
-i:指定网络接口
-n:对地址以数字的方式显示,否则显示主机名
-nn:在-n的基础上将端口也显示为数值
-N:不打印出host的域名部分
-p:指定要抓取的包是流入还是流出的包(in、out、inout)
-s:设置抓包长度,默认65535
在这里插入图片描述

4.iptables 对Linux系统中通信的数据包进行一定的检测,达到防火墙的目的
原理较为复杂,此处不做详解,百度上一大堆的详解。

7.makefile介绍下(cmake介绍下)

在windows中的一些IDE,已经帮我们做好了这一部分的工作,但是在Linux环境中,通过 makefile 来制定整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。makefile 教学

CMake是一个跨平台的不编译工具,可以用简单的一些语句来描述编译过程。CMake可以输出各种各样的makefile或者project文件,能够支持大型工程的联合编译。
CMake 是 makefile 的一个工具,读入所有源文件之后,自动生成makefile.
在这里插入图片描述

8.gdb调试步骤及常用命令

1)进入GDB  #gdb test
  test是要调试的程序,由gcc test.c -g -o test生成。进入后提示符变为(gdb) 。
2)查看源码  (gdb) l
  源码会进行行号提示。
  如果需要查看在其他文件中定义的函数,在l后加上函数名即可定位到这个函数的定义及查看附近的其他源码。或者:使用断点或单步运行,到某个函数处使用s进入这个函数。
3)设置断点  (gdb) b 6
  这样会在运行到源码第6行时停止,可以查看变量的值、堆栈情况等;这个行号是gdb的行号。
4)查看断点处情况  (gdb) info b
  可以键入"info b"来查看断点处情况,可以设置多个断点;
5)运行代码  (gdb) r
6)显示变量值  (gdb) p n

  在程序暂停时,键入"p 变量名"(print)即可;
7)观察变量  (gdb) watch n
在某一循环处,往往希望能够观察一个变量的变化情况,这时就可以键入命令"watch"来观察变量的变化情况,GDB在"n"设置了观察点;
8)单步运行  (gdb) n
9)程序继续运行 (gdb) c

  使程序继续往下运行,直到再次遇到断点或程序结束;
10)退出GDB  (gdb) q

9.gdb查看堆栈中所有遍历,gdb查看shared_ptr

在gdb中使用 thread apply all bt 查看所用线程堆栈信息
在这里插入图片描述
backtrace/bt  bt  用来打印栈帧指针,也可以在该命令后加上要打印的栈帧指针的个数,查看程序执行到此时,是经过哪些函数呼叫的程序,程序“调用堆栈”是当前函数之前的所有已调用函数的列表(包括当前函数)。每个函数及其变量都被分配了一个“帧”,最近调用的函数在 0 号帧中(“底部”帧)

frame  frame 1  用于打印指定栈帧
info reg  info reg  查看寄存器使用情况
info stack  info stack  查看堆栈使用情况
up/down  up/down  跳到上一层/下一层函数

10.指向的内容

11.gdb如何调试多进程多线程

一、GDB调试多线程

1. info threads 显示当前可调式的所有线程 
2. thread ID 切换当前调试的线程为指定ID的线
3. thread apply all command 所以的线程都执行command命令
4. thread apply ID1,ID2.... command  指定线程执行command命令
5. set scheduler-locking off|on|step: 
  在使用step或continue命令调试当前被调试线程的时候,其他线程也是同时执行的,如果我们只想要被调试的线程执行,而其他线程停止等待,那就要锁定要调试的线程,只让它运行。 
  off:不锁定任何线程,所有线程都执行。 
  on:只有当前被调试的线程会执行。 
  step:阻止其他线程在当前线程单步调试的时候抢占当前线程。只有当next、continue、util以及finish的时候,其他线程才会获得重新运行的
  6.show scheduler-locking: 查看当前锁定线程的模式
  7.i threads 实现线程间切换

二、GDB调试多进程

1.设置方法
  set follow-fork-mode [parent][child] 
  set detach-on-fork [on|off]  
2.查看上述两个属性的值
  show follow-fork-mode //查看系统默认的模式
  show detach-on-fork
/* 
	parent                   on               只调试主进程(GDB默认)
	child                    on               只调试子进程
	parent                   off              同时调试两个进程,gdb跟主进程,子进程block在fork位置
	child                    off              同时调试两个进程,gdb跟子进程,主进程block在fork位置
*/

3.查询正在调试的进程
  info inferiors  //查询正在调试的进程
  inferior 进程编号 // 切换调试的进程
4. add-inferior [-copies n] [-exec executable] //添加新的调试进程
5. detach inferior [进程编号] //释放掉 
6. kill inferior [进程编号] 
7. remove-inferior [进程编号] //删除该进程
8. set schedule-multiple 
9. set print interior-events on/off

12. g++和gcc编译出来有什么区别

1.g++ 会自动连接C++标椎库,比如algorith、string、vector等。 gcc 不会,所以有时,gcc在编译C++的时候会因为缺少默认的链接库而失败。
2.gcc 会根据文件后缀自动识别是C文件还是C++文件,g++ 均默认为是C++文件
3.gcc 编译C文件少很多宏定义,gcc编译C++会多一些宏定义。
总结:C++是C语言的超集,而g++同样也是gcc的超集。在编译阶段,g++ 会调用 gcc.
在这里插入图片描述

13.死锁怎么调试

借助 Core Dump。在程序莫名其妙down掉了,此时操作系统会把当前的内存状况存储在一个core 文件中,通过查看core文件就可以直观的程序是因为什么而垮掉了。有时候程序down了, 但是core文件却没有生成,core文件的生成跟你当前系统的环境设置有关系, 可以用下面的语句设置一下, 然后再运行程序便会生成core文件.

ulimit -c unlimited

core文件生成的位置一般于运行程序的路径相同, 文件名一般为core.进程号。
那么如何在多线程调试中使用Core Dump:
1.使用 kill 命令产生 core dump文件:kill -11 pid 产生core文件。
2.使用gdb工具打开core文件 gdb dead_lock_demo core
3.打印堆栈信息 thread apply all bt

14.core文件中是什么,gdb调试core文件

在一bai个程序崩溃时du,它一般会在指定目zhi录下生成一个core文件。daocore文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。通过core文件调试步骤:
1. ulimit -c unlimted(打开core,默认没有打开)
2. 运行./a.out(编译的时候加调试选项-g) 死锁阻塞,Ctrl+\ 产生core dump
3. gdb ./a.out core.xxx
4. thread apply all bt查看死锁位置

15.如何读取一个10G文件,cat一个10g文件会发生什么

有次面试遇到一个问题,10G的 log 里面每一行都保存着一个url,内存只有250M,当输入一个url时,如果快速查出日志里是否有这条记录,如果有,有多少条?要求不能使用数据库,只能使用文本处理。
这是一道非常典型的使用分治法来解决问题的题目。思路如下:
首先,考虑将10G的log文件划分为多个小于250M的文件,这样每个小文件就可以一次性载入内存了。
当小文件可以一次性载入内存后,可以直接grep搜索,也可以对文件内容排序后,然后二分查找。

疑问:如何避免在切分文件的过程中,误操作切断url?
解答:可以使用 split 按行来切分文件(注意:这里按行是按照“\n”分割,和你用vim编译器打开看到的行是不一样地)。因此,我们假设一个记录差不多是480byte(已经不少了),那么按照-l 500000 分割文件,那其实每个文件存储500000行也才240M,完全可以载入内存,也不存在url被截断的问题了。

强行 cat 一个大文件会造成内存溢出,通常将cat命令和split命令混合使用。

猜你喜欢

转载自blog.csdn.net/GJQJFJ/article/details/105974010
今日推荐