Python第三次作业

1.技术面试题

(1)解释Linux中的进程、线程和守护进程的概念,以及如何管理它们?

答:

一、基本概念

  1. 进程
    进程是程序的一次动态执行过程,是操作系统进行资源分配(如内存、文件描述符)和调度的基本单位。每个进程拥有独立的地址空间,进程间相互隔离。例如,运行ls命令、打开浏览器等操作,都会创建新的进程。
  2. 线程
    线程是进程内部的执行单元,也被称为 “轻量级进程”。一个进程可以包含多个线程,所有线程共享该进程的资源(如内存空间、文件描述符),但每个线程有独立的栈和程序计数器。线程间的切换成本远低于进程,适合需要高并发且资源共享的场景(如多任务处理的应用程序)。
  3. 守护进程(Daemon)
    守护进程是运行在后台的特殊进程,独立于终端,通常在系统启动时自动运行,用于提供持续服务(如sshdhttpd)。它没有控制终端,不会因终端关闭而终止,生命周期通常与系统一致。

二、管理方式

  1. 进程管理
  • 查看进程
    • ps aux:查看系统中所有进程的详细信息(包括用户、PID、状态、资源占用等)。
    • top/htop:动态查看进程的实时资源占用(CPU、内存),支持交互操作(如终止进程、排序等)。
  • 创建进程
    • 直接执行命令(如python script.py)会自动创建新进程。
    • 编程中通过fork()(复制当前进程)或exec()(加载新程序替换当前进程)系统调用来创建进程。
  • 终止进程
    • kill [PID]:向指定 PID 的进程发送终止信号(默认SIGTERM,允许进程清理资源后退出)。
    • kill -9 [PID]:发送强制终止信号(SIGKILL),用于无法正常终止的进程(强制终止,不允许清理资源)。
    • pkill [进程名]:根据进程名终止进程(如pkill firefox)。
  • 进程状态控制
    • Ctrl+Z:暂停当前前台进程。
    • bg:将暂停的进程放到后台运行(需配合Ctrl+Z使用)。
    • fg:将后台进程调回前台运行。
    • jobs:查看当前终端中所有后台进程的列表。
  1. 线程管理
  • 查看线程
    • ps -T -p [PID]:查看指定进程(PID)内的所有线程(-T参数表示显示线程信息)。
    • top -H -p [PID]:查看指定进程内各线程的资源占用情况(-H参数表示按线程显示)。
  • 创建与同步
    • 线程的创建主要通过编程语言的线程库实现,例如 C 语言的pthread库(通过pthread_create()函数)、Python 的threading模块等。
    • 线程间共享资源时,需通过锁机制(如互斥锁、信号量)进行同步,避免资源竞争问题。
  1. 守护进程管理
  • 查看守护进程
    守护进程通常以d为后缀(如sshdcrond),可通过ps aux | grep -v 'tty'过滤掉与终端相关的进程,剩下的多为守护进程。
  • 管理操作
    现代 Linux 系统中,守护进程多通过systemd进行管理,对应的命令为systemctl
    • systemctl start [服务名]:启动指定的守护进程(如systemctl start nginx)。
    • systemctl stop [服务名]:停止指定的守护进程。
    • systemctl restart [服务名]:重启指定的守护进程。
    • systemctl enable [服务名]:设置守护进程开机自启动。
    • systemctl status [服务名]:查看守护进程的运行状态(如是否活跃、PID 等)。

(2)请详细描述OSI七层模型和TCP/IP四层模型,并说明它们之间的对应关系。每一层的主要功能是什么?各层有哪些典型的协议?

