1.技术面试题
(1)解释Linux中的进程、线程和守护进程的概念,以及如何管理它们?
答:进程:进程是程序(可执行文件)的一次动态执行实例,是 Linux 系统进行资源分配和调度的基本单位。进程管理的核心是查看状态、控制生命周期、调整优先级。常用的命令有:查看进程列表—ps aux,终止进程–pkill 进程名。
线程:线程是进程内的一个执行单元,是 CPU 调度的基本单位(比进程更轻量)。“一个进程可以包含多个线程”。线程是进程的一部分,管理需结合进程上下文,核心是查看进程内的线程及资源占用。常用的命令有:查看进程内的线程—PS -T -p PTD。
守护进程:守护进程是在后台长期运行的特殊进程,独立于控制终端(无交互界面),通常用于提供系统服务(如网络服务、定时任务)。守护进程通常以 “服务” 形式存在,现代 Linux 通过systemd
管理,核心是启动 / 停止服务、设置自启动。常用的命令有:查看守护进程:ps -ef
(2)请详细描述OSI七层模型和TCP/IP四层模型,并说明它们之间的对应关系。每一层的主要功能是什么?各层有哪些典型的协议?
答:OSI 七层模型和 TCP/IP 四层模型是两种最核心的网络体系结构模型。前者是理论上的标准化框架,后者是实际应用中占主导地位的协议体系。
OSI七层模型从低到高依次为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。
1. 物理层
核心功能:负责将原始的比特流(0 和 1)通过物理介质(如电缆、光纤、无线信号)传输,是网络通信的物理基础。
:无严格意义上的 “协议”
2. 数据链路层
-
核心功能:将物理层的比特流封装为 “帧”(Frame),实现相邻节点(如两台直接连接的设备)之间的可靠传输。
-
典型协议
以太网(Ethernet):局域网中最常用的协议,定义了帧格式和 MAC 地址规则。
3. 网络层
- 核心功能:实现跨网络(不同局域网或广域网)的数据包传输,解决 “端到端” 的路由选择问题。
- 典型协议
- IP(Internet Protocol):核心协议,定义 IP 地址格式和数据包结构,负责跨网络路由。
- 路由协议:如 RIP(Routing Information Protocol)、OSPF(Open Shortest Path First),用于路由器之间交换路由信息,生成路由表。
4. 传输层
- 核心功能:为上层(应用层)提供 “端到端” 的可靠数据传输服务,屏蔽底层网络的差异。
- 典型协议
- TCP(Transmission Control Protocol):面向连接的协议,提供可靠传输(通过三次握手建立连接、确认机制、重传机制),适用于对可靠性要求高的场景(如文件传输、网页加载)。
- UDP(User Datagram Protocol):无连接协议,不保证可靠传输,但速度快、开销小,适用于实时性要求高的场景(如视频通话、直播、DNS 查询)。
5. 会话层
- 核心功能:管理 “会话”(即两个应用程序之间的通信过程),负责会话的建立、维护和终止。
- 典型协议
- RPC(Remote Procedure Call):远程过程调用协议,允许一台计算机的程序调用另一台计算机的程序,会话层负责管理调用过程的会话。
- NetBIOS(Network Basic Input/Output System):用于局域网中进程间通信的会话管理协议。
6. 表示层
- 核心功能:处理数据的 “表示形式”,确保发送方和接收方对数据的格式理解一致。
- 典型协议 / 标准
- JPEG、PNG:图像格式标准,属于表示层对数据格式的定义。
7. 应用层
- 核心功能:直接为用户或应用程序提供网络服务,是用户与网络的接口。
- 典型协议
- DNS(Domain Name System):域名解析协议,将域名(如www.baidu.com)转换为 IP 地址。
TCP/IP四层模型(从底层到高层):网络接口层、网络层、传输层、应用层。
- 网络接口层
- 核心功能:对应 OSI 模型的物理层和数据链路层,负责将网络层的数据包通过物理介质传输。
具体包括:比特流传输(物理层功能)、帧封装与 MAC 地址识别(数据链路层功能),是 TCP/IP 模型与物理网络的接口(如以太网、Wi-Fi、PPP 链路)。 - 典型协议:与 OSI 数据链路层和物理层协议一致,如以太网(Ethernet)、PPP、Wi-Fi(802.11 系列)。
2. 网络层
- 核心功能:与 OSI 网络层功能几乎一致,负责跨网络的数据包路由和转发,是 TCP/IP 模型的核心。
具体包括:IP 地址定义、路由选择、数据包分片与重组。 - 典型协议:与 OSI 网络层协议一致,如 IP(IPv4/IPv6)、ICMP、ARP、RIP、OSPF。
3. 传输层
- 核心功能:与 OSI 传输层功能一致,提供端到端的可靠或高效传输服务。
具体包括:TCP(可靠传输)和 UDP(高效传输)的实现,数据分段与重组,流量控制。 - 典型协议:与 OSI 传输层协议一致,即 TCP 和 UDP。
4. 应用层
- 核心功能:整合了 OSI 模型的会话层、表示层和应用层功能,直接为应用程序提供服务。
具体包括:会话管理(会话层功能)、数据格式处理(表示层功能)、特定应用服务(应用层功能),无需严格区分会话和表示逻辑,协议设计更灵活。 - 典型协议:与 OSI 应用层协议基本一致,但涵盖了更多功能(如 HTTP 同时处理数据格式、会话管理和网页传输),如 HTTP、FTP、SMTP、DNS、SSH(远程登录协议)。
(3)详细介绍什么是最大堆/最小堆。
答:一、最大堆(Max Heap)
1. 定义
- 结构特性:最大堆是一棵完全二叉树(除最后一层外,每一层都被完全填充,且最后一层的节点都靠左排列)。
- 值特性:每个节点的值都大于或等于其子节点的值。因此,堆顶元素(根节点)是整个堆中的最大值。
核心操作
-
插入(Insert):
- 将新元素插入到堆的末尾(保持完全二叉树结构)。
- 上浮(Heapify-Up):若新元素的值大于其父节点,则交换两者位置,重复此过程直到满足堆性质。
- 时间复杂度:O (log n),n 为堆中元素数量。
-
删除最大值(Extract Max):
- 移除堆顶元素(最大值)。
- 将堆的最后一个元素移到堆顶。
- 下沉(Heapify-Down):若新堆顶的值小于其子节点,则与较大的子节点交换位置,重复此过程直到满足堆性质。
- 时间复杂度:O(log n)。
-
获取最大值(Get Max):直接返回堆顶元素,时间复杂度为 O (1)。
最小堆
1. 定义
- 结构特性:与最大堆相同,是一棵完全二叉树。
- 值特性:每个节点的值都小于或等于其子节点的值。因此,堆顶元素(根节点)是整个堆中的最小值。
操作与最大堆相反。
(4)详细介绍什么是二分搜索树。
答:结构特性
-
二叉树:每个节点最多有两个子节点(左子节点和右子节点)。
-
有序性
:对于树中的每个节点,满足以下条件:
- 左子树的所有节点值 小于 当前节点值。
- 右子树的所有节点值 大于 当前节点值。
-
无重复值:通常不允许存在值相同的节点(某些变体允许重复值,但需额外规则处理)。
查找
-
目标:判断某个值是否存在于树中。
-
过程
:
- 从根节点开始比较。
- 若目标值等于当前节点值,返回成功。
- 若目标值小于当前节点值,递归查找左子树。
- 若目标值大于当前节点值,递归查找右子树。
- 若到达空节点,返回失败。
-
时间复杂度:平均 O (log n),最坏 O (n)(退化为链表时)。
插入
-
目标:将新值添加到树中,保持 BST 性质。
-
过程
:
- 从根节点开始,若树为空,直接创建新节点作为根。
- 若新值小于当前节点值,递归插入到左子树。
- 若新值大于当前节点值,递归插入到右子树。
- 若遇到空位置,创建新节点并插入。
-
时间复杂度:平均 O (log n),最坏 O (n)。
删除
-
目标:移除指定值的节点,保持 BST 性质。
-
过程
:
- 情况 1:待删除节点是叶子节点,直接移除。
- 情况 2:待删除节点只有一个子节点,用子节点替换该节点。
- 情况 3:待删除节点有两个子节点,找到其右子树的最小节点(或左子树的最大节点),用该最小值替换待删除节点,然后删除原最小值节点。
-
时间复杂度:平均 O (log n),最坏 O (n)。
遍历
- 中序遍历(In-order):左子树 → 根节点 → 右子树。
结果:按升序输出所有节点值。
示例树的中序遍历结果:1, 3, 4, 6, 7, 8, 10, 13, 14
。 - 前序遍历(Pre-order):根节点 → 左子树 → 右子树。
- 后序遍历(Post-order):左子树 → 右子树 → 根节点。
应用场景
- 高效查找:数据库索引(如 B 树、B + 树是 BST 的扩展)。
- 动态数据集合:需要频繁插入、删除和查找的数据结构。
- 排序:中序遍历 BST 可得到有序序列(时间复杂度 O (n))。
- 优先队列:通过维护最大或最小 BST 实现。
2.HR面试题
(1)我们非常欣赏你的能力,但目前只能提供比你期望薪资低20%的offer。在这种情况下,你会接受这份工作吗?如果接受,你对未来薪资增长有什么期望?如果不接受,你的底线是什么?
答:我会先深入了解岗位的核心价值 —— 比如是否能接触到核心业务、是否有完善的培训体系、团队是否有行业顶尖的资源或技术沉淀,以及公司对这个岗位的定位。
如果岗位本身能为我提供不可替代的成长机会(比如能快速积累关键经验、参与核心项目,或在目标领域实现能力突破),且公司有明确的薪资调整机制(如基于绩效的定期调薪、晋升通道透明),我会愿意接受这份 offer。因为短期的薪资差距,可能通过长期的能力提升和职业发展弥补,而核心能力的积累对职业生涯的价值更长远。
如果岗位的成长价值、发展空间与薪资差距不匹配(比如岗位内容重复机械、缺乏成长机会,且公司没有明确的调薪机制),我的底线会基于 “市场公允性” 和 “个人价值匹配度”。一般差距不会超过10%。
(2)我们公司经常需要加班到深夜,有时甚至需要周末工作。你如何看待这种工作强度?你认为工作与生活的理想平衡点在哪里?
答:我能理解工作中存在 “阶段性高强度” 的必要性 —— 比如紧急项目冲刺、业务攻坚期,这时加班到深夜或周末投入,是团队共同达成目标的正常协作,我会积极配合。但如果是 “常态化无意义加班”(比如因流程低效、分工不合理导致的拖延,或单纯为了 “加班而加班” 的形式主义),这种强度不仅会消耗个人精力,还会降低长期工作效率,反而不利于团队和业务的可持续发展。
所以,我的原则是:接受 “目标驱动的必要加班”,但拒绝 “低效内耗的过度加班”。如果加入贵公司,我会优先通过优化工作方法(比如提前规划、拆解任务、提升专注度)提高日常效率,尽量减少不必要的加班;若遇紧急情况,也会主动承担,确保目标达成。
我认为两者并非对立,而是 “相互滋养” 的关系 ——工作的成就感能让生活更有底气,生活的松弛感能反哺工作的创造力。
简单来说,我不排斥为有价值的目标付出额外精力,但更看重 “加班的性价比”—— 既要能解决问题、创造价值,也要保留足够的自我更新空间。毕竟,可持续的战斗力,才是个人和团队长期走得远的关键。
(3)你认为自己最大的优势是什么?这个优势如何帮助你胜任我们这个岗位?
答:我认为我的优势在于:自身扎实的能力和与与团队的沟通和协作能力。扎实的能力可以帮助我快速适应工作环境和工作内容,发挥自身价值(加一些对岗位的了解和与那些能力对接)。而在如今的工作环境中我深知一个人很难完成一些大的 任务,需要团队协助才能高效的完成任务,所以我快速融入团队的能力也会更好的发挥我能力。
(4)你认为这份工作能为你带来什么?你能为公司创造什么价值?
答:这个问题的核心是 “双向价值”—— 工作为我提供成长的土壤,我则用成长反哺公司的发展。具体可以从以下两方面展开:
对我而言,这份工作的核心意义在于 “实践中成长 + 价值感落地”
工作中会接触到不同行业的业务逻辑、用户的真实痛点、团队的协作模式,这些信息能帮我跳出单一视角,建立更立体的认知 —— 比如理解 “用户为什么需要这个功能”“公司业务的核心卡点是什么”,这种认知的深化不仅能提升工作质量,更能让我更贴近 “创造实际价值” 的本质。
当我的输出能切实帮用户解决问题(比如一篇文案推动了产品转化、一个解答帮用户理清了思路),或为团队节省了时间(比如优化了流程、沉淀了经验),这种 “被需要” 的感觉是内在驱动力的核心。工作的意义,正是让能力通过创造价值而被看见。
结合岗位需求,我的价值可体现为
面对高频问题或典型任务,我能主动总结规律,形成标准化的解决方案或方法论,供团队复用。这不仅能提升整体工作效率,还能降低新人上手的成本,让 “个体能力” 转化为 “组织能力”。
对团队:在协作中主动对齐需求、输出结构化成果,减少内部沟通损耗,让团队更聚焦核心业务。
“补充岗位与自身能力的对接方向和内容,自身掌握能力优势“
3.问答题
(1)以下代码运行结果是?并阐述函数func的主要功能是什么?
def func(lst):
result = []
for i in range(len(lst)):
if i == len(lst) - 1:
result.append(lst[i] * 2)
elif lst[i] < lst[i+1]:
result.append(lst[i] + 1)
else:
result.append(lst[i] - 1)
return result
print(func([5, 3, 7, 2]))
答:[4, 4, 6, 4]
如果列表的当前元素小于后一个元素时加一,大于时减一。如果为最后一个时元素将元素乘以二。
(2)以下代码运行结果是?并阐述函数func的主要功能是什么?
def func(lst):
result = []
for num in lst:
if num % 3 == 0:
result.append(num // 3)
elif num % 2 == 0:
result.append(num * 2)
if num > 10:
break
else:
result.append(num + 1)
return result
print(func([9, 4, 12, 7, 14]))
答:[3,8,4,8,28]
如果列表元素可以整除3则该元素整除3,如果不能则看是否能整除2,能则该元素乘以2,在判断该元素是否大于10,大于则结束循环。若也不能整除2则元素加一
(3)以下代码运行结果是?并阐述函数func的主要功能是什么?
def func(nums1, m, nums2, n):
i = j = k = 0
temp = nums1.copy()
while i < m and j < n:
if temp[i] < nums2[j]:
nums1[k] = temp[i]
i += 1
else:
nums1[k] = nums2[j]
j += 1
k += 1
while i < m:
nums1[k] = temp[i]
i += 1
k += 1
return nums1
nums1 = [1, 3, 5, 0, 0]
m = 3
nums2 = [2, 4]
n = 2
print(func(nums1, m, nums2, n))
答:[1,2,3,4,5]
这个函数的作用是将两个有序数组合并为一个有序数组,并直接修改第一个数组(nums1
)以存储合并后的结果。“0为占位符”
(4)以下代码运行结果是?并阐述函数func的主要功能是什么?
def func(lst):
total = 0
for i in range(len(lst)):
if i % 2 == 0:
total += lst[i]
else:
total -= lst[i]
if total < 0:
total = 0
return total
print(func([5, 3, 2, 7, 1]))
答:1
交替加减
对列表中索引为偶数的元素(位置 0、2、4…)执行加法。
对列表中索引为奇数的元素(位置 1、3、5…)执行减法。
- 非负约束:每次运算后,如果总和变为负数,则将其重置为 0。
- 最终返回:整个过程结束后的累计总和。
(5)以下代码运行结果是?并阐述函数func的主要功能是什么?
def func(lst):
evens = []
odds = []
for num in lst:
if num % 2 == 0:
evens.append(num)
else:
odds.append(num)
evens.sort()
odds.sort(reverse=True)
return evens + odds
print(func([3, 1, 4, 1, 5, 9, 2, 6, 5]))
答:[2,4,6,9,5,5,3,1,1]
将列表偶数按升序排前,奇数按倒序排后。
(6)以下代码运行结果是?并阐述函数func的主要功能是什么?
def func(lst):
result = []
for i in range(len(lst)):
current = lst.pop(0)
if current % 2 == 0:
lst.append(current * 2)
else:
result.append(current)
return result + lst
data = [1, 2, 3, 4, 5]
print(func(data))
答:[1,3,5,4,8]
若列表的元素为奇数则弹出,并添加到result中,若为偶数则乘以二,最后将result和lst拼接。
(7)以下代码运行结果是?并阐述函数func的主要功能是什么?
def func(lst):
result = []
for i in range(len(lst)):
for j in range(i+1, len(lst)):
if lst[i] + lst[j] == 10:
result.append((lst[i], lst[j]))
break
return result
print(func([5, 3, 7, 2, 8]))
答:[(3,7),(2,8)]
这个函数的作用是在列表中查找所有和为 10 的不重复整数对,并返回这些数对的元组列表。
(8)编写程序,反素数
反素数是指一个将其逆向拼写后也是一个素数的非回文数,例如17和71都是素数但不是回文数,且反转后依旧是素数
输出显示前100个反素数,每行显示10个
答:
def aaa(num):
for i in range(2, num):
if num % i == 0:
return False
return True
def bbb(num):
re_num = 0
while num != 0:
re_num = re_num * 10 + num % 10
num //= 10
return re_num
def ccc(num):
return bbb(num) == num
num = 13
a = 0
while True:
if aaa(num) == True and aaa(bbb(num)) == True and ccc(num) == False:
a+=1
print(num,end=" ")
if a%10 == 0:
print()
if a > 99:
break
num += 1
(9)编写程序,梅森素数
如果一个素数可以写成 2 p − 1 2^p-1 2p−1的形式,其中p是某个正整数,那么这个素数就称作梅森素数
输出p≤31的所有梅森素数
答:
def aaa(num):
for i in range(2,num):
if num % i == 0:
return False
return True
def bbb(num):
for i in range(32):
if num == 2**i - 1:
return True
return False
num = 0
while True:
if aaa(num)==True:
if bbb(num)==True:
print(num)
num += 1
if num>2**31-1:
break
(10)编写程序,数列求和
编写一个函数计算下面的数列:
m ( i ) = 1 2 + 2 3 + . . . + i i + 1 m(i) = \frac{1}{2} + \frac{2}{3} + ... + \frac{i}{i + 1} m(i)=21+32+...+i+1i
并输出测试结果:
i m(i)
1 0.500
2 1.16
...
19 16.40
20 17/35
答:
def aaa(i):
m = 0.0
float(m)
for a in range(1,i+1):
m += a/(a+1)
return m
print("i\tm(i)")
for i in range(1,21):
b = aaa(i)
print(f"{i}\t{b:.4f}")
(11)编写程序,组合问题
有1、2、3、4这个四个数字,能组成多少个互不相同且无重复数字的三位数?分别又是多少?
答:
a = 0
for i in range(1, 5):
for j in range(1, 5):
for k in range(1, 5):
if i != j and i != k and j != k:
print(f"{i}{j}{k}", end=" ")
a += 1
print(f"共有{a}个符合条件的三位数")
(12)编写程序,计算e
你可以使用下面的数列近似计算e
e
=
1
+
1
1
!
+
1
2
!
+
1
3
!
+
1
4
!
+
.
.
.
+
1
i
!
e=1+\frac{1}{1!}+\frac{1}{2!}+\frac{1}{3!}+\frac{1}{4!}+...+\frac{1}{i!}
e=1+1!1+2!1+3!1+4!1+...+i!1
当i越大时,计算结果越近似于e
答:
def aaa(num):
e = 1
for i in range(1,num+1):
e += 1 / (bbb(i))
return e
def bbb(i):
b = 1
for a in range(1,i+1):
b *= a
return b
num = int(input())
print(aaa(num))
(13)编写程序,完全数
如果一个正整数等于除了它本身之外所有正因子的和,那么这个数称为完全数
例如 6 = 3 + 2 + 1,28 = 14 + 7 + 4 + 2 + 1
输入输出描述
输入一个正整数
输出该数是否为完全数
示例1
输入:
6
输出:
Yes
示例2
输入:
9
输出:
No
答:
num = int(input())
a = 0
for i in range(1,num):
if num % i == 0:
a += i
if num == a:
print("Yes")
else:
print("No")