一些面试题目

之前逛论坛时,看到了一些经典的面试题,下边讨论的时候,也提供了一些不错的回答,现在把其中一个整理一下,不然老留着链接放浏览器里占位置,存文档里看的机会也会很少。

问题:
1、MySQL 里的记录有这么两个字段:
课程 id,课程余额
同时间大量学生抢同一门课,如何设计这个功能?
2、线上 Redis 内存满了,应该如何处理?这个问题,暂且认为是问线上Redis满了之后的处理方案。当然给了处理方案之后,后续的故障处理流程和优化方案也应该提供一下。
3、你认为解决高并发问题的本质是什么?

首先说第三个问题,根据下边网友讨论提示,这个面试官可能看过《高并发的哲学原理》才会问,链接: https://pphc.lvwenhan.com/
另外,有一个说法感觉说的也非常好:解决高并发的本质就是在业务上避免高并发的场景的产生,看看早年的双十一和现在的双十一。

OK,接下来贴一下一个网友(admol)的答案,如下:

第一问,实际上是在问你系统设计问题
而你只是直接回答了其中很小的一个点(做法),也不能说不对,只能说不完全对。

尝试从下面几个步骤回答下:
1. 多问
- 学校总的有多少学生需要抢课
- 学校大概总的有多少非常热门的课程
- 平均到每门热门课程大概有多少学生会同一时刻抢
- 给出一些人数,然后是否可以估算出 QPS
假设:需要抢课的学生 1000 人,
假设查询课程 QPS 粗略估算:1000QPS ,峰值*2 ,算 2000QPS

- 其他开放性问题,是否有其他要求
2.初步方案
分为两部来进行涉及:
1. 查询课程(查询并发最大)
设计一个高效的索引和缓存机制,以应对高并发查询需求。方案有:缓存、读写分离等
2. 提交抢课
设计一个分布式锁机制,确保同一时间只有一个学生可以成功抢课。方案有:Redis 、ZK 分布式锁、消息队列等

3.详细方案
- 开始抢课之前,提前将课程-课程余额缓存到 Redis 中
- 使用读写分离,分散查询课程和抢课程写结果时数据库的压力
- 使用 Redis 进行扣减余额
- 扣减成功,记录抢课结果(学生-课程)
4.总结
- 缓存、锁、读写分离、其他方案

问题2:线上 Redis 内存满了,应该如何处理?
思路:
1. 解决线上问题,快速恢复线上功能正常访问
- Redis 扩容
- 手动清理不必要的缓存数据,释放内存

线上功能恢复后再做
2. 找出为什么满问题
- 分析 Redis key ,是否是热点数据访问量暴增?
- 是否是 缓存 key 设计不合理
- Redis 配置参数不合理,导致内存使用效率低下
3. 避免为什么满问题
- 针对 2 进行优化,增加监控告警等措施

问题3.你认为解决高并发问题的本质是什么?
- 本质就是在大量的请求和有限的资源情况下,如何来保持系统的性能和可用性等。
- 手段很多:增加资源、减小开销、缓存、服务化、冗余、异步、队列、限流、熔断等

此网友还推荐看《系统设计面试:内幕指南》链接: https://learning-guide.gitbook.io/system-design-interview

以下是另外一个网友(dilu)的回答,这个点赞也比较多,回答也比较成体系,

 小菜鸡一枚,尝试回答一下,以下答案没查阅资料也没参考楼上大佬们的答案。

1. 这个问题我觉得可以分开讨论一下,首先如果真的只是学校的抢课场景,从经验来说,那就算有并发也不会有很高的并发,在不保证高可用的情况下(如果真是学校抢课,没必要真的做什么高可用吧?)单台 redis 足够支撑需求了,最简单的实现肯定是 setnx ,但是可以从这里延伸一下,例如锁的时长要设置多久,锁过期了怎么办,要不要重试等等八股文,也可以用 lua 脚本,但是缺点是什么巴拉巴拉(掺杂八股文)
但是如果不是简单的学校抢课场景,而是电商的抢购商品这种场景(说时候电商秒杀的八股文和方案大家估计背的比我熟了吧?)既要保证高可用也要数据一致性的情况下,我觉得可以这样设计:

a) 根据以往秒杀时期的数据前提下,前端直接抛弃一部分流量,例如只有 20%的请求才能真正的请求,80%的请求在前端直接抛弃。
b) 秒杀请求进入队列,这样可以把对 redis db 等资源的峰值削平避免服务出现毛刺。由于是秒杀场景,失败了用户也会重试,所以完全可以不在意消息是否会丢失,这种情况下 mq 的性能绝对是能承载主流量的
c) 在消费的时候,再按照商品纬度加锁,这里可以用 redis 集群模式,也可以用 zk 等等组件,调你熟悉的讲,例如你熟悉 redis 的 redlock 那就讲 redlock ,熟悉 zk 脑裂你就讲脑裂