答:

  1. 物理层(Physical Layer)
  • 主要功能:定义物理介质(如电缆、光纤、无线信号)的电气特性、机械规范、比特流传输规则,负责将数据转换为比特流(0 和 1)并在物理介质上传输,不涉及数据的意义或结构。
  • 典型协议:
    • 以太网物理层标准(如 10BASE-T、100BASE-TX)
    • 光纤传输标准(如 G.652 光纤规范)
    • 无线局域网物理层(如 802.11b/g/n 的物理层协议)
  1. 数据链路层(Data Link Layer)
  • 主要功能:将物理层的比特流封装为 “帧”(Frame),通过 MAC 地址(媒体访问控制地址)实现同一局域网内的节点寻址,同时处理帧的差错检测(如 CRC 校验)和流量控制,避免数据冲突(如以太网的 CSMA/CD 机制)。
  • 典型协议:
    • 以太网(Ethernet):定义帧结构和 MAC 地址规则
    • 无线局域网(WLAN,如 802.11 系列):无线环境下的帧传输协议
    • 点对点协议(PPP):用于拨号连接等点对点链路的帧封装
    • ARP(地址解析协议):将 IP 地址转换为 MAC 地址
  1. 网络层(Network Layer)
  • 主要功能:基于逻辑地址(如 IP 地址)实现跨网络的数据包路由和转发,解决不同局域网之间的通信问题,同时负责数据包的分片与重组(当数据包超过网络最大传输单元 MTU 时)。
  • 典型协议:
    • IP(网际协议):定义 IP 地址格式和数据包结构,是网络层核心协议
    • ICMP(互联网控制消息协议):用于传输网络错误信息(如 ping 命令的底层协议)
    • OSPF(开放最短路径优先)、BGP(边界网关协议):路由协议,用于计算最佳路径

4.传输层(Transport Layer)

  • 主要功能:提供端到端(源主机到目标主机的应用程序)的可靠或不可靠数据传输,负责数据的分段、重组、流量控制和差错恢复。
  • 典型协议:
    • TCP(传输控制协议):面向连接的可靠传输,通过三次握手建立连接,支持重传和流量控制(如 HTTP、FTP 依赖 TCP)
    • UDP(用户数据报协议):无连接的不可靠传输,速度快,适用于实时性要求高的场景(如视频流、DNS)

5.会话层(Session Layer)

  • 主要功能:管理应用程序之间的会话连接,包括会话的建立、维护、终止,以及数据交换的同步(如标记传输断点,以便后续恢复)。
  • 典型协议:
    • RPC(远程过程调用):允许一台计算机的程序调用另一台计算机的子程序,隐含会话管理
    • NetBIOS:用于局域网内计算机名称与 IP 地址的映射,包含会话建立功能

6.表示层(Presentation Layer)

  • 主要功能:处理数据的格式转换和呈现方式,确保不同系统的应用程序能理解对方的数据(如编码转换、加密解密、压缩解压)。
  • 典型协议:
    • JPEG、PNG:图像格式编码协议(处理数据呈现)
    • SSL/TLS:用于数据加密解密(保障数据安全传输)
    • ASCII、Unicode:字符编码转换协议
  1. 应用层(Application Layer)
  • 主要功能:为用户应用程序提供网络服务接口,直接与用户交互,定义特定应用的通信规则。
  • 典型协议:
    • HTTP/HTTPS:用于网页浏览的超文本传输协议
    • FTP(文件传输协议):用于文件上传和下载
    • DNS(域名系统):将域名转换为 IP 地址
    • SMTP(简单邮件传输协议)、POP3(邮局协议):用于电子邮件的发送和接收

二、TCP/IP 四层模型

TCP/IP 模型是实际互联网使用的协议体系,基于实用性设计,从下到上分为网络接口层、网络层、传输层、应用层。

