莫欺冬招穷 level
获赞
517
粉丝
88
关注
149
看过 TA
3234
蚌埠坦克学院
2025
golang
IP属地:北京
你刚刚提到了OC是吧,说一下OC的底层原理
私信
关注
0 点赞 评论 收藏
分享
苏州科技大学:面试官:接个面试,对面同学是个杀软二次元
0 点赞 评论 收藏
分享
Cyber丁真:还真就是这样,后面发现是个数学题,得O(logN)才能过😅
投递虾皮信息等公司10个岗位
0 点赞 评论 收藏
分享
牛客485316751号:第一题前缀和或者dp,第二题求一个最大子区间(前缀和后最大(当前值减去当前出现最小值)得到区间和),然后每次这个子区间和翻倍,加上其他,坑在于中间取模(80%思考一下,如果全都是负值,10000多个负值最后能不能保证取模拿到正数模)我是(答案+mod*100000)%mod。第四天写一个最大因数判断dcq来解决互斥判断,地图上1代表互斥,0代表没问题,然后判断几个区间里没有1。这个判断依旧可以前缀和二维前缀和记录每个点到(0.0)点一共多少个1,从而通过右下角+左上角-左下角-右上角得到一个区间中有没有1值。时间复杂度(nmlogk)复杂度体现在求出互斥。
查看3道真题和解析 投递拼多多集团-PDD等公司10个岗位
0 点赞 评论 收藏
分享
Crueyl:dp 4种情况,消除首尾,消除后两个,消除前两个,然后中间切分求和,不考虑最后一个的话只能过27
投递滴滴等公司10个岗位
0 点赞 评论 收藏
分享
协程一直来说概念上挺玄学的,个人觉得确实是属于网上误传也非常多一种概念,经常跟用户级线程、绿色线程各种概念混在一起了。很多时候都说是一个东西,很多时候又能说出区别。留一个自己认知的大概解就差不多了,关键落到会用,跟线程的对比上有足够认知就差不多了。要提到这些概念也没问题,面试别咬死了说就好(我目前感觉这三个确实是一个东西)。● 不管定义是怎样,一定正确的一些特点:  ○ 协作式,非抢占式,编程语言决定或者协程自己决定如何做切换调度  ○ 完全用户态,无内核开销,大多数操作不涉及系统调用● 跟线程对比  ○ 实现特点:线程是 os 的软中断实现的,内核决定主要调度,协程一般是自己让渡,很多时候是线程复用,无传统意义上的中断。  ○ 控制难度:这个是我之前没留意的一个点,感觉协程线程其实用起来都差不多。但协程确实提供了很多机制来降低控制难度,线程需要百分百管理锁和同步,而协程一般都会在语言运行时层面上进一步做抽象来简化并发模型。比如 go 里边的 wg 和 channel。  ○ 性能:更轻量实现并发。上下文切换、用户态、占用内存(栈空间)goroutine 是协程在 go 语言里的‘实现’(我觉得实现这种说法比是在 go 里面的‘优化’更好一点,因为协程本身就没有一个确定基础实现。所以其实就我目前的理解协程更像是满足上面特点的一种‘不同于多线程的程序并发实现思想’)● 基本认知  ○ 和线程 m 对 n 关系,可以并行  ○ 基于 GMP 模型,模型可以认知为整体的一个实现,其中 P 是作为调度器的角色,gm 分别代表 goroutine 和 内核线程的抽象。  ○ 几种调度方式:一种分类是主动、被动、正常、抢占四种情况。这个分类挺好的,列举了所有情况。主动是还没执行完交出执行权,被动是临时阻塞被调度器给调度了,正常调度是结束调度新的,抢占调度是后面版本引入的针对系统调用僵直情况的调度。前面三种都是协作式的符合协程特点。● 怎样做调度,大概的调度流程和机制,剩下有哪些调度细节  ○ gmp 模型中,p 主要是本地队列,m 主要是线程抽象,直接指向 g。执行设想就是,p 动态绑定一个 m,然后 m 再通过 p 去拿 g 去执行。  ○ m 怎么找到下一个正常执行的 g:主要按照本地队列、全局队列、wait 队列、work-stealing 的顺序取(再加上一个每 61 次会优先全局防止饥饿) ○ g 的生命周期,正常流程 idle -> dead -> runnable -> running -> dead,运行的两状态会分别进入一个系统调用状态和 wait 状态(即阻塞,就是上面的 wait 队列,由被动调度触发)  ○ 我们直接创建的 g 优先进入当前 p 的本地队列,本地队列满或者主动让渡等情况会进全局队列● 其他面试问题  ○ 调度器 P 起到了什么作用?试想没有 P,那么我们 g 直接跟 m 绑定,那么好像其实就跟直接跟使用线程差不多了只是简单封装。首先最明显的作用就是实现了一个 m:n 关系,p 虽然跟处理器没直接关系但是还是确实代表一个抽象,最佳实践就是 p = 核心数(GOMAXPROCS),一定程度上线程的数量。其次这样动态绑定实现了线程的复用。除了这两个设计上的作用,剩下的就是他作为本地队列了,就类似于一个 channel 无锁化的重要步骤。最后还有 p 是作为一个所谓的“万能中间层”,除了动态做这种绑定复用,还能处理僵直的抢占调度的情况,这种情况下 p 会重新绑定一个 m 再去执行 g。    ■ 有个进阶题目,在一个 GOMAXPROCS 不等于核心数的 container 中运行程序会怎样?简单说,p 的数量直接意味着整个调度系统认为我们 cpu 有多少核,最大并行能力是怎样的。如果多了的话,就是实际线程数可能会比最佳值要大。那么就是调度效率下降,资源竞争加剧,性能下降。少了基本就是没充分利用了。  ○ 如何实现无锁化的。调度的时候取 g 的顺序,只有全局要加锁,p 是空的时候和窃取失败的时候都会提前取好 g。  ○ 为什么轻量?用户态,弱内核依赖,上下文切换,栈动态扩缩(初始内存是 0)  ○ 操作系统如何向某个Goroutine发送时钟中断呢?(这个我暂时没找到答案,目前理解是 os 先通知 go runtime,然后相关 m 在自己执行过程中被插入系统调用。)  ○ goroutine 终止会对其他 goroutine 产生影响吗(已捕获可恢复可以,否则会因为传递到顶层 g 导致全部崩溃)  ○ 什么时候被回收(这个问题有点奇怪,了解所有调度方式就好了,正常用完都会被回收,不然就是 panic 恢复,程序结束)
0 点赞 评论 收藏
分享
关注他的用户也关注了:
牛客网
牛客企业服务