拼多多暑期后端一面

拼多多暑期后端一面
最新回答
此姻花弥散

2022-05-14 07:31:41

以下是拼多多暑期后端一面的问题及解答

  1. 自我介绍

    需简洁说明教育背景、技术栈、项目经历及与岗位匹配的技能,突出后端开发相关的经验(如Java、数据库优化、分布式系统等)。

  2. 可以实习多久?将来工作去哪些城市工作有考虑过吗?

    实习时长:根据个人情况明确回答(如3-6个月),需保证与学业无冲突。

    城市选择:优先回答公司所在地(如上海、杭州等),或说明接受灵活安排。

  3. Java的线程池有哪些核心参数?

    核心线程数(corePoolSize):线程池中始终存活的线程数。

    最大线程数(maximumPoolSize):线程池允许的最大线程数。

    空闲线程存活时间(keepAliveTime):非核心线程空闲时的存活时间。

    时间单位(unit):存活时间的单位(如秒、分钟)。

    任务队列(workQueue):用于存放待执行任务的阻塞队列。

    线程工厂(threadFactory):创建线程的工厂类。

    拒绝策略(handler):当队列和线程池满时的任务处理策略(如AbortPolicy、CallerRunsPolicy)。

  4. 创建线程的时候,什么情况下会创建新线程?线程池是先创建线程,还是先进入队列?

    创建新线程的条件

    当前线程数小于核心线程数时,直接创建新线程。

    当前线程数大于等于核心线程数时,任务进入队列等待。

    若队列已满且线程数小于最大线程数,则创建新线程。

    执行顺序

    核心线程数未满时,优先创建线程。

    核心线程数满后,任务进入队列。

    队列满后,若线程数未达最大值,则创建新线程。

  5. 假设在线程池执行任务时,任务抛出了异常,线程会退出吗?所有异常都会导致线程退出吗?

    线程是否退出

    任务抛出异常时,线程会终止,但线程池会重新创建一个新线程(若未达到最大线程数)。

    异常类型影响

    非受检异常(如NullPointerException)会导致线程终止。

    受检异常(如IOException)若未被捕获,同样会导致线程终止。

    若任务中捕获异常并处理,线程不会退出。

  6. 如果线程池嵌套线程池,可能会有什么问题?

    资源竞争:嵌套线程池可能导致线程数激增,超出系统资源限制。

    任务堆积:子线程池队列满时,任务可能阻塞或被拒绝。

    调试困难:嵌套结构增加线程管理和异常追踪的复杂性。

    性能下降:频繁创建销毁线程导致上下文切换开销增大。

  7. Java的List、Set和Map的区别?分别适用哪些场景?

    List:有序、可重复集合,支持索引访问。

    适用场景:需要按插入顺序遍历或通过索引操作的数据(如日志列表)。

    Set:无序、不可重复集合,基于哈希或树实现。

    适用场景:需要去重或快速查找的场景(如黑名单过滤)。

    Map:键值对集合,键唯一。

    适用场景:需要通过键快速访问值的场景(如缓存、字典)。

  8. Map的Key可以为null吗?

    HashMap:允许一个null键。

    TreeMap:不允许null键(因依赖比较器)。

    ConcurrentHashMap:JDK 1.7不允许null键,JDK 1.8允许但不建议使用。

  9. 在遍历List时,可以同时对List进行修改么?

    直接修改会抛出ConcurrentModificationException

    安全修改方式

    使用迭代器的remove()方法。

    通过CopyOnWriteArrayList实现并发遍历和修改。

    遍历前复制列表,操作副本。

  10. 假设一个对象有两个属性,多线程同时修改时如何保证原子性(要么同时修改成功,要么都不成功)?

    同步锁:使用synchronized或ReentrantLock保证代码块原子性。

    原子类:对属性使用AtomicReference或AtomicInteger等。

    CAS操作:通过compareAndSet实现无锁原子更新。

    事务管理:在数据库层面使用事务(如Spring的@Transactional)。

  11. 如何实现跨域单点登录(如淘宝登录后访问天猫自动登录)?

    共享Session:将用户信息存储在Redis等共享存储中,各子系统通过Token验证。

    OAuth2.0协议:通过授权码模式获取访问令牌,子系统凭令牌访问用户资源。

    JWT令牌:生成包含用户信息的加密令牌,子系统解析后自动登录。

  12. MySQL的最左前缀匹配原则是什么?联合索引字段顺序调换还能生效吗?

    最左前缀原则:联合索引(A,B,C)的查询条件必须包含最左字段A,才能利用索引。

    字段顺序影响:若调换顺序(如B,A),则无法使用原索引,除非查询条件包含B和A。

  13. 索引中能不能有NULL?NULL值与其他值比较会怎样?

    允许NULL:B+树索引的叶子节点可存储NULL值。

    比较结果:NULL与任何值比较(包括自身)均返回未知(UNKNOWN),需用IS NULL或IS NOT NULL判断。

  14. 分库分表场景下如何生成全局唯一主键?

    UUID:全局唯一但无序,不适合作为索引。

    雪花算法(Snowflake):结合时间戳、机器ID和序列号生成有序ID。

    数据库自增序列:通过AUTO_INCREMENT和LAST_INSERT_ID()实现跨库同步。

    Redis原子操作:使用INCR命令生成递增ID。

  15. 怎么保证雪花算法的唯一性?还有别的分布式ID生成方案吗?

    雪花算法唯一性:依赖时间戳、机器ID和序列号的组合,需确保机器ID不重复且时钟回拨处理。

    其他方案

    Leaf:美团开源的ID生成服务,支持号段模式和雪花算法。

    UidGenerator:百度开源的基于雪花算法的实现,支持自定义工作机器ID。

  16. Redis Cluster的槽位(slot)机制是什么?如何固定某个key映射到固定槽?

    槽位机制:Redis Cluster将16384个槽位分配给各节点,key通过CRC16算法计算槽位号。

    固定映射:使用哈希标签({user1000}.profile)强制key分配到同一槽位。

  17. Redis的pipeline是做什么用的?Pipeline是原子性的吗?

    作用:将多个命令批量发送,减少网络往返时间(RTT),提升吞吐量。

    原子性:Pipeline仅批量执行命令,不保证原子性。需用事务(MULTI/EXEC)或Lua脚本实现原子操作。

  18. 如何用Redis实现分布式锁?

    SETNX命令:SET key value NX PX milliseconds实现锁的获取和过期时间设置。

    释放锁:通过Lua脚本确保仅锁的持有者能释放(比较value后删除key)。

    Redlock算法:在多个Redis节点上获取锁,提高可靠性。

  19. Redis如何防止数据倾斜?大Key拆分具体怎么操作?

    防止数据倾斜

    均匀分配哈希槽位。

    避免热点key(如加随机后缀)。

    大Key拆分

    将Hash/List拆分为多个小结构(如user:1:profile拆为user:1:profile:basic和user:1:profile:detail)。

    使用分片存储(如按时间范围拆分)。

  20. 有没有用过Elasticsearch?

    需根据实际经验回答,示例:

    用于日志分析或全文检索,支持分词查询和聚合操作。

    核心概念:索引(Index)、类型(Type)、文档(Document)、分片(Shard)。

  21. 什么是工厂模式?工厂模式和策略模式有什么区别?

    工厂模式:通过工厂类创建对象,隐藏具体实现(如SimpleFactory、Factory Method)。

    策略模式:定义算法族并封装,使它们可互相替换(如排序策略)。

    区别:工厂模式关注对象创建,策略模式关注行为封装。

  22. 高并发系统如何做限流?

    计数器算法:固定时间窗口内限制请求数(如Guava RateLimiter)。

    漏桶算法:以固定速率处理请求,平滑突发流量。

    令牌桶算法:允许一定突发流量(如Redis+Lua实现)。

  23. 秒杀系统如何防止超卖?

    数据库乐观锁:通过版本号控制(UPDATE stock SET count=count-1 WHERE id=1 AND count>0)。

    Redis原子操作:使用DECR命令扣减库存,若结果小于0则拒绝请求。

    消息队列削峰:将请求写入队列,后台异步处理。

  24. 秒杀订单创建后未支付怎么处理?

    超时关闭:通过定时任务扫描未支付订单,释放库存并标记状态。

    延迟队列:使用RocketMQ或Redis实现延迟消息,触发关闭逻辑。

  25. 手撕:背包问题变种

    问题描述:给定数组(物品重量)、背包容量(物品数量c和总重量h),求最小遍历次数。

    思考方向

    动态规划:定义状态dp[i][j][k]表示前i个物品中选j个、总重k时的最小次数。

    贪心算法:优先选择重量大且数量少的物品(需验证正确性)。

    回溯法:模拟遍历过程,剪枝优化(面试官强调考察思考过程,无需完整代码)。