1.网络接口层(Network Interface Layer)

  • 主要功能:整合 OSI 物理层和数据链路层的功能,负责数据在物理介质上的传输,处理帧的封装、MAC 寻址和比特流转换,依赖具体的物理网络技术(如以太网、Wi-Fi)。
  • 典型协议:
    • 以太网协议(包含物理层和数据链路层规范)
    • PPP(点对点协议)、SLIP(串行线路网际协议)
    • 无线局域网协议(802.11 系列)
  1. 网络层(Internet Layer)
  • 主要功能:与 OSI 网络层一致,基于 IP 地址实现数据包的路由选择和跨网络互联,核心是 IP 协议。
  • 典型协议:
    • IP(IPv4、IPv6):网络层核心协议
    • ICMP、IGMP(互联网组管理协议)
    • 路由协议(OSPF、RIP、BGP)
  1. 传输层(Transport Layer)
  • 主要功能:与 OSI 传输层一致,提供端到端的数据传输服务,支持 TCP(可靠)和 UDP(不可靠)两种方式。
  • 典型协议:
    • TCP、UDP(同 OSI 传输层)
    • SCTP(流控制传输协议):适用于实时通信的新型传输协议
  1. 应用层(Application Layer)
  • 主要功能:整合 OSI 应用层、表示层和会话层的功能,直接为应用程序提供服务,同时处理数据格式、会话管理等任务。
  • 典型协议:
    • HTTP/HTTPS、FTP、DNS、SMTP(同 OSI 应用层)
    • SSH(安全外壳协议):用于远程登录(包含会话和加密功能)
    • NFS(网络文件系统):用于远程文件共享(包含数据格式处理)

三、OSI 七层模型与 TCP/IP 四层模型的对应关系

  • TCP/IP 的应用层对应 OSI 的应用层、表示层、会话层:TCP/IP 将这三层的功能整合,让应用协议同时处理服务接口、数据格式转换和会话管理(如 HTTPS 既定义应用交互,又通过 TLS 加密数据,还维护连接状态)。
  • TCP/IP 的传输层与 OSI 的传输层直接对应:两者功能完全一致,均负责端到端的可靠 / 不可靠传输,核心协议 TCP、UDP 通用。
  • TCP/IP 的网络层与 OSI 的网络层直接对应:均基于 IP 地址实现路由和跨网络互联,协议(如 IP、ICMP、路由协议)作用相同。
  • TCP/IP 的网络接口层对应 OSI 的数据链路层和物理层:TCP/IP 将底层的物理传输和帧处理整合,不严格区分两层,统一负责数据在物理介质上的传输。

(3)详细介绍什么是最大堆/最小堆。

答:堆是一种基于完全二叉树的数据结构,其核心在于满足特定的堆属性,据此可分为最大堆和最小堆。完全二叉树的结构特点是,除最后一层外,其他各层的节点均被完全填充,且最后一层的节点从左到右依次排列,这使得堆能够通过数组高效存储,无需额外指针维护节点间关系。

最大堆的关键特性是,树中每个父节点的值都大于或等于其左右子节点的值。这一特性决定了整个堆的根节点是所有元素中的最大值。在操作方面,插入元素时,新元素先放置在堆的末尾,随后通过 “上浮” 过程与父节点比较,若大于父节点则交换位置,直至重新满足最大堆的属性;删除最大值时,需先移除根节点,再将堆的最后一个元素移至根节点位置,接着通过 “下沉” 过程与左右子节点中较大的那个比较,若小于则交换,直到堆属性恢复;构建最大堆则是从最后一个非叶子节点开始,依次对每个节点执行下沉操作,将无序数组转换为符合要求的堆。

最小堆与最大堆的核心区别在于父节点与子节点的大小关系,最小堆中每个父节点的值都小于或等于其左右子节点的值,因此其根节点是所有元素中的最小值。操作逻辑上,插入元素时,新元素放在末尾后通过 “上浮” 与父节点比较,若小于父节点则交换;删除最小值时,将最后一个元素移至根节点后,通过 “下沉” 与左右子节点中较小的那个比较,若大于则交换,直至堆属性成立;构建最小堆同样从最后一个非叶子节点开始,依次执行下沉操作,只是比较时选择较小的子节点。

在存储上,堆通常采用数组实现,对于索引为 i 的节点,其左子节点索引为 2i+1,右子节点索引为 2i+2,父节点索引为 (i-1)//2。这种结构使得堆的插入、删除操作时间复杂度为 O (log n),获取极值的操作时间复杂度为 O (1),因此在优先队列、堆排序、Top K 问题等场景中应用广泛,能够高效地处理与极值相关的动态数据维护需求。

