好未来| IM平台| 一二面| Go社招
技术体系-数字效能部-知音楼-golang开发工程师
一面 8.14
- 自我介绍
- Golang
- GMP的调度器原理及怎么工作的
- 开发的时候需要控制goroutine的数量,避免调度的开销或者内存的增大,通过哪些机制可以避免或限制
- 垃圾回收简单介绍一下机制
- gin框架
- 介绍一下路由机制,或者举个例子
- 用没用过他的中间件,或者自己写过中间件吗,在你的业务里,比如说鉴权啊等
- 项目
- go+mysql重构中台系统,初衷是什么?当时为什么要重构,遇到了什么问题吗?有哪些优势
- 升级的过程中,有没有遇到数据迁移,从mongo迁移到mysql这块有做吗,怎么做的?
- 像你们迁移的时不是一到切的吧,这中间会产生新的数据,这个增量数据这块,你们是怎么处理的
- 迁的时候流量分发这块考虑了没有,服务升级可能会遇到新老服务的兼容,可能需要并行的去跑新老服务,这块你们有做流量的分发或者转发吗?比如说我们上新的服务的时候可能前期的话会逐步的去放量5%,10%这种?
- 负载均衡这块怎么做的?是在服务器网关这块去做还是怎么做的?
- 分布式缓存怎么理解?引入分布式缓存会设计到数据一致性的问题,在不同的节点上都会有缓存
- 渠道数据抓取,是抓哪里的数据?
- 数据的准确性完整性这是怎么做的?有核对核销还是怎么?
- 过程中有没有遇到数据对不上的,怎么解决的?数据的准确性确实非常关键和重要
- mysql
- 介绍一下事务的隔离级别
- 常用的是哪种级别
- b+树的特点或者优势介绍一下
- 有没有做过sql的优化?比如通过哪些方面去优化一个sql(索引,查询)
- kafka
- 用消息队列的一些场景和优势
- kafka的生产者,消费者的原理了解过吗,简单的介绍一下对kafka的理解
- 选举这一块了解过吗
- clickhouse
- rpc
- 原理和使用rpc的优势
- 底层通信协议是什么协议
- 你们rpc服务这一块的服务注册发现是怎么做的
- redis
- 数据类型简单介绍一下,以及常用的
- 你们用redis做缓存还是持久化还是都有
- 持久化机制简单介绍一下
- 程序题:实现一个简单的并发计数器 请编写一个Go程序,实现一个线程安全的计数器。要求如下: 提供增加计数的方法 Increment() 提供获取当前计数值的方法 Value() 要求: 使用Go语言内置的并发机制(如goroutines和channels)或互斥锁(sync.Mutex)来确保计数器在多线程环境下是线程安全的
package main
import (
"fmt"
"sync"
)
// Counter 是一个线程安全的计数器结构体
type Counter struct {
mu sync.Mutex
count int
}
// Increment 增加计数
func (c *Counter) Increment() {
c.mu.Lock() // 加锁,确保线程安全
c.count++ // 增加计数
c.mu.Unlock() // 解锁
}
// Value 获取当前计数值
func (c *Counter) Value() int {
c.mu.Lock() // 加锁,确保读取时的线程安全
defer c.mu.Unlock() // 使用 defer 语句确保方法结束时解锁
return c.count
}
func main() {
counter := &Counter{}
var wg sync.WaitGroup
// 启动多个 goroutine 并发地增加计数器
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
counter.Increment()
}()
}
wg.Wait() // 等待所有 goroutine 完成
fmt.Println("Final Counter Value:", counter.Value())
}
- 反问
- 知音楼团队-IM系统(类似于钉钉和飞书),做一些ai赋能提供工资效率,数字化伙伴和机器人,集团知识库的落地,低代码平台,Golang + Python
- 最近刚搬到朱辛庄
- 会评估一下,面试需要几轮,到时候再看
二面 8.15
- 共享屏幕手撕 leetcode 中等 53. 最大子数组和
func maxSubArray(nums []int) int {
if len(nums) == 0 {
return 0
}
localMax := nums[0]
globalMax := nums[0]
for i := 1; i < len(nums); i++ {
// 判断是开始一个新的子数组还是从上一个子数组中继续
localMax = max(nums[i], localMax+nums[i])
// 更新全局最大和
globalMax = max(globalMax, localMax)
}
return globalMax
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func main() {
nums := []int{1, -2, 3, 10, -4, 7, 2, -5}
fmt.Println("最大子数组和为:", maxSubArray(nums))
}
- 自我介绍
- 对好未来了解有多少
- 现在看过哪些公司了,那边面试怎么样,有多久了
- 你不会被裁吗?
- 项目
- 抽卡卡池缓存系统
- 游戏服务器这块用的实体机、虚拟机还是容器
- 容器应该不只一个吧,应该有多个吧?
- 多个pod的话,卡都写到内存里,抽的时候怎么保证本地内存里的数据几个pod之间数据协同的,比如说这个pod减,那边pod跟这减
- 接口每天的请求量多少
- 你觉得这个事情对你个人成长比较快是为什么?
- redis
- 常用的数据结构和应用的场景
- 两种持久化方式有什么不同,优缺点
- mysql
- 逻辑架构
- b+树 数据结构还有什么优势?
- 叶子节点仅保存索引,不存储实际数据,使得b+树的高度更低,为什么数据从子节点放到叶子节点会使这个树的高度变低
- 跨渠道数据抓取,采用了什么方法来确保数据抓取的准确性和完整性呢?
- 准确性和完整性怎么做的?怎么保证的?
- 反问