我用一个小小的开放设计题,干掉了40%的面试候选人

简介: 去年团队招聘需求比较大,本人参与了近百次的面试工作。今天来跟大家聊聊,面试候选人过程中,一个常见的开放类设计题目的解题思路,以及候选人的理解设计误区分析。

背景


去年团队招聘需求比较大,本人参与了近百次的面试工作。今天来跟大家聊聊,面试候选人过程中,一个常见的开放类设计题目的解题思路,以及候选人的理解设计误区分析。


微信图片_20220608122918.png


话不多说,咱们直接奔主题。


问题其实很简单,是一个手机绑定验证的场景。大概描述就是:


用户手机验证场景下,正常会给用户手机号码发验证短信,用户收到验证短信后填写验证码进行提交,完成验证。


第一个问题


正常短信发送逻辑没有问题,但由于短信资源宝贵,防止被恶意攻击,你有什么好的控制策略呢?


在面试交流过程中,收集到的答案无外乎这样几种,收集整理归类如下:


1. 发送时间间隔


设置同一个号码重复发送的时间间隔(前端置灰,后端设置间隔锁),一般设置为60-120秒。该手段可以在一定程度上防止短信接口被恶意攻击,且对用户体验没有什么伤害。但是不能防止更换手机号方式进行攻击,防护等级较低。


2. 获取次数限制


是指限制某个手机号在某个时间段内获取短信验证码次数的上限值。


采用这种策略时在产品设计过程中,有几点需要注意:


1)上限值的定义。需要根据业务真实的情况,甚至需要考虑到将来业务的发展定一个合适的上限值,避免因用户无法收到短信验证码而带来的投诉。


2)锁定时间段的定义。需要根据业务情况进行定义,可以是6小时,可以是12小时、24小时。


3. IP限制


设置单个IP地址某个时间段内最大的发送量。


该手段可很好的预防单一IP地址的攻击,但是也有很明显的缺点:


1)对于经常变更IP地址进行攻击的攻击者,该手段几乎没有很好的效果。


2)IP的限制经常会造成误伤。如在一些使用统一无线网的场所,很多用户连接着同一个无线网,这个IP地址就容易很快达到上限,从而造成连接该无线网的用户都无法正常的收到验证码。


4. 图形验证码


在发送短信验证码之前,必须通过通过图形验证码的校验。


这种手段相对来说可以防止某些攻击,因此也是目前非常普遍的短信防攻击机制。但是在使用过程中涉及到用户体验问题,不能简单粗暴地套用这一策略。


以下两个点值得仔细考虑:


1)是不是每次获取短信验证码之前都需要用户输入图形验证码,一般来说这样做会极大地影响用户体验,虽然是相对安全,但是用户用着不爽了。


2)可以给一个安全范围。


结合手机号限制、IP限制来考虑,比如同一个手机号当天第3次获取短信验证码的时候,出现图形验证码;比如同一个IP地址当天获取验证码次数超过100次后,出现图形验证码。


5. 加解密控制


通过对传向服务器各项参数进行加密,到了服务器再进行解密,同时用token作为唯一性识别验证,在后端对token进行验证,验证通过才能正常将短信发送。该手段可以在保证用户体验的情况下,可以有效防止某些攻击,因此也是目前比较常见的短信防攻击机制。

同时也有很明显的缺点:


1)使用的加解密算法可能会被识别,需要考虑使用识别难度较大的加解密算法。


2)在算法不被识别的情况下可以有效防止报文攻击,但是无法防止浏览器模拟机式攻击。


第二个问题


假如需要对用户请求发短信接口进行限制,具体策略针对同一用户手机号发送短信验证码,10分钟之内请求超3次则需要图形验证码(即先验证图形验证码通过后再发送短信),你会如何设计并实现呢?


好多同学听完题目后,就会就能很快给出一个解题思路,大概描述如下:


微信图片_20220608122921.png


实现思路:利用Redis KV存储方式,用手机号作为Key,Value记录短信成功发送次数,同时设置过期时间10min。


假设发送时间如下所示:


微信图片_20220608122923.png


到10.07时候申请发送,判断value的值已为3,发送失败,需要出现图形验证码进行补充验证。


上面的逻辑看似没有问题,其实它将时间自然切片处理了。


微信图片_20220608122926.png


1)按照上面的逻辑,在10.00-10.10这个时间段周期内:10.01、10.07、10.08 分别发送三次短信,是OK的。