(4)详细介绍什么是二分搜索树。

答: 二分搜索树(Binary Search Tree,简称 BST)是一种基于二叉树结构的数据结构,其核心特性是通过节点值的有序性来实现高效的查找、插入和删除操作。它满足以下关键性质:对于树中的任意节点,其左子树中所有节点的值都小于该节点的值,而右子树中所有节点的值都大于该节点的值。这种特性使得二分搜索树的中序遍历(左子树→根节点→右子树)结果是一个严格递增的序列,这也是判断一棵二叉树是否为二分搜索树的重要依据。

​ 从结构上看,二分搜索树是一种二叉树,每个节点最多包含两个子节点,分别称为左子节点和右子节点,没有子节点的节点称为叶子节点。与普通二叉树不同,二分搜索树的节点值分布并非随机,而是通过 “左小右大” 的规则形成了天然的有序性,这为数据的快速访问奠定了基础。

​ 在基本操作方面,查找是二分搜索树的核心优势之一。查找时,从根节点开始,将目标值与当前节点值比较:若目标值等于当前节点值,则查找成功;若目标值小于当前节点值,则转向其左子树继续查找;若目标值大于当前节点值,则转向其右子树查找。这种 “二分” 思路避免了对所有节点的遍历,理想情况下,每次比较都能排除一半的节点,因此平均时间复杂度为 O (log n),但在最坏情况下(如树退化为单链表),时间复杂度会降为 O (n)。

​ 插入操作的逻辑与查找类似。新节点的值会从根节点开始比较,若小于当前节点值且左子节点为空,则将新节点作为左子节点插入;若大于当前节点值且右子节点为空,则作为右子节点插入;若子节点不为空,则继续深入相应的子树,直到找到合适的插入位置。插入操作同样依赖于 “左小右大” 的规则,以维持树的有序性,其平均时间复杂度与查找相同,为 O (log n)。

​ 删除操作相对复杂,需要根据待删除节点的子节点数量分情况处理:若待删除节点是叶子节点(无左右子节点),直接删除即可;若待删除节点只有一个子节点(左子节点或右子节点),则用该子节点替代待删除节点的位置;若待删除节点有两个子节点,则需要找到其 “后继节点”(即右子树中值最小的节点,也就是右子树的最左节点)或 “前驱节点”(即左子树中值最大的节点,也就是左子树的最右节点)来替代它,随后删除这个替代节点。这种处理方式的目的是在删除节点后,仍能保持 “左小右大” 的性质,确保树的结构有序性,删除操作的平均时间复杂度同样为 O (log n)。

​ 二分搜索树的性能高度依赖于树的平衡性。如果插入的元素是有序的(如递增或递减序列),树会退化为一个单链表,此时所有操作的时间复杂度都会退化为 O (n),失去高效性。为了解决这一问题,人们提出了平衡二分搜索树,如红黑树、AVL 树等,它们通过特定的旋转操作来维持树的平衡性,确保在最坏情况下仍能保持 O (log n) 的时间复杂度。

2.HR面试题

(1)我们非常欣赏你的能力,但目前只能提供比你期望薪资低20%的offer。在这种情况下,你会接受这份工作吗?如果接受,你对未来薪资增长有什么期望?如果不接受,你的底线是什么?

答:感谢您的认可和坦诚沟通。关于薪资的问题,我确实需要认真考虑,但首先想说明的是,我对这个职位和公司的发展前景非常看重 —— 无论是团队的业务方向还是岗位能提供的成长空间,都和我的职业规划高度契合,这也是我一直积极沟通的核心原因。

​ 如果综合评估后选择接受这份 offer,我对薪资增长的期望会基于 “贡献与回报匹配” 的原则:短期内,我希望通过 3-6 个月的试用期,用实际业绩证明自己的能力(比如快速落地 XX 项目、达成 XX 目标),届时能有一次基于绩效的薪资调整,逐步向市场合理水平靠拢;长期来看,我期待薪资增长能和个人为公司创造的价值同步 —— 比如每年结合年度绩效考核,参考行业同岗位薪资涨幅和公司发展情况,获得与贡献对等的回报。对我而言,成长空间和薪资公平性同样重要,我相信只要能持续为团队创造价值,薪资自然会随能力和业绩提升而调整。

