跳到主要内容

南京|小米|外包|云服务工程师|一面

职位详情

岗位职责

  • 参与运动健康相关服务端需求开发和优化;
  • 参与技术方案选型,解决系统性能、稳定性、安全性等方面的挑战;
  • 编写高质量、可维护的代码,并进行代码审查,确保代码质量;
  • 与产品经理、各端工程师等团队成员紧密合作,共同完成产品选代和功能开发;

任职要求

  • 扎实的计算机基础知识,熟悉数据结构、算法、网络协议等;3 年以上 Golang 开发经验,熟悉 Golang 语言特性和生态,具备良好的编码风格:熟悉常用技术组件如 MySQL、Redis、MQ、gRPC 等,并具备数据库设计和优化能力;
  • 熟悉微服务架构,了解 Docker、Kubernetes 等容器化技术;
  • 具备良好的问题分析和解决能力,能够独立承担模块设计和开发工作;
  • 具备良好的沟通能力和团队合作精神,热爱技术,乐于分享;

加分项

  • 有运动健康、电商行业相关开发经验:

职位补充说明

  • 有高并发、高可用系统开发经验;

编程

使用两个协程交替顺序打印奇偶数,上限设置为10或者20,方便运行观察结果。

点击查看答案
main.go
package main

import (
"fmt"
"sync"
)

const UPPER = 10

func main() {
odd := make(chan struct{})
even := make(chan struct{})
var wg sync.WaitGroup

wg.Add(2)
// 打印奇数
go func() {
defer wg.Done()
for i := 1; i <= UPPER; i += 2 {
<-odd
fmt.Println(i)
even <- struct{}{}
}
}()

// 打印偶数
go func() {
defer wg.Done()
for i := 2; i <= UPPER; i += 2 {
<-even
fmt.Println(i)
if i < UPPER { // 防止死锁
odd <- struct{}{}
}
}
}()

odd <- struct{}{} // 启动
wg.Wait()
}

算法

leetcode 17题 电话号码的字母组合

点击查看答案

思路一,笛卡尔积问题,使用 python 的生成器类型输出结果,避免内存占用。

python
from itertools import product

class Solution:
def letterCombinations(self, digits: str) -> List[str]:
phone = {
"2": "abc",
"3": "def",
"4": "ghi",
"5": "jkl",
"6": "mno",
"7": "pqrs",
"8": "tuv",
"9": "wxyz",
}
return ["".join(group) for group in product(*[phone.get(i) for i in digits])]

思路二,使用递归,求 n 位电话号码的字母组合,就是求后 n - 1 位电话号码的字母组合前面拼上第一位的结果。

go
var phone = map[string][]string{
"2": []string{"a", "b", "c"},
"3": []string{"d", "e", "f"},
"4": []string{"g", "h", "i"},
"5": []string{"j", "k", "l"},
"6": []string{"m", "n", "o"},
"7": []string{"p", "q", "r", "s"},
"8": []string{"t", "u", "v"},
"9": []string{"w", "x", "y", "z"},
}

func letterCombinations(digits string) []string {
if len(digits) == 0 {
return []string{}
}
if len(digits) == 1 {
return phone[digits]
}

res := make([]string, 0)
for _, i := range phone[string(digits[0])] {
for _, group := range letterCombinations(digits[1:]) {
res = append(res, i+group)
}
}
return res
}

思路三,根据输入构造一棵树,使用深度优先遍历,这边省略,感兴趣的自己尝试实现。

Golang

  • slice 和 array 的区别

    点击查看答案
    • 切片底层是个结构体,由三部分组成,分别是长度字段、容量字段,以及一个指向存储了数据的数组的指针
    • 数组的长度也是类型的一部分,所以一般用得很少,切片则没有这个限制
  • map 的实现

    点击查看答案

    参考 map 的实现原理,从哈希表、拉链法、hmap、bmap等等角度展开讲一讲,也可以讲一下 key 的查询过程。你也可以提一下目前 go 1.24 版本中基于 swiss table 的实现,会加印象分。

  • go 底层内存分配方式

MySQL

  • MySQL 大表查询优化

    点击查看答案

    参考 MySQL 大表优化方案MySQL 性能怎么优化?,可以从定位和优化两个方面去展开。

    定位

    • 监控工具: 介绍常用的慢 SQL 监控工具,如 MySQL 慢查询日志、Performance Schema 等,说明你对这些工具的熟悉程度以及如何通过它们定位问题。
    • EXPLAIN 命令: 详细说明 EXPLAIN 命令的使用,分析查询计划、索引使用情况,可以结合实际案例展示如何解读分析结果,比如执行顺序、索引使用情况、全表扫描等。

    优化

    • 单表:字段/表结构优化、索引优化、SQL 语句优化、系统调优参数、硬件升级等角度各挑一两点讲一讲。
    • 拆分:读写分离、分库分表、冷热分离、引入缓存等。
  • B+树的原理

    点击查看答案
    • B+ 树只有叶子节点存放 key 和 data,其他内节点只存放 key
    • B+ 树的叶子节点有一条引用链指向与它相邻的叶子节点
    • B+ 树的检索效率很稳定,任何查找都是从根节点到叶子节点的过程
    • B+ 树的范围查询,只需要对链表进行遍历
  • 回表是什么

    点击查看答案

    在 InnoDB 存储引擎中,非主键索引的叶子节点包含的是主键的值。这意味着,当使用非主键索引进行查询时,数据库会先找到对应的主键值,然后再通过主键索引来定位和检索完整的行数据。这个过程被称为“回表”。

  • 深度分页问题怎么优化

    点击查看答案
  • MySQL 行锁

  • MySQL 死锁

    点击查看答案

Redis

  • 针对当日步数怎么实现排行榜功能?相同步数的情况下先达成该步数的排在前面

    点击查看答案
  • 缓存击穿怎么解决

  • 缓存穿透、缓存击穿、缓存穿透

Kafka

某个主题增加一个分区会造成什么影响

加载评论中...