面试公司:腾讯科技
面试岗位:后端软件开发工程师
面试过程:一面(50min)
面试总结:
算法题占了很多时间,后面基本上全是问八股,项目方面鲜有涉及。
面试官还是挺好的,中间会给一点引导,但自己操作系统和Linux命令部分准备的不够充分,回答的稀烂。
问八股文问到我头晕,真正工作上用得到这些八股文么?
-
自我介绍(5 min)
-
手撕两道算法题(30 min)
a. 旋转字符串
b. 删除链表中重复元素
-
Linux常用命令有哪些
-
awk命令有了解过嘛
-
平时怎么查看日志
-
有没有用过命令查看程序运行的栈信息
-
netstat命令怎么使用?用来干啥?
-
Linux网络抓包用什么命令来实现?
-
top命令用过嘛?如何查看僵死进程?
-
进程,线程和协程有什么区别?
-
进程和线程的区别在哪里?
-
进程之间的通信方式有哪些?
-
除了管道还有什么通信方式?
-
前端发起请求之后到达后端,中间过程是什么?
笔者整理答案,以供参考
1. 自我介绍 (5 min)
2. 手撕两道算法题 (30 min)
a. 旋转字符串
public String rotateString(String s, int k) {
int n = s.length();
k = k % n; // 处理k大于字符串长度的情况
return s.substring(n - k) + s.substring(0, n - k);
}
b. 删除链表中重复元素
public ListNode deleteDuplicates(ListNode head) {
ListNode current = head;
while (current != null && current.next != null) {
if (current.val == current.next.val) {
current.next = current.next.next;
} else {
current = current.next;
}
}
return head;
}
3. Linux常用命令有哪些
常用的Linux命令有:ls
、cd
、pwd
、cp
、mv
、rm
、mkdir
、rmdir
、cat
、less
、grep
、find
、chmod
、chown
等。这些命令可以帮助我们完成文件和目录管理、权限设置等操作。
- ls:列出目录内容
- 作用:显示目录中的文件和子目录
- 示例:
ls -l
显示详细信息
- cd:改变当前目录
- 作用:切换到指定目录
- 示例:
cd /home/user/Documents
切换到Documents目录
- pwd:显示当前目录路径
- 作用:显示当前工作目录的绝对路径
- 示例:
pwd
输出/home/user
- cp:复制文件或目录
- 作用:将文件或目录复制到指定位置
- 示例:
cp source.txt destination.txt
复制source.txt到destination.txt
- mv:移动或重命名文件或目录
- 作用:移动(剪切)文件或目录,或重命名
- 示例:
mv file.txt /home/user/
移动文件到指定目录mv oldname.txt newname.txt
重命名文件
- rm:删除文件或目录
- 作用:删除文件或目录
- 示例:
rm file.txt
删除文件rm -r /home/user/old_directory
递归删除目录及其内容
- mkdir:创建目录
- 作用:创建一个新的目录
- 示例:
mkdir new_directory
创建名为new_directory的目录
- rmdir:删除空目录
- 作用:删除一个空目录
- 示例:
rmdir empty_directory
删除名为empty_directory的目录
- cat:连接并显示文件内容
- 作用:读取并显示文件内容
- 示例:
cat file.txt
显示file.txt的内容
- less:分页显示文件内容
- 作用:以分页形式查看文件内容
- 示例:
less file.txt
分页查看file.txt的内容(使用q
退出)
- grep:文本搜索工具
- 作用:在文件中搜索匹配的文本
- 示例:
grep "pattern" file.txt
在file.txt中搜索"pattern"
- find:查找文件或目录
- 作用:在目录树中搜索文件或目录
- 示例:
find /home/user -name "*.txt"
在/home/user目录下查找所有扩展名为.txt的文件
- chmod:更改文件权限
- 作用:更改文件或目录的权限
- 示例:
chmod 755 script.sh
将script.sh的权限设置为-rwxr-xr-x- 用数字表示权限:所有者读写执行(7),所属用户组读执行(5),其他用户读执行(5)
- chown:更改文件所有者
- 作用:更改文件或目录的所有者和所属组
- 示例:
chown user:group file.txt
更改file.txt的所有者为user,所属组为group
4. awk命令有了解过嘛
有了解过,awk
是一种强大的文本处理工具,它的主要作用是对文本文件中的数据进行筛选、提取和处理。
使用格式
基本格式:
awk 'pattern { action }' file
pattern
:要匹配的模式(可以是正则表达式)action
:对匹配行执行的操作,用大括号括起来file
:输入文件
常用实例
-
简单打印每行
awk '{ print }' file.txt
打印文件file.txt的每一行。
-
打印某个字段
awk '{ print $1 }' file.txt
打印file.txt每一行的第一个字段。
-
字段定界符
awk -F, '{ print $1 }' file.csv
指定字段分隔符为逗号,打印file.csv每一行的第一个字段。
-
模式匹配
awk '/pattern/ { print }' file.txt
打印file.txt中包含指定模式
pattern
的行。 -
条件处理
awk '$3 > 100 { print $1, $3 }' file.txt
打印文件file.txt中第三个字段大于100的行的第一个和第三个字段。
-
计算总和
awk '{sum += $1} END {print sum}' file.txt
计算file.txt中第一个字段的总和。
5. 平时怎么查看日志
-
cat:显示整个日志文件内容
cat /var/log/syslog
适用于小型日志文件,但对于大型日志文件,可能会一次性输出太多内容。
-
tac:反向显示整个日志文件内容
tac /var/log/syslog
适用于查看最新的日志条目,因为它从文件的末尾开始显示。
-
more 和 less:分页显示日志文件
more /var/log/syslog less /var/log/syslog
less
更为强大,允许你在文件中前后移动,q
退出查看。 -
tail:查看日志文件的最后几行
tail /var/log/syslog tail -n 50 /var/log/syslog # 查看最后50行 tail -f /var/log/syslog # 实时查看(跟踪)日志的新增行
tail -f
对于监控服务实时输出非常有用。 -
head:查看日志文件的前几行
head /var/log/syslog head -n 20 /var/log/syslog # 查看前20行
-
grep:搜索日志文件中的特定模式
grep "ERROR" /var/log/syslog grep -i "error" /var/log/syslog # 忽略大小写 grep "ERROR" /var/log/syslog | less # 分页查看搜索结果
-
awk:筛选和处理日志文件中的特定字段
awk '/ERROR/ {print $0}' /var/log/syslog # 搜索含“ERROR”的行 awk '{print $1, $2, $3}' /var/log/syslog # 打印前3个字段
-
logrotate:管理日志文件的轮替
6. 有没有用过命令查看程序运行的栈信息
有,用过gdb
和pstack
来查看程序的栈信息。gdb
是一个强大的调试工具,而pstack
可以直接输出运行进程的栈信息。
使用 gdb
调试器
GNU Debugger(gdb
)是一个强大的工具,可以用来查看正在运行的程序的栈信息。以下是使用 gdb
查看栈信息的步骤:
-
找到进程ID(PID): 使用
ps
命令找到要调试的进程的PID。ps aux | grep program_name
-
附加到正在运行的进程: 使用
gdb
附加到进程。sudo gdb -p PID
-
显示栈回溯: 在
gdb
提示符下,输入bt
(backtrace)命令来查看栈信息。(gdb) bt
-
退出gdb:
(gdb) quit
使用 pstack
命令
pstack
用于显示给定 PID 的栈回溯信息。
-
安装: 在大多数Linux发行版中,你可以通过包管理器安装
pstack
。sudo apt-get install psmisc # Ubuntu/Debian sudo yum install psmisc # CentOS/RHEL
-
使用
pstack
:sudo pstack PID
使用 /proc
文件系统
你可以通过 /proc
文件系统手动查看进程的栈信息。
-
找到进程ID(PID): 使用
ps
命令找到要调试的进程的PID。ps aux | grep program_name
-
查看栈内容: 使用
cat
或hexdump
查看/proc/[PID]/stack
文件。cat /proc/PID/stack
该文件也可以通过
hexdump
以更易读的方式查看:hexdump -C /proc/PID/stack
7. netstat命令怎么使用?用来干啥?
netstat
命令用于显示网络相关信息,例如网络连接、路由表、接口状态等。常用参数包括netstat -an
查看所有网络连接,netstat -tuln
查看所有监听端口。
8. Linux网络抓包用什么命令来实现?
可以使用tcpdump
或wireshark
来实现网络抓包。tcpdump
是一个命令行工具,而wireshark
提供图形界面,更加直观。
9. top命令用过嘛?如何查看僵死进程?
用过,top
命令用于显示系统的资源使用情况。
在top
界面中可以按z
来高亮显示僵死进程,或直接使用ps -aux | grep Z
命令来查看。
10. 进程,线程和协程有什么区别?
进程是资源分配的基本单位,线程是CPU调度的基本单位,而协程是一种用户态的轻量级线程。进程之间相互独立,线程共享进程的资源,而协程通过用户程序自己来调度,通常比线程更加高效。
进程(Process)
- 独立的内存空间:每个进程都有自己的独立的内存空间,不共享内存。
- 高开销:进程之间的上下文切换和进程的创建、销毁开销较大。
- 资源独立性:进程之间互相独立,不会因为一个进程的崩溃影响到另一个进程。
- 操作系统调度:由操作系统来进行调度和管理。
使用场景
- 用于需要完全隔离的任务运行,例如不同用户运行的应用程序。
- 多进程模型适用于多核CPU充分利用资源。
线程(Thread)
- 共享内存空间:同一进程内的所有线程共享内存,可以直接访问相同的数据段。
- 低开销:线程创建、销毁和上下文切换的开销比进程小。
- 资源共享:因为线程共享进程的资源,所以一个线程的崩溃可能会影响到整个进程。
- 操作系统调度:线程由操作系统的线程调度器进行调度,但与进程相比,调度的粒度通常更细。
使用场景
- 在同一个应用程序内需要并发执行的多个任务,例如多线程的Web服务器。
- 适合I/O密集型和需要频繁上下文切换的场景。
协程(Coroutine)
- 用户态切换:协程的切换在用户态进行,不需要内核态切换,开销更小。
- 非抢占式调度:协程由程序自身控制调度,不会被其他协程打断。
- 协作式多任务:协程通过“协作”进行上下文切换,显式地挂起和恢复。
- 共享内存空间:像线程一样,共享进程的内存空间,但因为是协作式的,数据共享的冲突更易控制。
使用场景
- I/O密集型任务,例如网络编程中的异步I/O处理。
- 需要大量并发但不需要多核心的运算的场景。
对比总结
内存独立性 | 独立 | 共享 | 共享 |
创建销毁开销 | 大 | 较小 | 最小 |
上下文切换开销 | 大 | 较小 | 最小 |
调度方式 | 操作系统调度,抢占式 | 操作系统调度,抢占式 | 用户态调度,协作式 |
编程复杂度 | 独立性高,易管理,不需同步 | 需处理同步和锁,复杂度较高 | 需显式挂起和恢复,代码可读性好 |
使用场景 | 多个独立的任务,需隔离的任务 | 单个应用的并发任务,如Web服务器 | 高并发I/O密集型任务,如网络编程 |
12. 进程之间的通信方式有哪些?
进程间通信(IPC)方式有:管道(Pipe)、消息队列(Message Queue)、共享内存(Shared Memory)、信号量(Semaphore)、套接字(Socket)等。
1.匿名管道(Pipes)
只能在有亲缘关系的进程(如父子进程)之间通信。
2.命名管道(Named Pipe 或 FIFO)
可以在任何无亲缘关系的进程之间通信。
3.消息队列(Message Queues)
- 多个发送者和多个接收者之间通信,具有有序性和持久性需求。
- 消息是按照发送顺序存储并读取的。
- 即使接收进程尚未启动,消息依然可以被发送。
4.共享内存(Shared Memory)
- 多个进程访问时需要处理同步问题。
- 需要高效大数据量传输和频繁通信的场景。
5.信号(Signals)
- 事件通知,例如时间到时的闹钟信号,用户中断信号等。
- 可以中断进程的当前操作,处理信号后返回。
6.套接字(Sockets)
- 可以在同一台机器上或通过网络在不同机器间通信。
- 支持TCP/UDP协议,适用于复杂的网络应用。
7.信号量(Semaphores)
- 进程间的同步和控制,例如进程对共享资源的互斥访问。
- 信号量可以是一个计数器,用于多个进程间同步。
14. 前端发起请求之后到达后端,中间过程是什么?
1.客户端发起请求
2.DNS解析
- 浏览器检查缓存,如果没有找到需要的IP地址,会向本地DNS服务器请求。
- 本地DNS服务器如果没有对应的IP地址,会向根DNS服务器查询,直到获取到目标服务器的IP地址,并返回给浏览器。
3.建立TCP连接
- 使用目标服务器的IP地址和端口号,通过三次握手(TCP三次握手)建立一个TCP连接。
4.发送HTTP请求
- 浏览器通过已建立的TCP连接,发送HTTP请求(包括请求行、请求头、请求体等)。
5.网络传输
- 请求通过网络传输,包括可能的路由跳转、负载均衡、CDN(内容分发网络)等。
- 使用HTTPS时,会在这里进行SSL/TLS握手,建立加密连接。
6.服务器接收请求
- 后端服务器接收到请求包。
- Web服务器(如Nginx、Apache等)处理基础的请求任务,如负载均衡、静态资源提供等。
7.应用服务器处理请求
- Web服务器将请求转发给应用服务器(如Tomcat、Node.js等)。
- 中间件(如Spring、Express等)处理路由和中间件函数,如验证、日志记录等。
8.业务逻辑处理
- 应用服务器依据请求路径和参数,将请求分发到对应的业务处理逻辑中。
- 可能会进行数据库查询、调用其他API服务、业务逻辑运算等操作。
9.数据库及外部系统交互
- 如果需要数据库查询,应用服务器会构造SQL语句或者请求ORM(对象关系映射)框架。
- 数据库接收请求并返回结果。
- 可能还会调用其他微服务或第三方API,并处理响应结果。
10.构建响应
- 应用服务器完成业务处理后,构建HTTP响应,包括状态码、响应头和响应体。
- 响应体可能是HTML页面、JSON数据、XML数据等。
11.发送响应
- 应用服务器将HTTP响应通过TCP连接发送回客户端。
12.客户端接收响应
- 浏览器接收到HTTP响应。
- 浏览器检查HTTP状态码,根据状态码决定后续处理。
13.处理和渲染
- 如果响应是HTML,浏览器启动HTML解析器解析页面。
- 如果响应是JSON数据,JavaScript代码处理数据并更新DOM或执行其他操作。
- 进行后续资源的请求和加载(如CSS、JS文件)。
14.关闭连接
全部评论
(12) 回帖