​ 当然,如果暂时无法接受,我的底线其实源于对自身市场价值的合理评估:这份期望薪资是我结合同行业同岗位薪资水平、自身过往项目经验以及生活成本核算的结果。如果差距确实较大,我会希望和团队再沟通是否有折中方案 —— 比如是否有股权激励、额外的培训资源、灵活办公等福利来弥补部分差距,或者将薪资调整的节点和目标更明确地绑定(比如达成 XX 里程碑后即时调薪)。如果最终确实无法达成共识,虽然会非常遗憾,但我也会尊重公司的预算规划,因为我需要确保自己能全身心投入工作,而无经济顾虑影响状态。

​ 无论如何,我都非常珍惜这次机会,也希望能找到双方都满意的合作方式。

(2)我们公司经常需要加班到深夜,有时甚至需要周末工作。你如何看待这种工作强度?你认为工作与生活的理想平衡点在哪里?

答:感谢您的坦诚说明。关于工作强度,我的看法是:职场中难免会遇到需要集中精力攻坚的阶段 —— 比如项目上线前的关键期、突发问题的紧急处理等,这时候加班投入是必要的,也是职业责任感的体现,我对此有心理准备,也愿意在这类场景中主动承担,确保任务落地。

​ 但同时,我也会更注重 “高效工作” 的节奏:比如通过提前规划拆解任务、优化协作流程,尽量在常规工作时间内完成核心目标,减少不必要的低效加班。毕竟长期无规律的深夜或周末加班,可能会影响状态的可持续性 —— 就像长跑需要合理分配体力,持续的高效输出也需要适度的休息来支撑,这样才能在关键节点保持专注和创造力。

​ 关于工作与生活的理想平衡,我更倾向于 “动态平衡” 而非固定比例:两者的核心是相互支撑,而非对立。工作时专注投入,用成果体现价值;生活中通过休息、学习或陪伴充电,反过来为工作提供状态和灵感。比如,规律的作息、必要的个人成长时间(比如研究行业动态),其实能帮助我更快适应工作挑战。对我而言,“平衡” 不是 “工作占多少小时、生活占多少小时”,而是能在需要全力冲刺时不犹豫,也能在日常有基本的生活节奏来维持状态 —— 这样既不辜负工作中的责任,也能让自己长期保持对职业的热情。

​ 当然,我也相信如果团队能一起优化工作流程(比如更清晰的目标拆解、更高效的跨部门协作),很多加班其实可以转化为更合理的节奏。如果有机会加入,我也愿意和团队一起探索这样的方式,既保证成果质量,也让大家能在可持续的状态下协作。

(3)你认为自己最大的优势是什么?这个优势如何帮助你胜任我们这个岗位?

答:我最大的优势在于我大学所学知识,与我所应聘的岗位的需求完全契合。大一听了个计算机专业的知识讲座,了解到了运维这个方向,便对运维有了兴趣,之后加入了学习中心,我便确定了未来就业的方向,就是要做一名优秀运维工程师,在学习过程中也不断朝着这个方向前进。

​ 我深入学习了Linux操作系统,如红帽和乌班图,在服务器管理和网络配置方面能得心应手。此外,我还擅长使用自动化工具,如 Ansible ,来提高运维效率。例如,我曾通过编写 Ansible 脚本,实现了服务器的自动化部署和配置管理,将部署时间从原来的几个小时缩短到几分钟。

​ 我深知,要想成为一名优秀的运维工程师,仅靠操作系统相关知识是远远不够的。所以在学习Linux操作系统的同时,我还在学习开发、网安以及数据库的相关知识。其中深入学习了Python、HCIA和MySQL数据库,对c/c++,Java,数据结构等有一定的了解。有关我的学习历程,各位面试官感兴趣的话可以看看我的CSDN账号。

