连连支付Java后端实习生一面
自我介绍+项目介绍:5分钟左右
项目面:
你在简历中的两个项目里都是负责人是吗?是的。
在这两个项目中遇到的印象比较深刻的技术问题/项目推进和沟通方面的问题?协调不同团队成员的开发进度,要尝试去了解各个成员最近都在做的事情,尊重大家的现实情况,在不施压的情况下最大化开发进度;前后端的协作问题,接口规范,先开发后端还是先开发前端,或者相反又或者是一起推进(数据渲染中字段修改麻烦,数据库层面可能也会面临修改),团队项目的初期沟通是十分重要的;
那后面是否有提出一些改进的方案呢,比如后端定义好一些接口规范?每次会议都进行接口的讨论,基于RESTful API规范进行开发,尽量减少二次修改的可能性;
那么在开发过程中是否遇到过一些开发层面的困难呢?多级评论功能的实现;并发安全的问题,比如挂号服务的号源超卖问题,讲述项目场景(多线程场景下select后紧跟update),解决问题的方案(单体加锁->分布式锁),后端开发基本原则是尽量不引入中间件去解决问题,尝试去从MySQL的锁的角度去解决问题,即使用select for update来得到最新的号源数量。
有没有考虑过for update启动的锁它的范围是什么样的?当某个进程使用select for update的时候,其他线程想要加锁的时候就会被阻塞,所以能够得到最新的值。
他一定加的会是行锁吗,有没有可能是间隙锁或者一些范围区间的锁是由什么决定的?没有考虑到这个问题)(新阅读了一些资料,估计是想问间隙锁,就是幻读以及锁范围太大的情况)。
这样可能会有个问题,就是范围相对比较大,所以可能存在死锁的这种情况?应该不满足循环等待这个条件。
每次挂号的时候需要加锁的数据是不是只有一行的?是的,所以应该不会产生这种资源的互相等待的情况。
那除了这个之外呢是否还有对其他资源进行加锁,这一次的挂号操作?先尝试去医院端那边更新,只有对方那边成功返回这个情况才考虑我们这边数据进行号源数量的同步减少的原子性操作。
这个是调用的第三方接口吗?不是的,是我们自己模拟的一个医院服务器,通过HTTP请求进行通信。
对方告诉我们处理成功了是不是就是意味着在数据层面上医院端已经处理成功了?是的,所以我们需要对数据进行一个同步。
那如果失败了呢?就不做其他的逻辑了。
那假设医院端的信号没有发过来呢,比如网络包丢失了或者发生异常情况了,导致数据没有传输过来?可以采用超时机制,也就是如果在一定时间内没有返回,那么可以超时重传。
相当于失败了就要去重试了,那假设对方已经处理成功了数据库也更新了只不过返回的包丢失了,那么重传是不是就导致了多次重复处理?没有考虑到这个问题。
本质是分布式系统之间的一致性问题,你现在想想假如要保证一致性该怎么做?定时任务假如不一致那么就进行同步化。
你怎么知道什么时候不一致呢怎么进行同步呢?网站下线进行同步迁移(其实当时没懂这个场景,乱回答的)。
针对这一笔订单,既然我们其实并不知道医院方返回给我们的数据是否是可信的,到底是丢包了呢,还是他们发生异常了呢或者各种情况那么如何进行一个补偿性的操作弥补这个问题?重试一次。
可能有点太粗暴了,比如一笔支付要付钱,但是你现在要依赖对方返回给你的这个支付是否成功的一个接口,既然依赖他,但是结果又不明确,所以不能轻易无脑当做失败,因为他们那边可能实际上的处理是成功的,那么是不是就可能会出现问题?可以考虑做一个缓存,记录我们发出去的请求id,当对方收到我们的请求的时候也记录下这些请求id,每个请求设置多个状态,发送方记录是否收到回传,接收方记录是否收到信息,定期校验这两个缓存,如果我们已经发送且对方已经收到,但是我们还没收到对方的那么就让对方再发一次请求,如果我们发出去的对方没有收到,那么我们就再发一次请求。
那么对方也需要一个缓存?是的,要协商一下。
那基本不可能,因为公司提供的接口是固定的,不可能为你单独添加这样的扩展,还有什么方案吗,有个比较简单的方案,你想想?把我们这个请求涉及到的数据再查一次对面数据库的档案来进行比对,只有查询的操作。
好的,你基本说出来了,就是总的来说掉单了,那么就要放在一个掉单表里面,通过定时任务来获取掉单的数据,通过对应的接口来查询订单的状态,基本是这样的一个方式,因为既然不明确,那么就多问几次,查询操作其实影响是比较小的,你项目里用到了zset,你说说key存的是什么?不是我负责的这块(得去恶补一下了,为了显得好看临时包装的)。
项目里用到了Feign,那你有了解过其他的一个RPC框架吗?Spring Cloud&&Dubbo和gRPC&&Thrift。
你用到了微信支付的SDK,那你们这个网站是上线已经运营了吗?(因为SDK的使用需要注册一个服务号类型的公众号后认证该公众号同时提交资料申请微信支付,开户成功后登陆商户平台进行验证最后签署在线协议,所以才有这个问题,我推测)用的是网上的人提供的一个凭证。
你做的还是团队的成员做的呢?参与但是没有负责这个模块,设计了数据库的表和订单的一个监控行为。
推广的时候有没有考虑过资金损失的场景?我们这个除了云服务器应该没有资金损失吧..
付款的时候可能会涉及到部分退款和全额退款还是补偿,那么就可能会损失资金?我们采用的是全额退款,就是调取第三方接口。
就是说即使那笔订单已经退过了,但是再次发起退款还会再退?这个会根据我们数据库里的订单记录来查询退款状态。
八股文:
MySQL的回表你知道吗?聚簇索引/二级索引相关。
索引覆盖知道吗?联合索引相关。
索引失效有了解过吗?不太清楚。
场景其实挺多的,好吧那索引下推呢?最左匹配原则以及在使用 ICP(索引下推) 的情况下,如果存在某些被索引的列的判断条件时,MySQL 服务器将这一部分判断条件传递给存储引擎,然后由存储引擎通过判断索引是否符合 MySQL 服务器传递的条件,只有当索引符合条件时才会将数据检索出来返回给 MySQL 服务器 ,减少查询压力。
数据库的隔离级别了解吗?四大隔离级别。
分别会出现什么问题,哪些级别是去解决什么问题?脏读&&读提交,不可重复读&&可重复读隔离级别;
幻读了解吗?概念有点记不清楚了(早上面试完没有及时复盘去搜资料,吃了亏)。
可重复读是怎么实现的你能说一下吗?MVCC机制。
Spring里面有几种实现事务的方式呢?编程式事务(TransactionTemplate的execute方法&&TransactionManager的commit和rollback);声明式事务(@Transactional注解);注解失效的场景。
看你用了RabbitMQ,你能说说不同角色比如生产者消费者以及消息队列本身消息丢失的一个解决方案吗?生产者(开启MQ事务;开启Confirm模式);中间件(Emm忘记了);消费者(ACK自动确认机制的关闭);
消息是存储到哪里的呢?哦对,是磁盘,所以中间件是采用持久化的方式来避免丢失的。
反问环节
#JAVA##后端##实习#