首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >被问到项目的整体规模,应该怎么说?

被问到项目的整体规模,应该怎么说?

作者头像
王中阳AI编程
发布2026-03-17 18:31:15
发布2026-03-17 18:31:15
830
举报
文章被收录于专栏:Go语言学习专栏Go语言学习专栏

今天分享组织内部的朋友在面试的时候遇到的几个典型的问题【项目规模、分库、分表】,分享一下我给他出的回答思路,大家也可以学习一下:

面经分享

1、整体集群规模,部署了哪些内容,怎么部署的?依据什么判断需要多少节点和服务器

我们的医疗区块链系统采用混合云架构,在阿里云和自建数据中心部署。整体集群规模达到 80 个节点,分布在华东、华北两个区域中心。

部署内容包括:

  • 30 个应用服务器节点,运行 GoZero 框架构建的微服务
  • 24 个 Hyperledger Fabric 验证节点,形成联盟链网络
  • 12 个 IPFS 存储节点,构建分布式文件系统
  • 8 个数据库节点,包括 MySQL 集群、Redis 集群
  • 6 个 Kafka 消息队列节点
  • 6 个 Kubernetes 控制平面节点

部署方式采用 Kubernetes 容器编排平台,通过 Helm Charts 实现应用的自动化部署和管理。所有服务都打包为 Docker 容器,遵循 CI/CD 流程,从代码提交到生产环境部署全程自动化。

节点和服务器数量的判断依据主要有:

  1. 业务需求:日均处理交易能力目标、峰值 QPS 预期
  2. 性能测试结果:单节点处理能力基准测试
  3. 扩展性考虑:预留 30-50% 的资源冗余
  4. 高可用性要求:每个服务至少部署 3 个副本
  5. 数据冗余策略:关键数据 3 副本存储

例如,通过性能测试发现单个原材料数据处理节点每分钟可以处理 8000 条 IoT 数据,而我们的业务需求是每分钟处理 5 万条数据,同时考虑 30% 的冗余,因此部署了 8 个处理节点。

2、分库是怎么划分的,是分一个库,还是根据供应商分了很多库?每个库的结构都一样吗?每个库有多少表?如何去查某个库的数据,怎么做到库与库之间隔离的?

我们采用按业务域和数据访问模式相结合的分库策略,主要基于以下维度进行划分:

  1. 业务域:分为原材料库、成品库、设备库等
  2. 地域:按华东、华北、华南等区域划分
  3. 数据访问模式:高频交易库与低频分析库分离

例如,原材料库按照品类和区域分为:

  • medicine_raw_materials_east
  • medicine_raw_materials_north
  • medicine_raw_materials_south

每个库的核心表结构是一致的,但会根据区域特性添加少量区域专属字段。每个库包含约 15-20 张表,主要包括:

  • 基础信息表:原材料信息、供应商信息等
  • 交易记录表:采购、入库、出库等记录
  • 质量控制表:检验报告、质量标准等
  • 价格管理表:历史价格、价格调整记录等

查询某个库的数据通过服务路由实现:

  1. 应用层根据请求参数(如物料 ID 前缀)确定数据所在区域
  2. 通过服务注册中心获取目标库的连接信息
  3. 执行跨库查询时,通过分布式查询引擎(如 ShardingSphere)进行路由

库与库之间的隔离通过以下方式实现:

  • 网络隔离:不同区域的数据库部署在不同的 VPC 中
  • 权限隔离:每个库有独立的数据库账号,权限最小化
  • 资源隔离:通过 Kubernetes 的资源配额限制每个数据库容器的 CPU 和内存使用
  • 数据加密:敏感数据在库内加密存储,跨库传输时使用 TLS 加密

3、分表是根据哪些键分的,每张表大概都多少数据,分了多少张表?表结构是什么样的?

我们采用水平分表策略,主要基于以下键进行分表:

  1. 时间维度:按季度分表,例如 material_transaction_2023Q1
  2. 业务维度:按物料品类分表,例如 pharmaceutical_materials、biological_materials
  3. 数据热度:将热点数据与历史数据分离,例如近 3 个月数据和历史数据

每张表的数据量控制在 500-800 万条记录,以保证查询性能。例如:

  • 原材料交易记录表:每个季度分一张表,预计每张表 600-700 万条记录
  • 价格历史表:每个月分一张表,预计每张表 100-150 万条记录
  • 质量检验表:按品类分表,每张表 300-500 万条记录

分表策略带来的优势:

  • 单表数据量减小,查询性能显著提升
  • 便于数据归档和清理,历史数据可以单独处理
  • 可以针对不同表的访问模式进行优化
  • 水平扩展能力增强,可以通过添加表来应对数据增长

4、什么场景需要用到指针,用指针有什么好处

使用场景

  1. 传递大对象:当函数需要操作大结构体时,传递指针可以避免内存拷贝
  2. 修改原始数据:通过指针可以在函数内部修改调用者的数据
  3. 实现接口:某些接口要求接收指针类型的实现
  4. 表示可选值:使用指针类型可以表示 "零值" 和 "不存在" 的区别

主要好处

  • 减少内存占用:避免大对象的复制,降低内存压力
  • 提高性能:减少数据复制的开销,提升函数调用效率
  • 实现引用语义:允许函数修改原始数据,而不是操作副本
  • 支持可选参数:通过指针可以传递 nil 值,表示参数未设置

5、context和waitgroup的区别?分别在什么场景用到?

区别:

特性

context.Context

sync.WaitGroup

核心功能

传递请求范围的数据、取消信号和截止时间

等待一组 goroutine 完成

数据传递

支持跨 goroutine 传递键值对数据

不支持数据传递

取消机制

支持主动取消和超时取消

不支持取消,只能等待所有任务完成

使用场景

请求作用域的数据、超时控制、取消信号

等待多个并行任务完成后继续执行

适用场景:

  • context.Context:
    • 跨服务传递请求 ID、用户身份等元数据
    • 控制请求超时,防止资源长时间占用
    • 处理用户主动取消请求的场景
    • 实现级联取消(一个操作取消导致所有相关操作取消)
  • sync.WaitGroup:
    • 并行处理多个任务,等待所有任务完成后汇总结果
    • 启动多个工作协程处理队列数据,等待所有协程完成
    • 等待多个子任务完成后释放资源

6、context怎么做到取消操作?

在 Go 语言中,context.Context的取消操作是通过WithCancelWithTimeoutWithDeadline三个函数实现的。这些函数都会返回一个可取消的Context和对应的CancelFunc,调用CancelFunc即可触发取消操作。

取消机制的工作原理:

  1. 创建可取消的Context时,系统会在后台维护一个取消信号的传播链
  2. 调用CancelFunc时,会向该Context及其所有子Context发送取消信号
  3. 所有监听该Contextselect语句中的<-ctx.Done()分支会立即被激活
  4. 取消信号会级联传播,确保所有相关操作都能被及时终止

7、什么场景用到了微服务?微服务是怎么做的?

适用场景:

  1. 业务解耦:将医药供应链系统拆分为原材料管理、生产管理、流通管理、质量管理等独立服务
  2. 团队自治:每个微服务由独立的敏捷团队负责开发、测试和部署
  3. 技术异构:不同服务可以根据需求选择最适合的技术栈
  4. 弹性伸缩:根据各服务的负载情况独立扩展或收缩
  5. 容错隔离:单个服务的故障不会影响整个系统

微服务实现方式:

  1. 服务拆分:
    1. 按业务领域拆分:原材料服务、生产服务、物流服务、销售服务等
    2. 按功能拆分:认证服务、支付服务、通知服务等基础设施服务
  2. 通信机制:
    1. 同步通信:使用 GoZero 框架的 RPC 组件实现高性能服务间调用
    2. 异步通信:通过 Kafka 消息队列实现事件驱动的服务间协作
  3. 服务发现与注册:
    1. 使用 Consul 作为服务注册中心
    2. 服务启动时自动注册,下线时自动注销
    3. 客户端通过服务名而非具体 IP 地址调用服务
  4. API 网关:
    1. 统一入口,对外提供 RESTful API
    2. 实现请求路由、负载均衡、认证授权、限流熔断等功能
    3. 基于 GoZero 框架的 API 网关组件构建
  5. 服务治理:
    1. 熔断机制:使用 Sentinel 实现服务熔断和降级
    2. 限流策略:基于令牌桶算法实现请求限流
    3. 负载均衡:集成多种负载均衡算法(轮询、随机、加权等)
    4. 链路追踪:通过 Jaeger 实现分布式请求追踪
  6. 部署与运维:
    1. 容器化:所有微服务打包为 Docker 镜像
    2. 编排管理:使用 Kubernetes 进行服务部署、扩缩容和生命周期管理
    3. CI/CD:实现自动化测试、构建和部署流程

8、什么情况下会出现空指针?如何避免空指针?

在 Go 语言里,空指针(也就是nil指针)会引发运行时错误,像panic。下面为你介绍空指针出现的情形以及相应的避免方法。

空指针出现的情形

  1. 指针变量未初始化:当声明了指针变量却没有对其初始化时,它的值默认为nil。要是直接解引用这样的指针,就会触发panic
  2. 函数返回nil指针:某些函数在特定条件下可能会返回nil指针,要是调用方没有检查返回值就直接使用,就容易引发panic
  3. nil接口调用方法:当接口变量的值为nil时,调用该接口的方法会导致panic
  4. 切片、映射或通道未初始化:虽然切片、映射和通道的零值是nil,不过它们的使用规则有所不同。比如,向nil映射存入键值对会引发panic,而向nil切片追加元素则不会。

避免空指针的方法

  1. 指针初始化:在使用指针前,要先为其分配内存,可以通过取地址操作或者使用new函数来实现。
  2. 检查函数返回值:调用可能返回nil指针的函数后,要先确认返回值是否为nil,然后再进行后续操作。
  3. 合理使用零值对象:可以考虑返回零值对象(例如空结构体),而不是nil,以此避免空指针问题。
  4. 安全调用接口方法:在调用接口方法前,要检查接口是否为nil
  5. 初始化集合:使用映射或通道前,要先对它们进行初始化。
  6. 使用结构体代替指针:如果结构体不大,优先使用值类型而非指针类型,这样能避免nil的问题。
  7. 借助空指针安全的工具:可以使用 Go 1.18 引入的泛型和空指针安全的工具函数。

总结

避免 Go 语言中的空指针问题,关键在于养成良好的编程习惯,例如使用前初始化指针、检查返回值、合理运用零值对象等。同时,要理解指针、接口和集合的零值特性,防止对nil值进行非法操作。

9、异常处理机制如何做的?

  1. 错误处理:
  • 使用 Go 的多返回值机制返回错误
  • 采用 "明确错误处理" 的哲学,不隐藏错误
  • 错误类型分为业务错误和系统错误
  • 业务错误返回给调用者处理,系统错误记录日志并向上传播
  1. 异常处理(Panic/Recover):
  • 仅在严重错误(如不可恢复的状态)时使用 panic
  • 在关键入口点(如 HTTP 处理函数、RPC 服务端)使用 recover 捕获 panic
  • 将 panic 转换为错误,统一错误处理流程
  1. 日志记录:
  • 使用结构化日志记录错误上下文
  • 区分不同级别的错误(info、warning、error、fatal)
  • 记录错误堆栈信息,便于问题定位
  1. 中间件机制:
  • 在 API 网关层实现统一的错误处理中间件
  • 在 RPC 服务端实现拦截器处理异常
  • 统一错误响应格式,便于客户端处理

10、消息中间键用到哪些,简单介绍一下

  1. Kafka
  • 定位:高性能分布式消息队列
  • 主要应用场景:
    • 原材料价格波动实时通知
    • 采购订单异步处理
    • 生产数据实时同步
    • 物流状态变更事件分发
  • 技术特点:
    • 高吞吐量:单集群支持百万级 TPS
    • 持久化存储:消息按主题分区存储,支持数据回溯
    • 分布式架构:天然支持水平扩展
    • 高可用性:通过副本机制保证消息不丢失
    • 分区机制:支持消息顺序性和负载均衡
  1. Redis Pub/Sub
  • 定位:轻量级消息发布订阅系统
  • 主要应用场景:
    • 实时数据缓存失效通知
    • 系统配置变更实时推送
    • 轻量级事件广播
  • 技术特点:
    • 简单高效:基于内存操作,延迟极低
    • 支持模式匹配:可以订阅模式化的频道
    • 弱持久化:不保证消息可靠传递
    • 与 Redis 缓存无缝集成
  1. RabbitMQ
  • 定位:功能丰富的企业级消息队列
  • 主要应用场景:
    • 异步任务调度
    • 系统间可靠消息传递
    • 复杂路由需求的消息分发
  • 技术特点:
    • 支持多种消息模式:点对点、发布订阅、路由等
    • 强大的路由功能:支持直连、主题、扇形等多种交换器类型
    • 消息确认机制:保证消息可靠传递
    • 丰富的插件生态:支持分布式部署、消息优先级等

消息中间件选型策略:

  • 对吞吐量要求极高的场景使用 Kafka
  • 对实时性要求高、可靠性要求低的场景使用 Redis Pub/Sub
  • 对可靠性和功能丰富性要求高的场景使用 RabbitMQ
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 王中阳 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 面经分享
  • 1、整体集群规模,部署了哪些内容,怎么部署的?依据什么判断需要多少节点和服务器
  • 2、分库是怎么划分的,是分一个库,还是根据供应商分了很多库?每个库的结构都一样吗?每个库有多少表?如何去查某个库的数据,怎么做到库与库之间隔离的?
  • 3、分表是根据哪些键分的,每张表大概都多少数据,分了多少张表?表结构是什么样的?
  • 4、什么场景需要用到指针,用指针有什么好处
  • 5、context和waitgroup的区别?分别在什么场景用到?
  • 6、context怎么做到取消操作?
  • 7、什么场景用到了微服务?微服务是怎么做的?
  • 8、什么情况下会出现空指针?如何避免空指针?
  • 空指针出现的情形
  • 避免空指针的方法
  • 总结
  • 9、异常处理机制如何做的?
  • 10、消息中间键用到哪些,简单介绍一下
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档