版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2025年程序员工程面试题库及答案进程与线程的本质区别是什么?在高并发场景下如何选择使用进程还是线程?进程是操作系统资源分配的基本单位,拥有独立的内存空间、文件描述符等资源;线程是CPU调度的基本单位,共享进程的资源,仅拥有自己的栈空间和寄存器状态。高并发场景下,若任务需要隔离资源(如避免内存泄漏影响其他任务)或利用多核优势且任务间通信较少,优先选进程(如微服务架构中不同服务进程);若任务需高效协作(如Web服务器处理大量短连接),线程更轻量(上下文切换成本低),但需注意线程安全问题(如共享变量加锁)。TCP三次握手时,若第二次握手(SYN+ACK)丢失,客户端和服务端会如何处理?客户端发送SYN后进入SYN_SENT状态,等待SYN+ACK。若超时未收到(默认重传次数2-5次,间隔指数递增),客户端会重发SYN;服务端收到SYN后进入SYN_RCVD状态,发送SYN+ACK并启动超时重传(通常重传5次,总超时约30秒-2分钟)。若所有重传均失败,服务端会关闭该半连接。实际应用中,可通过调整tcp_synack_retries参数优化半连接队列处理,避免SYN洪泛攻击时资源耗尽。设计一个支持O(1)时间复杂度插入、删除、随机访问的动态集合,需考虑线程安全。使用哈希表(如Java的ConcurrentHashMap)存储元素值到节点的映射,同时维护一个动态数组保存元素。插入时,将元素添加到数组末尾,哈希表记录值到数组下标的映射;删除时,取数组最后一个元素覆盖待删除位置,更新哈希表中该元素的下标,再删除数组末尾元素(保证数组连续);随机访问通过数组下标O(1)获取。线程安全可通过读写锁(如ReentrantReadWriteLock)或CAS操作实现,插入和删除时加写锁,随机访问加读锁。MySQL中,RR(可重复读)隔离级别如何解决不可重复读?是否存在其他问题?RR通过MVCC(多版本并发控制)实现:每个事务启动时记录当前版本号,读取时访问该版本号之前的历史数据(undo日志),确保事务内多次读取结果一致。但RR仍存在幻读问题(同一事务内,两次范围查询返回不同行数)。MySQLInnoDB通过间隙锁(GapLock)解决幻读:执行写操作时,对查询范围加间隙锁,防止其他事务插入新记录。例如,查询id>10的记录,会对(10,+∞)间隙加锁,阻止插入id=11的记录。实现一个LRU缓存,要求支持并发读写,容量为N时淘汰最久未使用的元素。核心结构:双向链表(维护访问顺序)+哈希表(键到链表节点的映射)。双向链表头部为最近访问节点,尾部为最久未访问节点。写操作(put):若键存在,更新值并将节点移到头部;若不存在且容量已满,删除尾部节点及哈希表映射,再插入新节点到头部;若未满,直接插入头部。读操作(get):若键存在,将节点移到头部并返回值;不存在返回-1。并发场景下,使用可重入锁(如Java的ReentrantLock)或Go的sync.Mutex保护链表和哈希表的修改操作。示例代码(Java):```javaclassLRUCache{classNode{intkey,value;Nodeprev,next;Node(intk,intv){key=k;value=v;}}privateMap<Integer,Node>map=newHashMap<>();privateNodehead=newNode(0,0),tail=newNode(0,0);privateintcapacity;privateReentrantLocklock=newReentrantLock();publicLRUCache(intcap){capacity=cap;head.next=tail;tail.prev=head;}publicintget(intkey){lock.lock();try{if(!map.containsKey(key))return-1;Nodenode=map.get(key);remove(node);addToHead(node);returnnode.value;}finally{lock.unlock();}}publicvoidput(intkey,intvalue){lock.lock();try{if(map.containsKey(key)){Nodenode=map.get(key);node.value=value;remove(node);addToHead(node);}else{if(map.size()==capacity){NodetoRemove=tail.prev;map.remove(toRemove.key);remove(toRemove);}NodenewNode=newNode(key,value);map.put(key,newNode);addToHead(newNode);}}finally{lock.unlock();}}privatevoidremove(Nodenode){node.prev.next=node.next;node.next.prev=node.prev;}privatevoidaddToHead(Nodenode){node.prev=head;node.next=head.next;head.next.prev=node;head.next=node;}}```Kafka如何保证消息的有序性?在分区数大于1时如何处理?Kafka的有序性基于分区内的顺序写入:每个分区是一个有序的日志文件,生产者按顺序写入,消费者按顺序读取(offset递增)。单分区可保证全局有序;若分区数>1,消息按key哈希路由到不同分区,不同分区间无法保证全局有序。若业务需要全局有序,可采取:1)将消息发送到单分区(牺牲吞吐量);2)在业务层维护全局顺序号,消费者按顺序号重新排序(适用于允许延迟的场景);3)使用事务(Kafka0.11+支持),确保跨分区消息的原子性,但会降低性能。设计一个高并发的短链接服务,需考虑哪些关键点?1.提供算法:短码长度(如6位可提供62^6≈568亿个,足够使用),避免重复(雪花算法或自增ID取模+哈希碰撞处理)。2.存储方案:Redis缓存(快速查询)+MySQL/TiDB持久化(长链接与短码映射),缓存设置过期时间(如7天),同步更新主从。3.流量分流:Nginx负载均衡,根据地域或运营商路由;CDN加速静态跳转页面,减少源站压力。4.防刷机制:IP限流(如每分钟100次),短码提供频率限制,检测异常请求(如短时间内大量不同长链接转换)。5.容灾处理:主备机房同步,Redis哨兵模式,数据库双活,故障时自动切换;短码提供服务使用分布式ID提供器(如Leaf),避免单点故障。Java中,类加载的过程分为哪几个阶段?双亲委派模型的作用是什么?如何打破该模型?类加载阶段:加载(通过类加载器获取字节流)、验证(文件格式/元数据/字节码/符号引用验证)、准备(为静态变量分配内存并赋初始值)、解析(将符号引用转为直接引用)、初始化(执行类构造器<clinit>()方法,赋值静态变量和执行静态代码块)。双亲委派模型:类加载器收到加载请求时,先委托父类加载器加载,父类无法加载再自己加载。作用是避免重复加载(同一类由同一加载器加载)、保证核心类安全(如java.lang.String由启动类加载器加载,防止用户自定义同名类覆盖)。打破场景:1)热部署(如Tomcat的WebAppClassLoader为每个应用单独加载类,父类加载器(AppClassLoader)无法加载应用类);2)OSGi(动态模块加载,自定义类加载器根据Bundle需求加载);3)SPI机制(如JDBC,线程上下文类加载器可加载父类加载器无法访问的实现类)。Python中GIL的作用是什么?如何绕过GIL实现多线程并行?GIL(全局解释器锁)是Python解释器(如CPython)为保证线程安全而设计的互斥锁,同一时间仅允许一个线程执行字节码。作用是简化内存管理(避免多线程同时修改Python对象导致的竞态条件),但限制了CPU密集型任务的多线程并行(只能并发不能并行)。绕过方式:1)多进程(multiprocessing模块,每个进程有独立GIL,适用于CPU密集型);2)C扩展(在C代码中释放GIL,如使用Py_BEGIN_ALLOW_THREADS宏);3)使用其他解释器(如PyPy的TracingJIT支持真并行,但生态不如CPython);4)异步编程(asyncio,单线程事件循环处理I/O密集型任务,避免线程切换开销)。如何定位线上Java应用的CPU使用率过高问题?步骤:1)通过top命令找到CPU高的进程PID;2)top-HpPID查看该进程下高CPU的线程TID;3)jstackPID>stack.log,将TID转为16进制(如TID=1234→0x4D2),在stack.log中搜索0x4D2,定位具体线程的堆栈;4)分析堆栈:若线程在执行业务代码(如循环计算),检查是否有死循环或低效算法;若在等待锁(BLOCKED状态),检查锁竞争(jconsole或jmc查看锁持有情况);若频繁GC(GC线程CPU高),通过jstat-gcPID100010观察GC频率,jmap-heapPID查看堆内存使用,可能是内存泄漏(对象未被回收)或堆内存不足。分布式系统中,如何实现一个可靠的消息通知(如订单支付成功后通知库存系统)?需考虑:1)消息持久化:使用Kafka/RabbitMQ等消息队列,设置消息持久化(如Kafka的acks=all),避免Broker宕机丢失;2)消息确认:生产者开启同步确认(如RabbitMQ的publisherconfirm),消费者使用手动ack(处理完成后确认,失败则重新入队或进入死信队列);3)幂等性:消费者接口设计为幂等(如根据订单ID去重,数据库唯一索引),避免重复消费;4)补偿机制:消息发送失败时记录日志,通过定时任务扫描未确认消息并重发(如数据库记录消息状态,状态为“未发送”则重推);5)超时处理:设置消息过期时间(如30分钟),过期后进入异常队列人工处理;6)事务消息(如RocketMQ的事务消息):先发送半消息,本地事务提交后再确认,避免本地事务失败但消息已发送的问题。Go语言中,协程(Goroutine)与线程的区别是什么?调度器(GPM模型)如何优化并发性能?协程是用户态轻量级线程,创建成本低(几KB栈空间),由Go运行时调度;线程是内核态线程,创建成本高(MB级栈空间),由OS调度。GPM模型中,G(Goroutine)是任务,P(Processor)是逻辑处理器(持有本地G队列和M的上下文),M(Machine)是内核线程。调度过程:当M需要运行G时,从P的本地队列取G;若本地队列为空,从全局队列“偷”一半G(工作窃取);若G阻塞(如I/O),M与P解绑,P寻找其他M继续运行;I/O完成后,G被重新放入P的队列。优化点:减少内核调度次数(P管理本地队列,减少M与内核交互)、利用缓存(P固定绑定M,G在P的本地队列中运行,缓存友好)、避免阻塞(I/O时M释放P,其他G可继续运行)。如何优化MySQL的慢查询?举例说明。步骤:1)开启慢查询日志(slow_query_log=1,long_query_time=1),记录执行时间>1秒的语句;2)使用EXPLAIN分析慢查询的执行计划,关注type(最好是const,最差是ALL)、key(使用的索引)、rows(扫描行数);3)优化索引:若where条件字段未索引,添加索引(如whereuser_id=?andstatus=1,创建(user_id,status)联合索引);避免索引失效(如函数操作index_col、!=、or条件未覆盖索引);4)优化SQL逻辑:避免SELECT,只取需要的字段;将子查询改为JOIN(如SELECTa.FROMaWHEREidIN(SELECTidFROMb)改为SELECTa.FROMaJOINbONa.id=b.id);5)分库分表:若单表数据量超1000万,按时间或ID哈希拆分(如订单表按用户ID模10分表);6)读写分离:主库写,从库读(适用于读多写少场景),使用中间件(如ShardingSphere)自动路由。例如,慢查询:SELECTorder_id,amountFROMordersWHEREuser_id=1234ANDcreate_time>'2024-01-01'ANDstatus=1ORDERBYcreate_timeDESCLIMIT10;优化前执行计划显示type=range,rows=10000(扫描1万行)。通过创建(user_id,status,create_time)联合索引(覆盖查询字段),type变为ref,rows=100,利用索引的有序性避免文件排序(Usingfilesort消失),执行时间从500ms降至50ms。在微服务架构中,如何设计服务的降级与熔断?降级:当服务压力过大时,暂时关闭非核心功能(如电商大促时关闭“用户评价”接口),返回默认值或缓存数据。实现方式:配置中心(如Apollo)动态下发降级开关,代码中检查开关状态,触发时返回降级响应;使用Hystrix或Sentinel的@Degrade注解定义降级逻辑(如调用失败时执行fallback方法)。熔断:当服务错误率超过阈值(如5秒内错误率>50%),触发熔断,拒绝所有请求(快速失败),进入半开状态(尝试放行部分请求,若成功则关闭熔断,失败则重新打开)。Sentinel中可配置熔断规则(RT>500ms、异常比例>20%、异常数>5次),通过滑动窗口统计请求状态。例如,订单服务调用库存服务,库存服务因数据库故障错误率达80%。Sentinel检测到异常比例>50%,触发熔断,订单服务调用库存服务时直接抛出BlockException,执行fallback返回“库存查询暂不可用”。5秒后进入半开状态,放行1个请求,若成功则恢复调用;若失败,继续熔断。如何设计一个支持动态扩缩容的分布式任务调度系统?核心模块:1)任务管理:存储任务元信息(周期、参数、执行器),支持CRUD和状态变更(启用/暂停);2)调度中心:根据任务周期提供待执行任务(如Quartz的Cron表达式),使用一致性哈希或负载均衡算法(如最小负载)将任务分配给执行节点;3)执行节点:拉取分配的任务,执行并上报结果(成功/失败/重试);4)注册中心(如Consul/Etcd):执行节点启动时注册,下线时注销,调度中心实时感知节点列表;5)扩缩容策略:监控执行节点的CPU/内存使用率(Prometheus+Grafana),当负载>80%时自动创建新节点(调用云API),负载<30%时销毁空闲节点;6)容错处理:任务超时(设置执行超时时间,超时后标记为失败并重试)、节点宕机(调度中心检测到节点离线,重新分配未完成任务)。例如,系统检测到执行节点A的CPU持续90%,触发扩容,创建节点B并注册到Consul。调度中心重新计算任务分配,将部分任务从A迁移到B。节点B启动后拉取任务并执行,降低A的负载。当负载恢复正常,系统自动缩容,销毁B并将任务迁回A(或其他节点)。在前端性能优化中,如何减少首屏加载时间?1.资源压缩:JS/CSS使用Terser/PostCSS压缩,图片转WebP/AVIF格式(比JPEG小25%-50%),SVG优化(去除元数据);2.懒加载:非首屏图片/组件使用IntersectionObserverAPI延迟加载,路由懒加载(如React的React.lazy);3.缓存策略:设置HTTP缓存(Cache-Control:max-age=31536000),静态资源加哈希戳(如app.abc123.js),利用ServiceWorker缓存离线资源;4.减少请求数:合并CSS/JS文件(Webpack的SplitChunksPlugin),使用雪碧图(CSSSprite)合并小图片,图标用IconFont或SVG
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 分店介绍教学课件
- 血站培训班课件的
- 长春宝宝辅食添加攻略
- 败血症患者多器官功能支持
- 育婴师培训实操课件
- 药理学入门:静脉麻醉药课件
- 钻孔灌注桩技术培训课件
- 湖南省怀化市2025-2026学年九年级上学期期中语文试题(含答案)(含解析)
- 出入境管理的制度
- 公司销售制度
- 2026年春苏教版新教材小学科学二年级下册(全册)教学设计(附教材目录P97)
- 2026年基因测序技术临床应用报告及未来五至十年生物科技报告
- 2025北京陈经纶中学高一9月月考物理(贯通班)试题含答案
- 中国铝矿行业现状分析报告
- 2025海康威视安检机用户手册
- 学堂在线 雨课堂 学堂云 智能时代下的创新创业实践 期末考试答案
- FZ/T 81006-2017牛仔服装
- 广东新高考选科选科解读课件
- 脊椎保养理疗课件
- 建筑工程技术资料编制收集整理及归档要求课件
- 浙江东大环境工程有限公司年产400万平方米ptfe中空纤维膜
评论
0/150
提交评论