1.技术面试题
(1)解释Linux中的进程、线程和守护进程的概念,以及如何管理它们?
答:进程(Process)
定义:进程是程序在系统中的动态执行实例,包含程序代码、数据、寄存器状态及系统资源分配信息。每个进程拥有独立的地址空间和资源,是系统资源分配的基本单位。
管理方法:
-
查看进程
ps aux:显示所有进程详细信息(用户、PID、CPU/内存占用等)。top:实时动态查看进程资源占用,支持按CPU/内存排序。pstree -p:以树形结构展示进程父子关系。
-
控制进程
- 前台/后台切换:
&(后台运行)、Ctrl+Z(挂起)、bg/fg(恢复后台/前台)。 - 终止进程:
kill -9 PID(强制终止)、pkill -f "name"(按名称终止)。
- 前台/后台切换:
-
优先级调整
-
nice -n 10 command:以低优先级启动进程。 -
renice -5 PID:动态调整运行中进程的优先级。二、线程(Thread)
定义:线程是进程内的执行单元,共享进程的地址空间和资源(如文件描述符、内存),但拥有独立的栈和寄存器状态。线程是CPU调度的基本单位,多线程可实现并行任务处理。
管理方法:
-
创建线程
-
POSIX线程库(
pthread):
#include <pthread.h> void* thread_func(void* arg) { /* 线程逻辑 */ } pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); // 创建线程
-
-
线程同步
- 互斥锁(
pthread_mutex_t):保护共享数据。 - 条件变量(
pthread_cond_t):实现线程间通知机制。
- 互斥锁(
-
查看线程
ps -eLf:显示所有线程(LWP列表示线程ID)。top -H:实时查看线程资源占用。
-
-
三、守护进程(Daemon)
定义:守护进程是脱离终端控制、在后台持续运行的特殊进程,通常用于提供系统服务(如Web服务器、日志服务)。其生命周期与系统启动/关闭同步,不依赖用户登录状态。
管理方法:
-
创建守护进程
-
关键步骤:
fork()创建子进程,父进程退出(使子进程成为孤儿进程,由init/systemd接管)。setsid()创建新会话,脱离终端控制。chdir("/")切换工作目录至根目录,避免占用文件系统。umask(0)重置文件权限掩码,确保最大灵活性。- 关闭标准文件描述符(
stdin/stdout/stderr),重定向至/dev/null。
-
示例代码片段:
#include <unistd.h> void daemonize() { pid_t pid = fork(); if (pid > 0) exit(0); // 父进程退出 if (pid < 0) exit(1); // 错误处理 setsid(); // 创建新会话 chdir("/"); // 切换工作目录 close(0); close(1); close(2); // 关闭标准文件描述符 }
-
-
启动/停止守护进程
-
SysVinit系统:通过
/etc/init.d/下的脚本管理(如/etc/init.d/nginx start)。 -
systemd系统
:使用
.service文件定义服务(如
/etc/systemd/system/mydaemon.service):
[Unit] Description=My Daemon Service After=network.target [Service] Type=simple ExecStart=/usr/local/bin/mydaemon Restart=on-failure [Install] WantedBy=multi-user.target-
操作命令:
sudo systemctl start mydaemon # 启动 sudo systemctl enable mydaemon # 设置开机自启 sudo systemctl status mydaemon # 查看状态
-
-
(2)请详细描述OSI七层模型和TCP/IP四层模型,并说明它们之间的对应关系。每一层的主要功能是什么?各层有哪些典型的协议?
答:一、OSI七层模型
-
物理层(Physical Layer)
- 功能:传输原始比特流(0/1电信号),定义物理介质特性(如电缆类型、信号编码方式)。
- 典型设备:中继器、集线器、网卡。
- 协议:IEEE 802.3(以太网)、RJ45。
-
数据链路层(Data Link Layer)
-
功能:将比特流组装成帧,提供节点间可靠传输(错误检测、流量控制、MAC地址管理)。
-
子层
:
- MAC子层:管理物理地址(MAC地址)。
- LLC子层:处理逻辑链路控制。
-
典型设备:交换机、网桥。
-
协议:PPP、VLAN、STP、HDLC。
-
-
网络层(Network Layer)
- 功能:数据包路由选择与逻辑寻址(IP地址转换),实现跨网络通信。
- 典型设备:路由器。
- 协议:IP、ICMP、ARP、RARP、OSPF。
-
传输层(Transport Layer)
- 功能:端到端可靠传输(分段、流量控制、差错恢复),通过端口号标识应用进程。
- 典型设备:网关。
- 协议:TCP(可靠)、UDP(不可靠)、SPX。
-
会话层(Session Layer)
- 功能:建立、管理和终止会话,支持数据交换同步(如检查点恢复)。
- 协议:NFS、SQL、NETBIOS。
-
表示层(Presentation Layer)
- 功能:数据格式转换(如ASCII/JPEG)、加密解密、压缩解压。
- 协议:JPEG、MPEG、ASCII。
-
应用层(Application Layer)
- 功能:为用户提供网络服务接口(如文件传输、邮件收发)。
- 协议:HTTP、FTP、DNS、SMTP、Telnet。
二、TCP/IP四层模型
- 网络接口层(Network Interface Layer)
- 功能:处理物理网络介质访问(如以太网帧传输、Wi-Fi信号调制)。
- 协议/技术:Ethernet、Wi-Fi、PPP、MAC地址。
- 网络层(Internet Layer)
- 功能:数据包路由选择与逻辑寻址(IP地址管理),实现主机间通信。
- 协议:IP、ICMP、ARP、RARP。
- 传输层(Transport Layer)
- 功能:端到端数据传输(可靠传输用TCP,高效传输用UDP)。
- 协议:TCP、UDP。
- 应用层(Application Layer)
- 功能:直接为应用程序提供服务(如Web浏览、邮件传输)。
- 协议:HTTP、FTP、DNS、SMTP、HTTPS。
| OSI七层模型 | TCP/IP四层模型 | 对应关系说明 |
|---|---|---|
| 应用层、表示层、会话层 | 应用层 | TCP/IP将OSI上三层功能整合,提供统一应用接口(如HTTP同时处理数据格式与会话管理)。 |
| 传输层 | 传输层 | 均负责端到端可靠传输(TCP/UDP对应OSI的TCP/UDP)。 |
| 网络层 | 网络层 | 均实现数据包路由与逻辑寻址(IP协议核心功能一致)。 |
| 数据链路层、物理层 | 网络接口层 | TCP/IP将OSI下两层合并,处理物理介质访问与帧传输(如以太网协议跨两层实现)。 |
(3)详细介绍什么是最大堆/最小堆。
答:最大堆(Max Heap)
定义:父节点的值 ≥ 子节点的值,根节点为全局最大值。
关键操作:
- 插入(Insert)
- 步骤
- 将新元素添加到堆末尾(完全二叉树最后一个位置)。
- 上浮(Heapify Up):比较新节点与父节点值,若大于父节点则交换,重复直到满足堆序。
- 时间复杂度**:O(log n)(树高度级操作)。
- 步骤
- 删除最大值(Extract Max)
- 步骤
- 移除根节点(最大值),将末尾节点移至根位置。
- 下沉(Heapify Down):比较当前节点与子节点值,若小于较大子节点则交换,重复直到满足堆序。
- 时间复杂度:O(log n)。
- 步骤
- 建堆(Build Heap)
- 自底向上法:从最后一个非叶子节点(索引
n/2 - 1)开始,对每个节点执行下沉操作。 - 时间复杂度:O(n)(数学证明:比逐个插入的 O(n log n) 更高效)。
- 自底向上法:从最后一个非叶子节点(索引
最小堆(Min Heap)
定义:父节点的值 ≤ 子节点的值,根节点为全局最小值。
关键操作:
- 插入(Insert)
- 类似最大堆,但上浮时比较是否 小于 父节点。
- 删除最小值(Extract Min)
- 类似最大堆,但下沉时比较是否 大于 较小子节点。
- 建堆(Build Heap)
- 同样采用自底向上法,时间复杂度 O(n)。
(4)详细介绍什么是二分搜索树。
答:
一、定义与核心特性
**二分搜索树(BST)**是一种特殊的二叉树,满足以下性质:
-
节点值有序性
:
- 对于任意节点,其 左子树 的所有节点值 均小于 该节点的值。
- 其 右子树 的所有节点值 均大于 该节点的值。
-
递归结构:左子树和右子树也必须是二分搜索树。
-
无重复值(通常约定):若允许重复值,可定义左子树 ≤ 节点值 ≤ 右子树。
2.HR面试题
(1)我们非常欣赏你的能力,但目前只能提供比你期望薪资低20%的offer。在这种情况下,你会接受这份工作吗?如果接受,你对未来薪资增长有什么期望?如果不接受,你的底线是什么?
答:首先肯定公司价值,建立情感共鸣:
“非常感谢贵司对我的认可,也理解当前市场环境和公司薪酬体系的限制。这个岗位的业务方向/团队配置/技术栈(根据实际情况补充)与我的职业规划高度契合,我本身对加入团队有很强的意愿。”
若公司薪资结构透明,可进一步说明:
“根据我前期调研的行业报告(如猎聘、脉脉数据),同岗位在XX地区的中位数薪资约为XX万,结合我的经验(如X年XX领域经验、主导过XX项目),期望薪资XX万是合理范围。当前offer与市场水平存在XX%的差距,能否请您帮忙分析具体原因?
若公司发展潜力大、岗位能带来核心能力提升,可表达接受意愿,但需绑定明确的薪资增长路径:
“如果加入团队,我希望薪资增长能与个人价值创造挂钩。例如:
- 短期:能否在3-6个月内设定明确的考核目标(如完成XX项目、达成XX业绩),若达标则薪资调整至XX万?
- 长期:公司是否有晋升通道(如从初级到高级/专家岗)?晋升后薪资涨幅通常是多少?
- 补充福利:是否可以通过增加期权、培训预算、弹性工作制等方式弥补现金差距?”
示例话术:
“我理解当前薪资限制,但希望未来1-2年内能通过绩效证明价值,将年薪提升至XX万。能否在offer中增加一条:若年度绩效评估为A/B级,次年薪资涨幅不低于15%?”
总结:展现长期思维
无论接受与否,最后需回归职业发展规划:
“我始终相信,薪资是个人价值的体现。如果贵司能提供清晰的成长路径和价值认可机制,我愿意与团队共同成长;如果当前条件确实存在差距,也希望未来有机会再合作。”
(2)我们公司经常需要加班到深夜,有时甚至需要周末工作。你如何看待这种工作强度?你认为工作与生活的理想平衡点在哪里?
答:表达对工作强度的理解与态度
1. 肯定公司价值,展现责任感
先认可公司业务需求,避免直接否定加班文化:
“我理解贵司所处的行业(如互联网、咨询、金融等)竞争激烈,项目周期紧张或业务高峰期(如大促、交付节点)需要团队高效协作,短期高强度工作是必要的,这也能让我更快熟悉业务、积累经验。”
2. 区分“有效加班”与“无效内耗”
强调对加班质量的关注,而非单纯接受无意义耗时间:
“但我更关注加班的目的性和效率。如果是为了冲刺关键目标、解决突发问题或学习新技能,我会全力配合;但如果是因流程低效、分工模糊或日常任务堆积导致的重复性加班,可能需要通过优化工作方式(如使用自动化工具、明确优先级)来减少无效投入。”
定义“平衡”的核心:动态调整而非绝对分割
避免非黑即白的回答,展现灵活性:
“我认为工作与生活的平衡不是简单的‘五五开’,而是根据职业阶段和个人目标动态调整。例如:
- 在项目攻坚期(如新产品上线),我愿意投入更多时间确保结果;
- 在非紧急阶段,我会通过高效时间管理(如番茄工作法、任务拆解)保证准时下班,留出时间充电或陪伴家人。”
(3)你认为自己最大的优势是什么?这个优势如何帮助你胜任我们这个岗位?
答:“我的核心优势是云原生环境下的资源优化与故障自愈能力,这能帮助企业在降本的同时提升运维效率。
例如,在帮助某制造企业迁移至阿里云时(Situation),其K8s集群资源利用率仅30%,且频繁出现Pod调度失败(Task)。我通过以下优化:
- 资源分析:用kubectl top和Vert.x工具定位到Java应用内存泄漏(Action);
- 调优方案:为JVM设置合理的-Xmx参数,并启用HPA(水平自动扩缩容)(Action);
- 成本优化:将Spot实例与预留实例混合使用,结合Cluster Autoscaler动态扩缩(Action);
- 结果:资源利用率提升至75%,月均云成本降低40%,故障率下降80%(Result)。
贵司的混合云架构(根据岗位信息推测)需要统一管理多云资源,我的经验可以帮助设计跨云监控方案(如Thanos+Loki),并通过GitOps(ArgoCD)实现配置标准化,减少人为操作风险。”
(4)你认为这份工作能为你带来什么?你能为公司创造什么价值?
答:双向价值绑定
-
工作能为你带来的价值
(个人成长):
- 技术能力提升(如云原生、AIOps、安全合规);
- 业务视野拓展(从“系统运维”到“业务连续性保障”);
- 职业路径发展(如向SRE、运维架构师转型)。
-
你能为公司创造的价值
(业务贡献):
- 稳定性价值:减少系统故障,提升MTTR(平均修复时间);
- 效率价值:通过自动化降低人工操作成本;
- 成本价值:优化资源利用率,节省云/硬件支出;
- 安全价值:构建合规防护体系,降低数据泄露风险。
关键原则:避免空谈“学习”或“贡献”,需用具体技术场景+量化结果证明。
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]
函数 func 的主要功能是对输入列表 lst 进行如下操作:
- 遍历列表:通过
for i in range(len(lst))遍历列表的每个元素。 - 条件判断:
- 最后一个元素:如果当前元素是列表中的最后一个元素(即
i == len(lst) - 1),则将该元素的值乘以 2 并添加到结果列表result中。 - 当前元素小于下一个元素:如果当前元素小于其下一个元素(即
lst[i] < lst[i+1]),则将当前元素的值加 1 并添加到结果列表result中。 - 其他情况:如果上述两种情况均不满足,则将当前元素的值减 1 并添加到结果列表
result中。
- 最后一个元素:如果当前元素是列表中的最后一个元素(即
(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]
函数 func 的主要功能是对输入列表 lst 中的每个元素 num 进行如下操作:
-
判断
num是否能被 3 整除:- 如果能,将
num除以 3 的结果添加到result列表中。
- 如果能,将
-
否则,判断
num是否能被 2 整除:- 如果能,将
num乘以 2 的结果添加到result列表中。
- 如果能,将
-
如果
num大于 10:- 立即退出循环(
break)。
- 立即退出循环(
-
否则:
- 将
num加 1 的结果添加到result列表中。
- 将
最终,函数返回处理后的 result 列表。
(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]
函数 func 的主要功能是 将两个已排序的数组合并为一个有序数组。具体来说:
-
参数:
nums1和nums2是两个已排序的数组。m和n分别是nums1和nums2中有效元素的数量。
-
实现逻辑:
- 首先复制
nums1到temp,以保留nums1的原始有效部分。 - 使用双指针方法,比较
temp和nums2中的元素,将较小的元素依次放入nums1中。 - 最后,如果
temp中还有剩余元素,将其依次放入nums1中。
- 首先复制
这样,函数就能有效地将两个有序数组合并为一个有序数组。
(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
函数 func 的主要功能是对输入列表 lst 进行如下操作:
- 遍历列表: 通过
for i in range(len(lst))遍历列表的每个元素。 - 条件累加/累减:
- 如果索引
i为偶数(i % 2 == 0),则将该位置的元素值加到total上。 - 如果索引
i为奇数,则将该位置的元素值从total中减去。
- 如果索引
- 非负保证: 如果在某一步操作后
total小于 0,则将total重置为 0。 - 返回结果: 最终返回
total的值。
(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]
函数 func 的主要功能
- 分离偶数和奇数:
遍历输入列表lst,将偶数(num % 2 == 0)和奇数分别存入两个子列表evens和odds。 - 排序处理:
- 偶数列表按升序排序(
evens.sort())。 - 奇数列表按降序排序(
odds.sort(reverse=True))。
- 偶数列表按升序排序(
- 合并结果:
将排序后的偶数列表和奇数列表拼接(evens + odds),偶数在前,奇数在后。
(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]
函数 func 的主要功能
- 分离奇数与偶数
- 遍历输入列表
lst,每次取出第一个元素(pop(0))。 - 如果是奇数,直接存入
result。 - 如果是偶数,将其乘以 2 后重新追加到
lst的末尾(延迟处理)。
- 遍历输入列表
- 动态修改列表
- 由于
pop(0)和append的操作,lst的长度可能在循环中增加(例如遇到偶数时)。 - 但循环次数由原始
len(lst)决定(本例中为 5 次),因此部分偶数会被重新处理(如4被处理两次)。
- 由于
- 合并结果
- 最终返回
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)]
函数 func 的主要功能是 在给定列表中找到所有和为 10 的数对,并返回这些数对的列表。具体步骤如下:
- 初始化结果列表:
result = [],用于存储找到的数对。 - 外层循环:遍历列表中的每个元素,索引为
i。 - 内层循环:从当前元素的下一个元素开始遍历,索引为
j(即j从i+1开始)。 - 条件判断:如果
lst[i] + lst[j] == 10,则将数对(lst[i], lst[j])添加到result列表中,并通过break语句退出内层循环,继续外层循环的下一个元素。
(8)编写程序,反素数
反素数是指一个将其逆向拼写后也是一个素数的非回文数,例如17和71都是素数但不是回文数,且反转后依旧是素数
输出显示前100个反素数,每行显示10个
答:
# Your Codes
def is_素数(n):
"""判断一个数是否为素数"""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def reverse_number(n):
"""反转数字"""
return int(str(n)[::-1])
def is_反素数(n):
"""判断是否为反素数"""
if not is_素数(n):
return False
reversed_n = reverse_number(n)
return n != reversed_n and is_素数(reversed_n)
def find_反素数(count):
"""查找指定数量的反素数"""
反素数 = []
num = 2
while len(反素数) < count:
if is_反素数(num):
反素数.append(num)
num += 1
return 反素数
# 查找前100个反素数
反素数_list = find_反素数(100)
print("前100个反素数:")
for i in range(0, 100, 10):
# 取出当前行的10个数字
line = 反素数_list[i:i+10]
# 将数字转换为字符串并调整宽度为4个字符
formatted_numbers = [f"{num:4}" for num in line]
# 用空格连接并打印
print(" ".join(formatted_numbers))
(9)编写程序,梅森素数
如果一个素数可以写成2p−12^p-12p−1的形式,其中p是某个正整数,那么这个素数就称作梅森素数
输出p≤31的所有梅森素数
答:
# Your Codes
def is_prime(n):
"""判断一个数是否为素数"""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
def find_meisen_primes(m):
"""找出所有p≤m的梅森素数"""
meisen_primes = []
for p in range(2, m + 1):
# 计算梅森数
梅森素数 = 2 ** p - 1
# 检查是否为素数
if is_prime(meisen_number):
meisen_primes.append((p, merisen_number))
return meisen_primes
# 找出p≤31的所有梅森素数
m = 31
result = find_meisen_primes(m)
# 输出结果
print(f"p ≤ {m} 的所有梅森素数:")
for p, meisen in result:
print(f"p = {p}: 2^{p} - 1 = {meisen}")
(10)编写程序,数列求和
编写一个函数计算下面的数列:
m(i)=12+23+...+ii+1m(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
答:
# Your Codes
def sulie_m(i):
total = 0.0
for n in range(1, i + 1):
total += n / (n + 1)
return total
print("i\tm(i)")
for i in range(1, 21):
result = sulie_m(i)
print(f"{i}\t{result:.2f}") # 一律保留2位小数
(11)编写程序,组合问题
有1、2、3、4这个四个数字,能组成多少个互不相同且无重复数字的三位数?分别又是多少?
答:
# Your Codes
digits = [1, 2, 3, 4]
# 用于存储所有可能的三位数
three_digit_numbers = []
for hundred in digits: # 百位数
for ten in digits: # 十位数
for unit in digits: # 个位数
# 确保三个数字都不相同
if hundred != ten and hundred != unit and ten != unit:
number = hundred * 100 + ten * 10 + unit
three_digit_numbers.append(number)
# 输出结果
print("用1、2、3、4可以组成以下互不相同且无重复数字的三位数:")
for num in three_digit_numbers:
print(num, end=" ")
print("\n\n总共有", len(three_digit_numbers), "个这样的三位数")
(12)编写程序,计算e
你可以使用下面的数列近似计算e
e=1+11!+12!+13!+14!+...+1i!
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
答:
# Your Codes
n = int(input("请输入要计算的项数:"))
e = 1.0
for i in range(1, n+1):
# 计算阶乘
jiecheng = 1
for j in range(1, i+1):
jiecheng *= j
# 加上当前项 1/i!
e += 1 / jiecheng
print(f"e 的近似值(前 {n} 项):{e}")
(13)编写程序,完全数
如果一个正整数等于除了它本身之外所有正因子的和,那么这个数称为完全数
例如 6 = 3 + 2 + 1,28 = 14 + 7 + 4 + 2 + 1
输入输出描述
输入一个正整数
输出该数是否为完全数
示例1
输入:
6
输出:
Yes
示例2
输入:
9
输出:
No
答:
# Your Codes
n = int(input("请输入一个正整数:"))
sum = 0 # 存储因子之和
# 寻找所有小于n的因子
for i in range(1, n):
if n % i == 0: # 如果i是n的因子
sum += i
# 判断是否为完全数
if sum == n:
print("Yes")
else:
print("No")
87

被折叠的 条评论
为什么被折叠?



