type
status
date
slug
summary
tags
category
icon
password

2024 拼多多后端实习面经

他这个面试这么奇怪,还换部门面试的

📎一面(2024.03.31,已通过)

部门:物流管理
 

算法题

lc845 数组中的最长山脉(中等
 

C++ & Golang

(1)内存泄漏是什么?
Answer:
内存泄漏(Memory Leak)是指已分配的内存未能成功释放回操作系统或内存池,导致该部分内存在未来无法被再次使用的现象。内存泄漏在长时间运行的程序中尤为严重,因为随着时间的推移,可用内存会越来越少,最终可能导致程序运行缓慢或异常终止。
内存泄漏的原因
内存泄漏可以由多种原因引起,常见的有:
  1. 未释放内存:程序分配了内存给某个对象,但在不再使用该对象后,未正确释放或删除其占用的内存。
  1. 循环引用:在一些具有垃圾回收机制的语言中(如JavaScript、Python),两个或多个对象相互引用,但它们不再被其他活跃的对象引用。这种情况下,垃圾回收器可能无法识别这些对象为垃圾,导致它们占用的内存不被释放。
  1. 静态集合类的滥用:在一些编程语言中,静态集合类(如静态列表、哈希表等)存储了对象的引用,如果不显式移除,即使对象不再需要,它们也会一直占用内存。
  1. 缓存机制的错误使用:错误地管理缓存,比如缓存过多数据而没有相应的淘汰机制,也会导致内存泄漏。
(2)除了去排查代码,还有什么办法来检测内存泄漏的情况?
Answer:
在Go语言开发中,管理和检测内存泄漏也是一个重要的任务。由于Go的运行时包括一个垃圾回收器(GC),它可以帮助减少内存泄漏的可能性,但是依然存在因错误使用或者不当的资源管理导致的内存泄漏情况。Go提供了一些工具和库来帮助检测和分析内存泄漏:
pprof
pprof是Go语言标准库中的一个强大工具,用于收集和分析性能数据。它可以生成堆内存的剖析报告,帮助开发者找到内存分配的热点。使用pprof,你可以通过HTTP服务器动态获取程序的性能分析数据,或者将分析数据导出并使用go tool pprof命令行工具进行分析。
要使用pprof检测内存泄漏,可以这样做:
  • 导入net/http/pprof包启动pprof分析HTTP服务器。
  • 在程序运行过程中,通过访问http://localhost:端口/debug/pprof/heap获取堆内存的剖析报告。
  • 使用go tool pprof工具下载和分析堆内存剖析数据,寻找内存分配的热点和潜在的内存泄漏。
 
除了Go标准库中的工具外,还有一些第三方工具和库可以帮助检测内存泄漏,例如:
  • go-leak:一个专门用于检测goroutine泄漏的库。
  • memguard:一个安全的内存管理库,可以帮助防止内存泄漏和其他内存相关的安全问题。
使用这些工具和实践可以帮助Go开发者有效地管理内存使用和检测潜在的内存泄漏问题。
 
(3)多态有什么种类?
(4)多态的目的是什么?
(5)go实现一个死锁怎么弄?
Answer:
这段代码试图从一个未缓冲的channel ch 中接收数据,但是没有任何数据被发送到这个channel。由于Go的运行时能够检测到这种情况(当所有goroutine都无法继续运行时),它会报告一个死锁错误:
 

设计模式

(1)给了一段代码,看看有什么问题,要怎么修改?(很多if,应该是拓展问题,但我不懂。。)
(2)我们如果疯狂对需求,一直加代码,可能后期就会导致代码非常臃肿无法维护,这个时候我们要怎么办?(提到了git rebase,他居然说确实可行,我真乱说的)
 

Mysql

(1)索引下推是什么?
(2)为什么要用自增id?
(3)随机id会导致B+树什么问题?
Answer:
我们在建表的时候,都会默认将主键索引设置为自增的,具体为什么要这样做呢?又什么好处?
InnoDB 创建主键索引默认为聚簇索引,数据被存放在了 B+Tree 的叶子节点上。也就是说,同一个叶子节点内的各个数据是按主键顺序存放的,因此,每当有一条新的数据插入时,数据库会根据主键将其插入到对应的叶子节点中。
如果我们使用自增主键,那么每次插入的新数据就会按顺序添加到当前索引节点的位置,不需要移动已有的数据,当页面写满,就会自动开辟一个新页面。因为每次插入一条新记录,都是追加操作,不需要重新移动数据,因此这种插入数据的方法效率非常高。
如果我们使用非自增主键,由于每次插入主键的索引值都是随机的,因此每次插入新的数据时,就可能会插入到现有数据页中间的某个位置,这将不得不移动其它数据来满足新数据的插入,甚至需要从一个页面复制数据到另外一个页面,我们通常将这种情况称为页分裂页分裂还有可能会造成大量的内存碎片,导致索引结构不紧凑,从而影响查询效率
(4)mysql的数据页是什么?
(5)mysql读写后的脏页,是怎么处理的?(buffer pool的刷新策略)
 

分布式

(1)mysql主从复制是怎么实现的?(binlog)
(2)主从结构是怎么分摊分布式压力的?
(3)如果要同时修改多张表的字段,它怎么保证主库和从库的一致性?(面试官说是分布式事务,然后说没做过不知道也正常)
 
然后就问项目去了。。。确实有点难,问到了很多刚好不会的点。。。
 

📎二面(2024.4.9,已通过)

部门:拼多多搜广推
 
一开始问项目,也没啥好说的
 

Golang

(1)golang里面的slice底层是什么?函数传递的时候是值传递还是引用传递?
(2)C++里面有没有像slice类似的结构?(我说vector他说不太像,因为slice还有len的特性)
(3)golang的map遍历为什么是无序的?
(4)为什么golang的map遍历要设置为无序?这是出于什么样的设计理念?
Answer:
map 在扩容后,会发生 key 的搬迁,原来落在同一个 bucket 中的 key,搬迁后,有些 key 就要远走高飞了(bucket 序号加上了 2^B)。而遍历的过程,就是按顺序遍历 bucket,同时按顺序遍历 bucket 中的 key。搬迁后,key 的位置发生了重大的变化,有些 key 飞上高枝,有些 key 则原地不动。这样,遍历 map 的结果就不可能按原来的顺序了。
当然,如果我就一个 hard code 的 map,我也不会向 map 进行插入删除的操作,按理说每次遍历这样的 map 都会返回一个固定顺序的 key/value 序列吧。的确是这样,但是 Go 杜绝了这种做法,因为这样会给新手程序员带来误解,以为这是一定会发生的事情,在某些情况下,可能会酿成大错。
当然,Go 做得更绝,当我们在遍历 map 时,并不是固定地从 0 号 bucket 开始遍历,每次都是从一个随机值序号的 bucket 开始遍历,并且是从这个 bucket 的一个随机序号的 cell 开始遍历。这样,即使你是一个写死的 map,仅仅只是遍历它,也不太可能会返回一个固定序列的 key/value 对了。
多说一句,“迭代 map 的结果是无序的”这个特性是从 go 1.0 开始加入的。
 
 

算法题

lc 236 二叉树的最近公共祖先(中等
lc 416 分割等和子集(中等) → 改造成4等分,不过无所谓是一样的
 

📎三面(2024.4.18,已通过)

部门:物流管理
 
先跟我聊什么人生规划,为什么去ntu啊,工作了后面几年怎么规划?选开发or算法balabala
 
后面聊完了讲了个项目,感觉他还算认可
 

mysql

(1)msyql可重复读是怎么实现的?
 

算法题

感觉是一道中等偏上的题,类似于 lc207 课程表(中等),不过比它难一点
 
有N个工作任务,各个工作之间存在依赖关系,例如必须先完成A工作,才能去执行B工作,现在给出每个工作的执行时间,在零时刻时,你收到了全部的工作任务,问你怎么规划,才能使得你完成所有任务的时候,每个任务的平均等待时间最短。可能会有多种不同的答案,请你返回字典序最小的那一个。
 
第一行输入N,M,表示有N个工作任务以及M个依赖关系
第二行输入N个整数,表示每个工作任务所需的时间
第三行开始,有M行输入,每一行两个整数A,B,表示工作B依赖于工作A
 
示例输入:
 
示例输出:
 
Answer:
这题很明显的拓扑排序+贪心,可以用类似于操作系统里面的“短作业优先”方法,来实现最短平均时间的效果,于是我们可以用一个优先队列来完成这个任务
 

📎hr面(2024.4.28)

2024 腾讯 微信支付 后端实习面经2024 美团 大模型后台实习面经
公告
type
status
date
slug
summary
tags
category
icon
password
🎉Welcome!!!🎉
NTU在读master
字节、腾讯实习 Get!💯
Blockchain、分布式爱好者
向天祈求一份好offer

近期会更新MIT 6.824课程lab
共勉。