2020-05-12 22:27:40
京东秋招后端开发一面(8.16)问题及解答思路如下:
能详细说一下你这个实习做的一些主要的工作吗?(针对简历中的实习经历)
需结合简历中实习项目描述,重点说明参与的核心模块、技术栈及成果。例如:
参与后端服务开发,使用Spring Boot框架搭建RESTful API,完成订单模块的CRUD功能。
优化数据库查询性能,通过添加索引使某接口响应时间从500ms降至100ms。
协助解决线上服务偶发超时问题,通过日志分析定位到数据库连接池配置不合理,调整参数后问题解决。
能简单说一下TCP和UDP的一些区别吗?
连接性:TCP是面向连接的协议,需通过三次握手建立连接;UDP是无连接的,直接发送数据包。
可靠性:TCP提供可靠传输(确认机制、重传、排序);UDP不保证可靠性,可能丢包或乱序。
开销:TCP头部较大(20字节以上),含序列号、确认号等字段;UDP头部仅8字节(源/目的端口、长度、校验和)。
应用场景:TCP适用于文件传输、网页浏览等需可靠性的场景;UDP适用于实时音视频、DNS查询等对延迟敏感的场景。
能详细说一下TCP和UDP的连接过程吗?
TCP连接过程(三次握手):
客户端发送SYN包(序列号=x)到服务器,进入SYN_SENT状态。
服务器收到后回复SYN+ACK包(序列号=y,确认号=x+1),进入SYN_RCVD状态。
客户端发送ACK包(确认号=y+1),连接建立,双方进入ESTABLISHED状态。
UDP连接过程:无连接建立步骤,直接发送数据包,无需确认或状态维护。
Redis的数据结构有哪些?
基础类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、ZSet(有序集合)。
高级类型:
HyperLogLog:用于基数统计(如UV计算),占用空间极小。
Geospatial:存储地理位置信息,支持距离计算和范围查询。
Bitmap:通过位操作实现高效统计(如签到系统)。
Redis的底层数据结构了解过吗?
String:底层为动态字符串(SDS),支持O(1)长度获取和空间预分配。
Hash:当元素较少时使用压缩列表(ziplist),较多时转为哈希表(dict)。
ZSet:使用跳表(skiplist)和哈希表结合实现,跳表支持高效范围查询,哈希表支持快速查找。
压缩列表和跳表的特点及原理?
压缩列表:
特点:内存紧凑,按顺序存储元素,节省空间;但插入/删除需频繁分配内存,可能引发连锁更新。
原理:通过zlbytes(总长度)、zltail(尾偏移量)等字段快速定位节点,每个节点包含prev_len(前驱长度)和encoding(编码类型)。
跳表:
特点:通过多级索引实现O(logN)时间复杂度的查找、插入、删除,比平衡树实现简单。
原理:每个节点有多个后继指针(层级随机生成),高层指针用于快速跳过低层节点。
Redis主从复制和集群模式下的数据同步机制?
主从复制:
全量同步:从库发送PSYNC ? -1,主库执行BGSAVE生成RDB文件并传输,从库加载后主库发送缓冲区中的增量命令。
增量同步:主库记录写命令到复制缓冲区(环形队列),从库通过offset同步缺失部分。
集群模式:
数据分片:通过CRC16算法将键映射到16384个槽(slot),每个节点负责部分槽。
故障转移:哨兵(Sentinel)监控主节点状态,主节点故障时选举新主并更新槽映射。
Redis内存淘汰策略及特点?
volatile-lru:淘汰最近最少使用的键(仅限设置了过期时间的键)。
allkeys-lru:淘汰最近最少使用的键(所有键)。
volatile-ttl:淘汰即将过期的键。
noeviction:不淘汰,返回OOM错误(默认策略)。
特点:LRU策略通过近似算法实现(随机采样5个键淘汰最久未使用的),避免全量扫描性能开销。
IO多路复用的原理?
核心思想:通过单个线程监控多个文件描述符(fd)的I/O事件(如可读、可写),避免为每个连接创建线程的开销。
实现方式:
select/poll:遍历所有fd检查事件,fd数量有限(select默认1024)。
epoll(Linux):基于事件回调机制,仅通知活跃fd,支持边缘触发(ET)和水平触发(LT),无fd数量限制。
MySQL索引的底层原理?
B+树结构:
非叶子节点仅存储键值和指针,叶子节点存储数据或主键(聚簇索引),且通过指针串联形成有序链表。
查询效率稳定(O(logN)),范围查询只需定位起始节点后顺序遍历叶子节点。
哈希索引:
通过哈希函数直接定位数据,查询效率O(1),但不支持范围查询和排序。
B树和B+树的区别?
节点内容:B树非叶子节点也存储数据,B+树仅叶子节点存储数据。
查询效率:B树可能需多次I/O(数据可能分布在任意节点),B+树所有数据在叶子节点,查询更稳定。
范围查询:B+树叶子节点链表结构支持高效范围查询,B树需中序遍历整棵树。
MySQL事务的实现机制?
原子性:通过undo log实现,事务回滚时执行反向操作。
持久性:通过redo log实现,事务提交时先写日志再刷盘(WAL机制)。
隔离性:通过锁(如行锁、表锁)和MVCC(多版本并发控制)实现。
一致性:通过原子性、持久性、隔离性共同保障。
MySQL事务使用中遇到的问题?
死锁:多个事务互相等待对方释放锁,可通过调整事务顺序或设置锁超时解决。
幻读:在REPEATABLE READ隔离级别下,通过Next-Key Lock(记录锁+间隙锁)避免。
项目中用到过哪些设计模式?
单例模式:如数据库连接池,确保全局唯一实例。
工厂模式:如根据配置动态创建不同数据库驱动实例。
策略模式的应用场景及实现?
场景:需根据运行时条件动态切换算法(如支付方式选择、排序策略)。
实现:
定义策略接口(如PaymentStrategy),不同支付方式(支付宝、微信)实现该接口。
上下文类(如OrderService)持有策略引用,通过依赖注入切换策略。
JVM内存结构?
线程私有:
程序计数器:记录当前线程执行的字节码行号。
虚拟机栈:存储局部变量表、操作数栈等,栈帧随方法调用入栈/出栈。
本地方法栈:为Native方法服务。
线程共享:
堆:存放对象实例,分新生代(Eden、Survivor)和老年代。
方法区:存储类信息、常量、静态变量(JDK8后改为元空间,使用本地内存)。
JVM垃圾回收(GC)机制?
分代收集:
新生代(Minor GC):采用复制算法,Eden区存活对象复制到Survivor区,多次存活后进入老年代。
老年代(Major GC/Full GC):采用标记-清除或标记-整理算法,可能伴随STW(Stop-The-World)。
常见收集器:
Serial:单线程收集,适合客户端应用。
CMS:并发标记清除,减少STW时间,但可能产生浮动垃圾。
G1:面向服务端,将堆划分为Region,优先回收价值高的Region。
AQS(AbstractQueuedSynchronizer)原理?
核心思想:通过CLH队列(双向链表)管理线程等待队列,结合状态变量state实现独占/共享锁。
获取锁流程:
线程尝试通过CAS修改state,成功则获取锁;失败则入队并挂起。
释放锁时唤醒后继节点,后继节点通过自旋+CAS竞争锁。
求二叉树最大深度的算法实现?
递归法:
public int maxDepth(TreeNode root) { if (root == null) return 0; return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;}迭代法(BFS):
public int maxDepth(TreeNode root) { if (root == null) return 0; Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); int depth = 0; while (!queue.isEmpty()) { int size = queue.size(); for (int i = 0; i < size; i++) { TreeNode node = queue.poll(); if (node.left != null) queue.offer(node.left); if (node.right != null) queue.offer(node.right); } depth++; } return depth;}复盘建议: