Uncategorized

开发流程中Mysql设计表和优化表的过程

开发流程中Mysql设计表和优化表的过程 在实际开发过程中,先有开发需求,要解决实际问题和诉求在进行需求分析规划和排期, 我的实际开发流程 产品的需求文档,讲解需求,功能描述等 整理要实现的需求和功能点,和产品,需求方做功能确认 整理需求写开发文档 整理表关系,画er图,完善开发文档 写开发文档,实际完善和填充表字段和表结构 整理需求中涉及到的模块和开发顺序流程 如果涉及到老的业务流程和表结构的需要和之前的代码所有人同事进行确认沟通 开发过程中表结构可能还有缺陷,需要进行完善和补充, 有些场景下明确知道会有大量频繁查询的固定组合sql 可以提前建立索引 需要注意在设计表结构的时候需要和需求方确定一定的数据体量的预期,预期是20w 数据量,实际2000w数据量,这种数据量差异设计的表结构一定是不匹配,并且有问题的 开发上线后,需要根据慢查询sql 和实际接口响应,包括数据的增量状态来调整和完善表结构, 实际项目中,某些变化比较大,增量较大的项目可能会有较大的差异,需要注意实时分析和调整 今天面试某有声app科技公司有问到该问题,当时回答的不是很完善,回来整理了一下,希望对你有所帮助!

Uncategorized

Mysql中int(10)和int(11)有什么区别

Mysql中int(10)和int(11)有什么区别 mysql数据类型中int 数据类型也可以指定长度,但是mysql的int长度和varchar的长度的意义有些不同 不管是int(10)或者int(11)在存储大小和数据内容上是一致的,都是存储的4字节存储范围是-2147483648 – 2147483647 int类型的长度指示作用是显示宽度 当mysql 语句中使用zerofill 时 会在mysqlint字段中补充前导零,如果11位会填充满11位的前导零,10位则填充至10个前导零, 如果不使用zerofill则这个数字的填充位数不生效

Uncategorized

技术面试遇到的有趣的问题

技术面试遇到的有趣的问题 你有什么优势和别人比 审题总结就是你和别人比有什么不一样,’What’s the difference?’ 开放式问题没有标准答案大概可以分几个维度方向去回答这个问题 你的不可替代性 重点描述你的特长和不可替代性,或者在众多求职人中比较稀缺的能力,都可以说 岗位匹配度 重点描述你与岗位的匹配度 你的技术专业垂直度 技术深度,技术面,架构能力,对新知识点的获取积累,总结能力 技术基础 技术内容和基本功 基本面 基本情况,技术积累,技术能力,开发能力 文档和与人协调的能力 文档能力和与人配合的能力在中大型企业是非常需要,非常重要的,一定不要忽视 遇到问题的应急处理能力 遇到问题如何处理,有哪些自己单独负责项目并且解决问题的案例也可以说 表达和技术总结输出能力 技术人看问题的角度和表达方式都是在技术层面,但是实际工作和需求中,可能需要与大量不懂技术的其他职位的同时打交道,并且让他明白你的技术难点和技术方案是一项非常有优势的能力 融洽的与人配合 有些技术人员专业能力非常棒,但是不太能融洽的和同事相处,在中大幸公司与人配合协调的能力非常重要,10句话8句都是怼人的技术不是好技术 是否能站在技术之外看待问题? 在做开发时间长了之后,会有技术的路径依赖,处理一些问题更多的会依赖自己的技术能力,但是实际开发中可以尝试技术以外的方式看待或者处理问题,实际效果可能会更好 软件工程能力 对于程序员来说,产出的是代码,程序,实际项目是通过代码支撑运行,产生价值和收益,但是实际的开发完善和需求过程中,你写代码过程中的需求文档,开发文档,er图,表结构说明,表注释,完善良好的测试用例,关键逻辑的说明文档,api结构文档,业务逻辑说明文档,在软件工程中是对代码的强有力支撑,并且如果有完善的软件工程支撑的代码,会更加健壮完善,更好维护和迭代 总结: 实际面试中有些hr不懂技术,并且在成千上万的简历中,如何留下印象 是你要考虑的问题和方向 以上是一些经验和思考,临时想起来记录一下,希望对你有所帮助!

Golang

go协程工具WaitGroup

go协程工具WaitGroup waitGroup 是go语言非常常用的一个协程的流程工具,可以在指定位置阻塞等待指定数量的协程执行完成,从字面意思理解即是阻塞等待指定组的协程执行完成,在需要控制或者等待一批协程执行完成时可以使用waitGroup 实现该效果,其实该包的原理也是使用了channel实现的协程同步机制,通过在指定位置添加waitGroup.Wait() 方法来阻塞等待指定数量的协程执行完成,在协程执行完成后调用waitGroup.Done() 方法来通知waitGroup 协程执行完成,waitGroup 内部维护了一个计数器,当计数器为0时,waitGroup.Wait() 方法才会返回,否则会阻塞等待。 type WaitGroup struct { } func (wg WaitGroup) Add(delta int) func (wg WaitGroup) Done() func (wg WaitGroup) Wait() Add(delta int) 每次激活想要被等待完成的协程之前,先调用Add(),用来设置或添加要等待完成的goroutine数量 Done() 表示该协程执行完成,执行Done()会将waitGroup 内部的计数器减1 Wait() 表示等待所有的协程执行完成,当waitGroup 内部的计数器为0时,Wait() 方法才会返回,否则会阻塞等待 一般在所有的协程执行完成后调用Wait() 方法,等待所有的协程执行完成 func (wg WaitGroup) Add(delta int) { // 先从 state 当中把数据和信号量取出来 statep, semap := wg.state() // 在

Golang

Go语言syncMap实现的功能和使用场景

Go语言syncMap实现的功能和使用场景 在go语言提供的标准map类型中,如果涉及到协程读取map的场景,会存在并发读写的问题,并发操作map的会导致数据不一致, 为什么map不是并发安全的? 因为map的读写操作不是原子操作,当多个协程同时读写map时,会发生脏读和脏写导致数据不一致的问题。 在go 语言1.9版本后引入了syncMap,可以提供更加便捷的并发map操作方法, 例如: var m sync.Map 可以使用syncMap的方法来进行并发安全的map操作,例如: m.Store(key, value) m.Load(key) m.Delete(key) 这些方法都是并发安全的,不会导致数据不一致的问题。 但是该数据类型仅适合一定程度上的读多写少场景,syncMap内部使用了读写锁来实现并发安全,当写操作比较多时,会导致读操作的阻塞,影响性能。 源码:https://github.com/golang/go/blob/go1.23.0/src/sync/map.go func (m *Map) Swap(key, value any) (previous any, loaded bool) { read := m.loadReadOnly() if e, ok := read.m[key]; ok { if v, ok := e.trySwap(&value); ok { if v == nil { return nil, false }

Redis

redis-Sub/Pub消息订阅

redis-Sub/Pub消息订阅 Sub/Pub 消息订阅,是redis 中一个处理消息通知和数据一致的机制,它可以实现实时消息系统,比如普通的即时聊天,群聊等功能。 sub/pub 消息订阅案例demo package main import ( “fmt” “time” “github.com/go-redis/redis” ) func main() { client := redis.NewClient(&redis.Options{ Addr: “localhost:6379”, Password: “”, // no password set DB: 0, // use default DB }) pubsub := client.Subscribe(“chat”) go func() { for msg := range pubsub.Channel() { fmt.Println(msg) } }() time.Sleep(time.Second) } 使用场景 独立进程数据交互: redis是基于内存实现的,执行和计算流转效率速度非常快,如有两个独立进程需要进行数据交互和通知时,subpub是一个非常好的数据通知交互的方式,比传统的http请求和websocket请求实现的网络版数据交互方式时间效率要高很多

Uncategorized

Mysql的索引是如何实现数据的快速查找的

Mysql的索引是如何实现数据的快速查找的 inndb的存储引擎,索引实现的数据结构是B+树的一个数据结构,B+树是一个比较矮胖的数据结构,本身的特性比较适合在io磁盘的场景下做数据索引,可以减少大量不必要的io查询操作 B+树的数据结构本身就是一个平衡树,每个节点的子节点数量是固定的,每个节点的子节点数量是相等的 B+树的每个节点都有一个指向下一个节点的指针,这个指针可以用来遍历整个树 B+树的每个叶子节点都有一个指向下一个叶子节点的指针,这个指针可以用来遍历整个树

Uncategorized

Mysql-sql实例分析

Mysql-sql实例分析 Select A,B,C FROM t WHERE D=? AND E=?; 索引:D,E 组合索引 Mysql 执行这个sql 查询数据,会先根据索引D 查找符合条件的叶子节点,然后根据索引E 查找符合条件的叶子节点,最后返回符合条件的结果 问题:索引不变,新增一个字段F,F字段没有索引,sql也不变的场景下,查询效率会不会有变化? 我认为这个场景不会有变化,sql语句使用同样的索引命中同样的叶子结点,然后查询B+树的主树,根据id去检索数据,查询命中数据条目,最后将用户需要的数据字段检出返回给用户

Uncategorized

为什么要从php迁移到go

为什么要从php迁移到go 今天约到一个公司面试,聊到他们公司正在从php语言迁移到go语言,我就想知道他们为什么要迁移到go语言,有什么优势吗? 他们的回答是: 1. go语言是一种编译型语言,编译后直接运行在操作系统上,没有解释器的 overhead,所以性能要比 php 高很多。 2. go语言天生支持并发,通过 goroutine 和 channel 可以很方便地实现并发编程,而 php 原生要实现并发编程比较繁琐。 for example: 在实际使用场景下: php在需要进行大量数据计算和数据清洗的场景下,原生php只能顺序执行,在遇到计算体量比较大的场景下,如果顺序执行的时间成本比较高,比如要计算10个模块的子数据块的金额数据,一个数据块需要500ms 10个数据块则是5000ms go在进行大量数据计算和数据清洗的场景下,通过 goroutine 和 channel 可以很方便地实现并发编程,每个数据块可以分配一个 goroutine 来并行计算,最后通过 channel 来合并结果,这样可以大大提高计算效率,减少时间成本。同样的计算场景下10个子模块的数据可以将10个子模块的数据计算叠加到一起进行并发计算,计算需要的时间则是10个子模块数据计算中计算时间最长的单元的时间成本,相比于10个模块时间成本的和计算的时间成本是指数级的提高。 3. go语言的学习成本和php的swoole型框架的学习成本比较,底层知识的学习成本是一样,相近的,在相同学习成本的场景下,go语言普适性更高,性能更好,社区支持更长久,第三方框架和语言功能适配性会更好 4. go语言生成的二进制包能更好的迁移和服务器扩容

架构设计

本地消息表简介

本地消息表简介 本地消息表是分布式事务的一种实现方式,解决了分布式场景下数据最终一致性问题,是分布式事务相对简单可靠的解决方案,有一定的数据延迟性 实现思路 例:如在支付场景中,当用户支付完订单后, 订单服务会向本地消息表插入一条消息,消息内容为订单支付成功 订单服务会向支付服务发送一条消息,消息内容为订单支付成功 订单支付的业务逻辑和本地消息表的写入,生成订单相关业务逻辑和数据,订单的异步MQ任务投递是在同一个事务中,其属性是原子的 订单的异步MQ任务会被需要的服务消费,消费后的结果会更新本地消息表的状态 本地消息表会定时扫描,将状态为未处理的消息重新投递到MQ中 其他服务在需要查询订单状态时,会先查询本地消息表,若状态为已处理,则直接返回结果,否则向订单服务查询 并且需要一个定时扫描程序定期扫描本地消息表,检查检索没有正确投递,或者下游服务没有正确应答的消息,将其重新投递到MQ中 需要注意的是重新投递的MQ任务也可能会投递、消费失败,则需要在本地消息表中记录重试次数,超过最大重试次数则需要人工处理,注意在所有下游服务拉去MQ时的消息记录和日志需要完整,并且记录下每次消费的结果(正确或异常),方便后续分析和处理 问题 MQ服务,和其他服务在交互环节中会有数据不一致,延迟,消息丢失,服务挂机的情况发生,有服务宕机,消息丢失,进程消费异常等情况是会经常发生出现的,如何解决该问题 需要通过生成全局消息表traceId的方式完善该问题的逻辑,全局消息表是全局唯一,并且幂等,如果有消息丢失进程挂起,假死等情况需要将全局的本地消息表记录中的mq数据重复投递, 在其他分布式服务中需要幂等该进程的traceId的幂等消费,多次投递多次消费的结果是一致的 本地消息表是和业务逻辑相对耦合的,如果业务逻辑发生变化,需要同步修改本地消息表的处理逻辑,否则会导致数据不一致的问题,所以该实现方式对业务侵入性较强,不适合处理通用性较强的场景,所以使用时需要注意代码的后期维护几率和成本,如果后期维护成本较高,并且业务逻辑频繁变更,建议使用其他分布式事务实现方式 https://www.ierchina.com

Scroll to Top