2)接着在10.10-10.20这个时间段周期内:10.11、10.13、10.15 也是可以成功发送短信的。


这样就出现了问题:


在10.07、10.08、10.11、10.13、10.15 这十分钟时间里,竟然发送了5条短信!


这样就绕过了发送短信超3次需要图形验证码验证的操作,这显然是不合理的。


其实好多候选人看到10min 和次数限制后,就陷入到了思维定势中去了。


那有什么好的解题思路么?


在此,针对此种问题,提供一种解题思路:


利用Redis List数据格式;Key:send_msg_phoneValue:请求时间戳。


直接上实现代码吧:


/**
 * Redis 单位时间内请求次数限制
 * User: 架构精进之路
 * Date: 2021/03/11
 * Time: 10:23
 */
$key = 'send_msg_xxx'; //xxx 指具体手机号
$listLen = lLen($key);
if($listLen < 3){
    // 直接将当前时间戳插入List尾部
    Lpush($key, now());
} else {
    $index0Time = Lindex($key);
    if((当前时间 - $index0Time) < 10min){
        // 触发10min内请求大于3次,提醒,“请求过多,请稍后再试。”
        echo "请求过多,请稍后再试。";
        exit;
    } else {
        // 将当前时间戳插入List尾部
        // 取出List头部首元素
        Lpush($key, now());
        Ltrim($key, 0, 9);
    }
}


总结


随着目前安全问题造成的影响日趋严重,Web 安全控制对于研发人员来说是一个非常重要的课题。


通过上面的问题,想要了解到大家对安全防控的认知有哪些,有什么好的处理方案,以及对不同方案之间的优劣比较有怎样的认知。


有了好的方案之后,那如何设计实现呢?在具体落地过程中,还有什么需要补充和注意的事项呢?


......


一系列连续的开放性问题走下来,你就能很好的判断候选人在这部分的能力水平了。


微信图片_20220608122929.jpg

相关文章
|
9月前
|
算法 Java 关系型数据库
限时开放!涵盖2023年大厂后端全套考点-字节后端面试上岸手册香
今年这情况,真心建议所有 Java 后端不要随便被“行情差洗脑”! 目前职友集上搜到的 java 岗位仍有22万+,招聘需求相比其他行业不算少!
|
11月前
|
算法 Java 关系型数据库
限时开放!涵盖2023年大厂后端全套考点-字节后端面试上岸手册香
今年这情况,真心建议所有 Java 后端不要随便被“行情差洗脑”! 目前职友集上搜到的 java 岗位仍有22万+,招聘需求相比其他行业不算少!
|
数据库
LeetCode(数据库)- 面试中被录取的候选人
LeetCode(数据库)- 面试中被录取的候选人
100 0
|
数据库
LeetCode(数据库)- 寻找面试候选人
LeetCode(数据库)- 寻找面试候选人
112 0
|
算法 Java 大数据
峰哥最近面试了几个候选人,总结一些经验和看法
峰哥最近面试了几个候选人,总结一些经验和看法
|
3天前
|
存储 缓存 网络协议
复盘女朋友面试4个月的Java基础题
这篇文章是关于Java基础面试题的复盘,涵盖了HashMap原理、对象序列化作用等高频面试问题,并强调了Java基础知识的重要性。
复盘女朋友面试4个月的Java基础题
|
5天前
|
存储 NoSQL Java
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
这篇文章是关于Java面试中的分布式架构问题的笔记,包括分布式架构下的Session共享方案、RPC和RMI的理解、分布式ID生成方案、分布式锁解决方案以及分布式事务解决方案。
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
|
28天前
|
SQL Java Unix
Android经典面试题之Java中获取时间戳的方式有哪些?有什么区别?
在Java中获取时间戳有多种方式,包括`System.currentTimeMillis()`(毫秒级,适用于日志和计时)、`System.nanoTime()`(纳秒级,高精度计时)、`Instant.now().toEpochMilli()`(毫秒级,ISO-8601标准)和`Instant.now().getEpochSecond()`(秒级)。`Timestamp.valueOf(LocalDateTime.now()).getTime()`适用于数据库操作。选择方法取决于精度、用途和时间起点的需求。
31 3
|
1月前
|
存储 算法 Java
Java面试之SpringCloud篇
Java面试之SpringCloud篇
67 1