# job-interview **Repository Path**: jacob-lab/job-interview ## Basic Information - **Project Name**: job-interview - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-07-29 - **Last Updated**: 2023-06-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 电子合同签章 #### 电子合同签章模块 ![电子合同签章模块](./电子合同签章模块.jpg) #### 电子合同签章时序图 ![电子合同签章时序图](./电子合同签章时序图.jpg) #### 合同签署主要流程 1. 数据无需重新生成且已存在库表,返回处理成功,否则继续下面流程。 2. 读取合同文件模板,将合同参数填充到模板,然后生成合同PDF文件。 3. 调用三方接口:上传合同PDF文件,处理成功接口返回合同唯一编号。 4. 调用三方接口:添加合同签署人信息。 5. 调用三方接口:转让人和受让人盖章。 6. 调用三方接口:锁定合同,签署完成。 7. 调用三方接口:下载签署成功的合同。 8. 上传签署的合同文件到集团文件系统。 9. 签署文件保存本地,数据存入数据库。 #### 合同检测主要流程 1. 读取本地已签署成功的合同PDF文件。 2. 从合同PDF文件内读取表单域内的参数。 3. 重新请求接口,从业务数据库获取合同参数。 4. 两份参数不同则告警,相同则更新库表记录,标记为无差异。 5. 每天按协议类型,随机抽取已标记为无差异的合同,邮件通知人工抽检。 #### 数据基本情况 库表记录数:约10亿行。 每行表数据大小:约420B。 所有表数据总大小:约390G。 数据库分库分表类型:年库月表。 系统运行2年半,每天生成约110万条记录,每张月表约3000万行。 电子合同协议类型主要包含:普通注册协议、网贷理财注册协议、授权委托书、产品购买协议、借款协议、债权转让协议等。其中占比最多的为《产品购买协议》、《借款协议》和《债权转让协议》。 数据截至2020-11-30,累计借贷75,915,733笔。 数据截至2020-11-30,累计借贷金额86,439,536,778元。 数据截至2017-09-30,出借人平均每笔投资匹配151位借款人。 数据取自官网:https://www.juzilicai.com/info-disclosure/data-disclosure.html ## 多级缓存组件 #### 缓存组件结构 ![缓存组件结构](./缓存组件结构.jpg) #### 缓存组件数据一致性方案 ![缓存组件数据一致性.jpg](./缓存组件数据一致性.jpg) #### 缓存组件读数据流程 ![缓存组件读数据流程.jpg](./缓存组件读数据流程.jpg) 多级缓存组件里使用的功能模块,都是基于Java SPI机制实现扩展,开发者可以扩展自己的实现方式,然后接入到缓存组件中。目前提供扩展的功能模块有以下几个: 1. 缓存变更同步策略:Redis、Hippo、Zookeeper。 2. 缓存存储扩展策略:Local Cache、Remote Cache。 3. 缓存监控数据消费策略:上报火眼系统、日志文件。 4. 缓存数据对象序列化策略:Kryo、Jackson、Fastjson。 #### 缓存分类及特性 1. 本地缓存(Local Cache): 优点:缓存和应用在同一个进程内部,请求缓存速度非常快,没有过多的网络开销等性能消耗。 缺点:缓存与应用耦合,各个应用无法直接共享缓存且需自行维护。同一份数据存在多个副本,较浪费内存。 2. 分布式缓存(Remote Cache): 优点:缓存自身是为独立应用,与本地应用隔离,多个应用可直接共享缓存,使用分布式缓存容量可以很大。 缺点:缓存为独立应用,存在第三方依赖风险,一旦第三方组件挂了,整个缓存系统不可用,造成缓存雪崩。 3. 多级缓存(Multi Cache): 第一级缓存使用Caffeine内存缓存,第二级缓存使用Redis。由于大量的缓存读取会导致L2的网络成为整个系统的瓶颈,因此L1的目标是降低对L2的读取次数。目前多级缓存主要解决以下问题: a. 使用内存缓存时,多个应用节点无法共享缓存数据,同一份数据存在多个副本比较浪费内存。一旦应用重启后,由于缓存数据丢失,缓存雪崩给数据库造成巨大压力,有可能导致数据库宕机。 b. 使用集中式缓存,由于大量的数据通过缓存获取,导致缓存服务的数据吞吐量太大,带宽跑满。现象就是Redis服务负载不高,但是由于机器网卡带宽跑满,导致数据读取非常慢。 #### 缓存数据变更集群同步策略 在缓存节点数据变更时,会同步给其他节点,同步过程中存在一定的时延。目前基于Hippo、Redis和Zookeeper的发布订阅功能实现了缓存同步策略: 当Key有Put或Evict操作时,缓存同步策略通过组装统一的同步Command发布到缓存配置中心,其它缓存节点订阅配置中心消息。当其他节点收到同步Commmand消息,会解码Command并执行同步命令,以实现数据同步。 为了简化数据同步操作,对于Put操作,缓存同步策略在同步到其它节点时会转换成Evict Key操作,当这些节点遇到Get时,会重新加载最新数据,以保证缓存节点数据的最终一致性。 配置中心为Hippo:通过注册Hippo配置变动监听器来实现各缓存节点Command消息的同步。 配置中心为Redis:采用Redis的发布订阅模式Publish/Subscribe实现缓存各节点Command消息的同步。 配置中心为Zookeeper:用Curator的NodeCache监听Node,各缓存节点对NodePath注册NodeCacheListener监听器。当Node的数据更新或被删除时触发监听,以实现各缓存节点Command消息的同步。 ## Redis 可重入分布式锁 ![Redis可重入锁执行流程图](./Redis可重入锁执行流程图.jpg) #### 设计原则 高性能:有较好的获取锁和释放锁的性能。 高可靠:依赖组件的高可用性,如崩溃时主从切换等。 互斥性:同一时刻只能被一台服务器的一个线程所持有。 防死锁:保证锁最终都能释放掉,其他线程能正常获得锁。 安全性:加锁和解锁必须是同一线程,操作遵循隔离性和原子性。 每把“锁”对应一个 hash 结构,key为锁的标识,field为锁的持有者信息UUID:ThreadId,value为锁的重入次数。每个模块流程对应一个lua脚本,通过lua脚本保证隔离性,主要流程如下: 1. 首次加锁流程: a. 判断锁key在master节点是否存在:EXISTS key。 b. 锁不存在,加锁:HINCRBY key UUID:ThreadId 1。 c. 设置锁的过期时间:PEXPIRE key milliseconds。 d. 加锁成功后,lua脚本返回 null。 2. 加锁成功创建定时任务,每隔milliseconds/4执行锁续期,续期流程: a. 判断锁的持有者是不是UUID:ThreadId:HEXISTS key UUID:ThreadId。 b. 锁的持有者未变更,则重置锁的过期时间:PEXPIRE key milliseconds。 只要定时任务线程还在,且锁的持有者未变更,持有者就能⼀直持有这把锁。 3. 同一台机器上的同一个线程,再次请求加锁时,重入锁流程: a. 判断当前锁是否被当前线程持有:HEXISTS key UUID:ThreadId。 b. 满足条件则将获取锁的次数加1:HINCRBY key UUID:ThreadId 1。 c. 重置锁的过期时间,此时锁续期的定时任务仍然在后台正常运行。 4. 锁未释放,其他线程加锁时阻塞等待(等待时间waitTime)流程: a. 锁已存在,且被其他线程持有,返回锁的剩余存活时间:PTTL key。 b. 线程尝试加锁失败后,循环等待MIN(ttl, waitTime)时间后再尝试加锁。 c. 如果等待超时仍未获取锁直接返回失败,否则一直等待,直到获取锁成功。 5. 锁的持有者主动释放锁流程: a. 判断锁是否存在:EXISTS key。 b. 锁存在,继续判断持有者是否为当前线程:HEXISTS key UUID:ThreadId。 c. 锁存在且持有者为当前线程,将锁的重入次数减1:HINCRBY key UUID:ThreadId -1 d. 如果锁的重入次数等于0,当前线程主动释放锁成功,并且执行DEL key删除锁记录。 e. 如果锁的重入次数不为0,当前线程仍持有锁,重置锁的存活时间:PEXPIRE key milliseconds。 6. 业务超时,被动释放锁流程: a. 如果服务宕机,持有锁的线程和续期的线程都没有了,当存活时间过后key就会被删除,锁也就被释放了。 ## 银行存款项目 ![银行存款交易流程图](./银行存款交易流程.jpg) ## 营销 OA 系统 #### 营销系统业务流程图 ![营销系统业务流程图](./营销系统业务流程图.jpg) #### 营销系统佣金计算 ![营销系统佣金计算](./营销系统佣金计算.jpg)