2. reidis 内存满了怎么办?我认为有也得分类讨论(前提是 redis 满了已经导致服务不可用了,如果配置了内存淘汰策略那就不用在乎满不满了)
a) 首先确认这个 redis 里面的数据是不是全是“缓存型数据”,如果是,可以挑一些 topn 的 key 先删一批,先让服务正常可用,然后迅速扩容,如果能动态扩容最好,如果不行先用 rdb 复制一台更高规格的 redis ,然后切换过去。
b) 如果 redis 后面不是传统 MySQL 或者 qps 不高的情况下,直接重启是最好的办法,当然这种情况不太常见,如果 qps 过高可能会直接拖垮 DB 。
c) 这件事的关键是要做好事后复盘、做好防护,避免下次再出问题,一个是要增加 redis 内存监控告警,超过 80%要告警,其次要配置一下 redis 的缓存淘汰策略,(这里也可以卖弄一下 LRU 之类的八股文)。

3. 我认为并发问题就是资源竞争的边界问题,解决并发的问题就是让资源竞争的请求从并行变成串行(加锁),让无序变有序,让混沌变秩序。这里可以卖弄一下读写锁,互斥锁,CAS ,原子操作之类的八股文。

其次,有一些关于面试的经验,想分享给 V 友们。

1. 面试跟谈恋爱是一样的,眼缘最重要,而不是闯关或者解密游戏,答对所有题,写出所有算法,不会决定你能否通过,能通过面试,一个是因为合适,一个是因为眼缘。而我认为后者的占比更大一些,所以建议可以适当处理一下个人形象,面试的时候别太颓废,别太随意。不管是面试还是生活中,看起来让人舒服的人,总能占更多的好处。

2. 面试的时候,问题不会,算法不会是很正常的一件事,计算机的知识没人能做到全都懂,你需要做的是把握面试节奏,让面试官去讨论你熟悉的东西,引导面试官的话题。例如楼主的题目,问你 redis 怎么实现分布式锁,如果你不熟悉 redlock 但是你熟悉 zk 那就说不好意思面试官,xxx 我不太熟,但是 zzz 我用的比较多,zzz 的原理是这样的 balabala 。要把节奏掌握在自己手中。

3. 面试官不一定能决定你是否通过,很多情况下还是 HR 话语权大一些

4. 面试前最好了解一下面试的公司和部门,他们有什么产品?主营什么业务,熟悉一下,对方问起来可以增加一些好感。

5. 面试必问,自我介绍、离职原因、语气薪资,这些问题一定要提前想好避免回答的时候大脑一片空白。

以上挑选了两个比较完整、认真的回答,保存下来,自己也多温习,毕竟基础不能丢啊。

股票软件脚本的几个函数

自己炒股,之前发现一个指标,觉得挺有使用价值的,想要自己通过这个指标选股。

一开始的想法,是自己写代码解析同花顺、东方财富之类的软件的数据,因为本科时候自己的一个小项目就是解析这些软件数据的,应该好弄。但是后来在做公式和指标的时候发现,有很多的公式,应该是软件本身就有的,比如均价,最低价、最高价,指数平滑移动均价,等等。

这些指标自己再去实现,首先自己做不一定能一次做对,其次哪怕做对了,可能中间也要花费大量的时间,最后,我是知道这些软件都是能编辑指标、公式的,这些东西自己再去实现一遍实在是有些没必要。

于是,根据自己发现的那个指标,来研读软件的这些系统自带公式,整理了一些用得到的指标,后续的选股方法也放在软件上去实现,而不是非得要自己写代码了。当然当前这种情况自己也没避免写代码,只是写的代码只是应用方面了。

函数:

HHV:求最高值,HHV(X,N)=>表示N个周期内X的最高值,X可以是其他的指标,比如HH:HHV(H,60)=>表示60个周期内最高价的最高值,以日线为例则表示60日内最高价

LLV:求最低值。HHV的反向函数,用法相同。

OPEN:开盘价(同O)

CLOSE:周期收盘价(同C)

LOW:周期最低价(同L)

HIGH:周期最高价(同H)

VOL:成交量(手),(同V)

AMOUNT:成交额(元),(同AMO)

以下几个复杂函数释义参考:https://zhuanlan.zhihu.com/p/584492746

MA:简单移动均价,简单算数平均值,不分轻重,平均算,N日内收盘价均价(当前周期使用当前价格)

EMA:指数平滑移动平均,EMA(C,N)=2*C/(N+1)+(N-1)/(N+1)*昨天的指数收盘平均值,在计算时,考虑了前一日的平均值,平滑系数固定。

SMA:SMA(C,N,M)与EMA的区别就是增加了权重参数M,也就是用M代替EMA平滑系数中的2,这样我们可以根据需要调整当日数值在均价中的权重=M/N。(要求N>M)

DMA:DMA(C,A) 中A为权重值,公式如下:X=DMA(C,A)=A*X+(1-A)*X'(A小于1),可以发现,DMA与SMA原理是一至的,只是用一个小数直接代替了M/N;而在实用中,这个小数最有价值的就是换手率=V/CAPITAL;DMA(C,V/CAPITAL)的直接含义是用换手率作为权重系数,利用当日收盘价在均价中的比重计算均价;直观理解就是换手率越大,当日收盘价在均价中的作用越大。

REF:引用几个周期之前的数据,REF(O,1)->调用前一天的开盘价

CROSS:穿越,CROSS(A1,A2),指标A1超过A2

此外搬运一个耿直老哥的选股方法:

同花顺问财选股里输入:DDE连续3日净流入,实际流通盘小于50亿,月换手率排行,平台整理。

大概能选出二三十个,删掉近期大涨的,删掉日成交额低于5000万的,大概还能剩下10个,然后取月换手率排名前6的,找个筛子,扔出几就买哪个。