​ 我相信,我的相关知识不仅能够帮助我快速适应贵公司的工作环境,还能够为团队带来新的视角和解决方案。我期待能够将我的知识和技能应用到贵公司的项目中,与团队一起推动公司的发展。

(4)你认为这份工作能为你带来什么?你能为公司创造什么价值?

答:首先是技术深度与广度的双重提升。运维岗位需要兼顾底层架构(如服务器、网络)、中间件(如容器、监控系统)和业务场景的适配,这种 “全链路保障” 的特性,能让我在实践中深化 Linux 系统、自动化脚本、云平台等核心技能,同时接触到高可用架构设计、故障应急响应等复杂场景 —— 这些正是运维工程师进阶的关键能力,也是我现阶段希望突破的方向。
其次是对业务的深度理解。运维的价值不仅在于 “保稳定”,更在于 “懂业务” 才能提前规避风险。贵公司在 [提及公司业务,如 “互联网服务”“企业级软件” 等] 领域的业务模式,能让我理解不同场景下的运维侧重点,这种 “技术 + 业务” 的结合能力,对长期职业发展至关重要。
最后是团队协作中的经验沉淀。运维工作离不开跨团队协作(开发、产品、测试等),我期待在贵公司的协作模式中,学习如何更高效地推动流程优化(如 DevOps 落地)、如何将故障复盘转化为预防机制,这些经验能帮我从 “被动响应” 转向 “主动运维”。

而我能为公司创造的价值,主要体现在三个方面:
第一,高效的稳定性保障能力。过往我在 [相关经验,如 “服务器集群运维”“自动化监控搭建” 等] 中,习惯通过 “预判 - 监控 - 应急” 的闭环管理降低故障概率 —— 比如用脚本批量处理重复操作减少人为失误,用监控告警提前发现磁盘满、内存泄漏等隐患,确保核心业务的可用性。面对突发故障时,能快速定位根因(如通过日志分析、链路追踪),减少停机时间。
第二,成本与效率的平衡优化。运维不仅要 “保稳定”,还要 “控成本”。我会关注资源利用率(如服务器负载、云资源开销),通过 [具体方法,如 “弹性伸缩配置”“闲置资源清理” 等] 降低运维成本;同时推动自动化工具落地(如 Ansible 批量部署),减少重复劳动,让团队聚焦更核心的问题。
第三,故障经验的沉淀复用。每次故障后,我会主动复盘并输出 “故障手册”,明确触发条件、解决步骤和预防措施,避免同类问题重复发生。这种 “吃一堑长一智” 的积累,能逐步提升团队的整体运维效率,尤其是在业务扩张时,能快速复制成熟的运维模式。

简单来说,我期待在这份工作中成长为 “既懂技术又懂业务” 的运维工程师,同时也相信自己的稳定性保障能力、成本优化意识和经验沉淀习惯,能为公司的业务连续性和运维效率提供扎实支撑。

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, 2, 8, 4]。函数func的核心逻辑是对列表lst中的每个元素进行条件处理:对于最后一个元素,将其值乘以 2;对于其他元素,若当前元素小于下一个元素,则将当前元素加 1,否则减 1。这种处理方式通过与后续元素的比较,动态调整当前元素的值,最终生成一个新列表。

(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]。函数func遍历列表lst,根据元素的特性进行不同转换:若元素能被 3 整除,则将其除以 3 并取整;若元素为偶数且不超过 10,则将其值翻倍;若该偶数超过 10,则翻倍后立即终止整个循环;若元素为奇数,则将其加 1。在处理过程中,遇到第一个大于 10 的偶数时会提前结束遍历。

(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预先分配了足够的空间来容纳合并后的结果。具体实现是先将nums1的有效元素复制到临时数组temp中,然后使用双指针法,分别从tempnums2的起始位置开始比较,将较小的元素依次放入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]))

