1、怎么保证API的安全性?(怎么确保请求参数不被别人篡改?)
利用签名验证方式保证。
1)在API的一端存储密钥,使用md5算法,对请求参数和密钥进行md5加密,加密成签名字符串,把签名跟参数一起请求API的另一个端
2)在API的另一端获取签名信息和参数,把请求参数再加上当前端的密钥(两端的密钥必须保持一致的),重新加密一个新的签名,和传递过来的签名进行匹配,相同则代表请求合法,不合法代表不合法(参数被篡改了)
2、怎么保证API的幂等性?(任何幂等性都是去重判断)
GET:查询类,不需要做幂等性处理
POST/PUT/DELETE: 修改类(新增,修改,删除),有必要做幂等性判断修改业务,才需要幂等性处理
1)在API的一端,在每次刷新页面时,利用密钥生成新的token,请求过程携带token到API的另一个端
2)在API的另一端,
判断redis中是否存在该token,如果存入该token,代表请求已经重复提交了!!
如果redis不存在token,验证token是否合法,如果合法则把token存入redis中,并设置过期时间,代表该请求不重复。
3、项目中哪里用到多线程?(必问)
1) 案例一:
在商品数据从MySQl导入到Elasticsearch时,因为mysql商品数量很大,不能一次性导入,否则会内存溢出(OOM, out of memeory)。
该业务采用多线程+ES批量写入完成。
//分页查询(1页查询200条)
ExecutorService service = Executors.newFixedXXXX(5);
for( xxxxx ){
if(i%200=0){
CompletableFuture.runAsync(new Runnable(){
public void run(){<br /> //创建批处理对象<br /> BulkRequest bulkRequest = new BulkRequest();//缓存区//将写入请求加入到批量处理对象中<br /> for(ApArticle apArticle:apArticleList){<br /> //放入缓存区<br /> bulkRequest.add(request);<br /> }//执行批处理请求(真正把数据发送到ES执行)<br /> highLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);}<br /> <br /> },service );<br /> }
}
4、线程池的核心参数有哪些?(7个)
自定义线程池实现:new ThreadPoolExecutor(7个参数)
corePoolSize:核心线程数(默认值:1)。allowCoreThreadTimeout=false为默认值
如果设置allowCoreThreadTimeout=false后, 当前线程数大于corePoolSize,如果线程空闲等待时间超过keepAliveTime,则该线程会被回收。
如果设置allowCoreThreadTimeout=true后, 当前线程数小于corePoolSize时,线程池的线程空闲等待时间超过keepAliveTime,也会被回收
maximumPoolSize:最大线程数(默认值:Integer.MAX_VALUE)
keepAliveTime:空闲线程存活时间(默认值:60秒)
unit:时间单位 (秒)
workQueue:工作队列大小(默认值:Integer.MAX_VALUE)
threadFactory:线程工厂
handler:拒绝策略。(默认AbortPolicy策略)
JDK默认的拒绝策略有四种:
1.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。(默认值)
2.DiscardPolicy:丢弃任务,但是不抛出异常。可能导致无法发现系统的异常状态。
3.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。
4.CallerRunsPolicy:由调用线程处理该任务。
参考文章:https://www.jb51.net/article/209548.htm
5、线程池的一个任务执行过程是怎样?
当前线程数是否大于corePoolSize(5)
小于corePoolSize,直接创建线程
大于或等于corePoolSize,再判断工作队列是否已满(8)
未满,创建临时线程存入工作队列的尾部,等待执行
已满,再判断是否大于maximumPoolSize(20)
小于maximumPoolSize,创建临时线程去执行任务
大于或等于maximumPoolSize,执行拒绝策略
