P2P项目专题(java)
1. 具体的你在P2P项目中都干什么了,你负责哪一块,每一块实现的时候用到了哪些技术?
2. 你们项目的并发量设计了多少?
3. P2P项目上线了吗?
4. 你项目中的事务是怎么处理的?
5. 在秒杀项目中使用消息队列ActiveMQ进行流量削峰,如果ActiveMQ接收消息失败了,怎么办?
- 消息在接收后会被服务器删除,为了避免接收消息失败而消息又被服务器删除,此时我们可以关闭自动确认机制AUTO_ACKNOWLEDGE,采用手动消息确认机制,由程序进行消息的确认,接收消息发生异常,则不确认消息,以便于下次可以再次接收。
6. 在秒杀项目中使用消息队列ActiveMQ进行流量削峰,如果ActiveMQ挂掉怎么办?
-
第一点,首先消息需要使用持久化消息,服务挂掉,重启服务后消息依然可以消费,不会丢失;
-
第二点,ActiveMQ采用主从模式搭建集群,比如搭建3台主从模式的ActiveMQ集群,提高服务的可用性;
7. 在交易中,如何控制超卖问题(卖出去的商品大于数据库实际商品库存)? -
解决超卖问题,一个是
借助于锁机制实现,这里面有线程锁、数据库锁、分布式锁等
,另一个是借助于某些中间件产品实现,比如Redis; -
如果我们的服务只是部署了一台服务器,我们通过线程锁即可控制并发问题,控制了并发问题,也就不会产生减库存的冲突,即不会产生超卖问题,这种实现,效率不高,而且只能是单机部署,实际项目不会采用;
-
如果我们的服务是
集群部署
,线程锁就不行了,此时可以使用数据库锁或分布式锁控制并发问题
,从而控制减库存的冲突,避免超卖问题,数据库锁可以采用乐观锁、悲观锁,其中乐观锁比悲观锁效率稍高,在实际项目中使用多一些,悲观锁使用较少,但由于数据库本身的性能和并发处理能力并不理想,在高并发项目中,使用数据库锁也是不合适的; -
使用分布式锁解决超卖问题,在实际项目中有相关真实的案例,
主要采用zookeeper实现分布式锁,
分布式锁是将我们的线程锁扩展为多个jvm的锁,代码在多个jvm上执行时,分布式锁也能进行锁定,因为能锁定就能控制并发,控制了并发即能控制减库存的冲突,即可解决超卖问题; -
使用一些中间件产品解决超卖问题被经常使用,最被常用的是Redis,在实际项目中被大量使用,由于Redis是单线程的,不管有多少个并发请求,Redis会将请求排队进行处理,即一个一个地有先后顺序地处理,这样即不会有并发问题,即不会产生减库存的冲突,从而解决减库存的超卖问题;
8. 在实际项目中,是否使用过多线程?
-
在P2P项目中,比如在用户投资到期后需要给用户回款,此处我们使用了多线程,加快整个回款的速度,我们先从数据库获取所有待回款的数据,然后创建一个线程池,每个回款是一个线程,将这些回款线程提交到线程池中执行,从而充分利用服务器的CPU资源快速为用户回款;
-
再比如当每个投资用户生日时,我们会在用户生日当天给用户送一个生日红包,由于同一天有大量用户生日,我们也是通过多线程为用户送红包,先从数据库获取当天生日的用户,然后创建一个线程池,给每个用户发红包是一个线程,将这些发红包线程提交到线程池中执行,从而加速生日红包的发送任务;
9. P2P中的投资及收益金额采用Java中的什么数据类型进行存储?
- 由于涉及到精度问题,我们项目中都采用
BigDecimal类型
,以避免在计算收益时,导致金额精确的损失。
10. 你们这个P2P项目上线后采用的是什么访问协议?
- 为了数据传输的安全性,我们的p2p项目访问的时候,
全部都https协议,https协议会将数据加密传输,提高安全性,
我们当时公司的运维部门采购了https的安全证书,在服务器上搭建了https协议的访问方式,如果用户采用http访问,我们会自动跳转到https协议打开网页;
11. 你们P2P项目对金钱是怎么处理的?
- 项目中涉及到的资金问题,有几处处理,一个是我们有一个后台对账系统,每天会根据第三方支付系统的结算清单,与我们这边的充值数据进行对账,保证我们与第三方的数据一致;
- 对于用户投资到期后,提现自己的本金和收益,我们后台系统有专门的提现审核功能,通过系统审核该投资用户的资金流是否有异常,无异常方可通过提现审核。
12. 你们使用定时任务是干什么的?
- 我们使用定时任务主要是处理一些
定时或延迟的工作
,这些工作不需要马上处理,就配置好时间,让程序在指定的时间或者指定的频率去执行,比如我们在理财产品投资满标后,会生成收益计划,投资到期后给用户返回收益等,我们都是采用定时任务来完成的,Spring框架集成支持定时任务,我们采用的就是spring框架下的spring-task来实现定时任务;
13. 请你描述一下整个P2P的支付流程?
- 支付模块,我们当时对接了两家,一家快钱支付,一家丰付支付,当时是由我开发的,我们的商务和对方谈好后并签订了支付协议,对方的技术给我们提供了相关的支付接口文档及demo,我主要是根据对方的接口文档进行开发,首先是调用对方提供的支付下单接口,把我这边准备好的参数传给对方,然后调用对方接口,根据对方的返回信息进行处理,如果对方返回成功,然后调用对方的获取短信验证码接口,此时将给用户的手机号发送一个支付验证码,用户输入支付短信验证码后,点击确定支付,然后我们提交支付请求,对方将返回支付的结果,支付结果对方会通过两种方式返回,一个是同步返回,一个是异步返回,我们接收对方的这两个返回结果,更新我们的数据库状态,完成整个支付流程;
14. 请介绍一下这个P2P项目的整体架构及你做了什么?
-
整个P2P项目第一个版本,我们是采用普通的ssm框架进行开发的,是一种集中式的开发方式,上线一年之后,随着公司发展和业务需要,我们原来的ssm架构的项目,代码非常庞大和混乱,一个方法可能出现好几百行,里面很多逻辑,要新增一个功能,开发特别慢,由于修改这个功能,可能又导致另一个功能出现问题或者bug,后来我们对整个p2p项目进行了重构,采用分布式开发方式,当时选择了非常流行的Dubbo分布式开发框架,
主要架构是spring mvc + spring + dubbo +mybatis的架构
,另外还有一些中间件,dubbo注册中心zookeeper,缓存Redis、队列ActiveMQ、文件存储FastDFS,Session同步Sprign Session等; -
在这个项目中,我参与了整个过程的开发,当时公司处于快速发展中,工作分工并不明确,前后台基本都会参与开发,我先是开发了p2p前端网站部分的理财产品展示、用户投资、用户充值三大功能模块,同时开发这些模块对应的Dubbo服务,其中的支付模块,是单独一个项目,主要对接第三方支付接口,快钱和丰付,这个项目全部是我完成的,对此我也比较熟悉。
15. 你们这个P2P项目的并发量大概多少,部署了几台tomcat?
- 我们P2P项目有三端,一个是PC端,一个是H5端,一个的App端,其中H5端的流量比较小,并发量也很低,PC端和App端并发量高一些,其中App端并发量最大,因为App端的用户最多,App端的后端接口部署了5台tomcat,最大的并发是3500左右,这个3500是同时处理请求的能力,而不是一段时间或者多少秒的处理能力,QPS大约是30万左右,整个平台大约有200万左右的用户;
16. 你们P2P项目中分布式事务怎么解决和处理的?
- 我们这个P2P项目,后端的服务,没有再拆分,就是一个dubbo服务,所以一个事务请求会提交到一个项目单元上执行,这样我们是避免了分布式事务的问题,因为对于一般的中小型项目,也建议不涉及到分布式事务的问题,也就是说能避免尽量避免,而在一些大型项目中无法避免需要分布式事务时,目前常用的解决方案是:
1、两阶段提交;
2、三阶段提交;
3、TCC补偿;
4、异步确保;
5、最大努力通知;
17. 为什么充值会发生掉单问题?怎么解决的?
- 充值时候与第三方接口对接的过程中,涉及到多个系统,每个系统都无法保证整个充值过程中都是100%的高可用,还有网络等原因,就不可避免会出现某个系统成功了,另一个系统没有成功的问题,当出现这种情况的时候,这笔充值就会出现数据状态的不一致,也就是掉单,为了解决该问题,我们采用的是一种补偿机制,在发生掉单后,进行自动补偿,系统开启一个定时任务,对出现掉单的订单进行再次补偿,我们会先检索出掉单的订单,然后通过第三方支付系统的接口,查询该订单的充值状态,如果第三方已经成功了,我们这边系统就需要更新相关的数据;
18. 你们的P2P项目使用Redis主要做什么?
- 在该项目中,最初没有使用Redis,是边运营边迭代升级的,在没有使用Redis的时候,我们的前端业务系统上的所有数据都是直接到达数据库获取,导致我们后端的数据库经常出现cpu及io压力很大,
后续我们将前端业务系统上一些不需要实时更新的数据,一些频繁查询的热点数据,进行了Redis缓存存储,来提升系统的能力。
19. 生产环境(线上环境)中出现的问题,你们是怎么解决的?
- 生产中的问题,发现后由该系统的技术负责人全力协调解决,如果是紧急影响较大的bug,会暂时下线该功能,快速对该问题进行修复,然后由测试团队进行严格测试,再上线,再次上线前将之前由于bug产生的数据问题进行修复。处理线上问题的步骤是先判断问题的严重程度、波及范围等,优先快速恢复服务,让用户可以继续使用,然后再解决bug,排查bug主要是根据线上日志、数据库数据等;
20. 你们P2P项目的利息是怎么计算的?
- 利息的计算,公司的产品经理提供了计算公式,我们技术人员
根据计算公式进行计算,由于涉及到精度问题,所有计算都是采用BigDecimal类型进行加减乘除;
21. 用户在你的P2P充值,如何防止你的请求被黑客拦截,给你返回一个假的充值成功结果?实际用户未支付,但你系统给用户充了值?
- 这个问题,我们有
签名验签机制
就保证了,我们的请求中都有一个签名串,签名串黑客无法伪造,如果签名串验证无法通过,我们将不会给用户充值,提示签名失败;
22. 如何防止用户重复点击、重复提交充值?
- 用户点击后我们会将用户的提交在redis中存放一个标志,如果用户重复提交,我们会检查redis的标志,来拒绝用户的第二次提交,值处理第一次提交请求;
23. 用户的钱的整个流转过程是怎么样的?
- 用户通过第三方充值渠道,将用户银行卡的资金划入到P2P平台在第三方支付公司开通的账户中,然后我们会把用户的充值金额记录在我们的数据库用户资金记录表中,当用户投资某个产品,比如100元,我们会将用户资金记录表中的资金冻结掉投资金额100元,当投资到期后,会产生收益,比如收益是1元,那么我们就会将之前冻结的100元,再加上收益1元返回到用户的资金记录表中,最后用户提现101元,我们的后台结算系统审核用户的提现金额,审核通过后,通过第三方支付公司,从我们P2P平台在第三支付公司开通的账户中扣除101元,将101元打入用户提交的银行账号中;
24. 请介绍一下你做的这个P2P项目?
-
该项目是一个基于互联网金融的网贷平台,有理财端和借款端,我主要是参与做的理财端,该项目主要包括PC站、M站、APP客户端(Android、iOS),由多个项目系统构成,包括前端业务系统PC端和H5端、数据接口系统、核心系统、结算系统、支付系统、定时任务系统、营销活动系统,红包系统,合同签章系统、实名认证接口系统、轮播图系统等。
-
整个项目采用分布式开发模式,Tomcat集群部署,采用Nginx实现负载均衡和动静分离,MySQL主从复制模式,Redis集群模式,ActiveMQ的异步处理、Zookeeper做为注册中心,Spring session共享,Redis集群缓存热点数据提升系统吞吐量,整个项目采用的技术架构主要是:
Spring mvc + Spring + Dubbo +MyBatis
, 采用Dubbo实现项目间的RPC调用,采用分布式文件系统FastDFS存储投资借款合同。 -
我在这个平台中参与过前端业务系统,Dubbo数据接口系统,支付接口系统、合同签章系统的开发,对这几个系统比较熟悉,通过这个项目,遇到过一些问题,也学到很多东西。比如最早的时候,对Dubbo开发框架不是很了解,通过该项目,现在比较得心应手。
25. 你都知道哪些技术可以完成异构系统整合?
- httpclient、webservices
26. 自我介绍?
- 面试官您好,我叫XX,非常高兴认识您。到目前为止我从事Java软件编码工作已经3年了,之前一直在石家庄的XX公司工作,他是一家外包公司,在这期间我接触了有六七个项目,其中包括政府部门的项目、银行相关的项目、还有互联网公司相关的项目,最近做的是一个P2P互联网金融项目。北京这边毕竟软件环境好一些,有一些朋友也来到北京发展情况挺好的,所以前两天把石家庄的工作辞掉了,想在北京闯一闯。这就是我的个人情况,谢谢。
27. 你还有什么要问的吗?
基本上也没什么问题了,我就是想知道一下咱们团队开发使用的是哪些技术,如果可以的话,我回去抓紧时间熟悉一下。比如用的哪些框架,后台使用的什么技术,前端使用的什么框架等。
28. 项目经理怎么监控代码质量的?
- 不定期的进行代码走查(代码review),项目经理、组长、程序员一起到会议室,打开投影仪,把最近几天的代码一行一行的看一看,主要看看代码的注释、代码的格式、代码的命名规范、代码的冗余度等。
29. AJAX跨域你是怎么实现的?
-
首先我先给您解释一下我理解的跨域,为什么会有跨域呢?这是因为
浏览器的同源策略导致的,同源策略是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。它的核心就在于它认为来自任何站点装载的信赖内容是不安全的。当被浏览器半信半疑的脚本运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意的资源。所谓同源是指:域名、协议、端口相同
。所以跨域限制主要的目的就是为了用户的上网安全。不过在实际的开发中有很多情况下需要我们实现跨域访问,因为同一个项目的不同服务可能部署在不同的服务器当中,服务器A调用服务器B当中的资源时,就涉及到了跨域问题,那么怎么解决AJAX跨域呢? -
第一种方式:JSONP方式解决跨域问题。
jsonp解决跨域问题是一个比较古老的方案(实际中不推荐使用),实际项目中如果要使用JSONP,一般会使用jQuery对JSONP进行了封装的类库来进行ajax请求。