答:运行结果是3。函数func计算列表lst的交替和,即偶数索引位置的元素累加,奇数索引位置的元素累减,并且在累加过程中,若总和变为负数则将其重置为 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]。函数func将列表lst中的元素按奇偶性分离并分别排序,偶数部分按升序排列,奇数部分按降序排列,最后将两部分合并。

(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,通过循环弹出列表的首元素,对其进行判断:若为奇数则直接添加到结果列表中,若为偶数则将其翻倍后追加到原列表的末尾。这个过程会持续进行,直到原列表为空。

(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 的元素对,要求每个元素仅参与一次配对。具体实现是通过双重循环遍历列表,外层循环控制当前元素,内层循环从当前元素的下一个位置开始,寻找与当前元素和为 10 的元素,若找到则记录该元素对并跳出内层循环,以避免重复配对。

(8)编写程序,反素数

反素数是指一个将其逆向拼写后也是一个素数的非回文数,例如17和71都是素数但不是回文数,且反转后依旧是素数

输出显示前100个反素数,每行显示10个

答:

def prime(num):
    if num < 2:
        return False
    for i in range(2, num):
        if num % i == 0:
            return False
    return True

def back(num):
    return int(str(num)[::-1])

def is_palindrome(num):
    return num == back(num)

def anti_prime():
    result = []
    num = 10
    while len(result) < 100:
        reversed_num = back(num)
        if prime(num) and prime(reversed_num) and not is_palindrome(num):
            result.append(num)
        num += 1
    for i in range(0, 100, 10):
        for j in range(i, i + 10):
            print(result[j], end=" ")
        print()

anti_prime()

(9)编写程序,梅森素数

如果一个素数可以写成2p−12^p-12p1的形式,其中p是某个正整数,那么这个素数就称作梅森素数

输出p≤31的所有梅森素数

答:

def is_prime(num):
    if num < 2:
        return False
    for i in range(2, int(num ** 0.5) + 1):
        if num % i == 0:
            return False
    return True
def find_mersenne():
    mersenne_primes = []
    for p in range(1, 32):
        mersenne_num = 2 ** p - 1
        if is_prime(mersenne_num):
            mersenne_primes.append((p, mersenne_num))
    return mersenne_primes

result = find_mersenne()
for p, prime in result:
    print(f"p = {p} 时,梅森素数为 {prime}")

(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

答:

def sum_seq(n):
    res = 0
    for i in range(1, n + 1):
        res += i / (i + 1)
    return res

for i in range(1, 21):
    result = sum_seq(i)
    if i == 20:
        numerator = 0
        denominator = 1
        for j in range(1, 21):
            numerator = numerator * (j + 1) + j * denominator
            denominator *= (j + 1)
        def gcd(a, b):
            while b:
                a, b = b, a % b
            return a
        g = gcd(numerator, denominator)
        print(f"{i}\t{numerator//g}/{denominator//g}")
    else:
        print(f"{i}\t{round(result, 3):.3f}")

(11)编写程序,组合问题

有1、2、3、4这个四个数字,能组成多少个互不相同且无重复数字的三位数?分别又是多少?

答:

count = 0
for a in range(1, 5):
    for b in range(1, 5):
        if b == a:
            continue
        for c in range(1, 5):
            if c == a or c == b:
                continue
            num = a*100 + b*10 + c
            print(num)
            count += 1
print("共有:", count)

(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

答:

n = 20
e = 1
f = 1
for i in range(1, n+1):
    f *= i
    e += 1/f
print("e ≈", e)

(13)编写程序,完全数

如果一个正整数等于除了它本身之外所有正因子的和,那么这个数称为完全数

例如 6 = 3 + 2 + 1,28 = 14 + 7 + 4 + 2 + 1

输入输出描述

输入一个正整数

输出该数是否为完全数

示例1

输入:

6

输出:

Yes

示例2

输入:

9

输出:

No

答:

n = int(input("请输入一个正整数:"))
s = 0
for i in range(1, n):
    if n % i == 0:
        s += i
if s == n:
    print("yes")
else:
    print("no")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值