HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

50 天 10 万行代码,一号专车系统重构细节回顾

  • 2016-08-23
  • 本文字数:7925 字

    阅读完需:约 26 分钟

2013 年底,我关闭当时的创业项目,无所事事之时,打电话向快的 CEO Dexter 请教,当时快的和大黄蜂刚刚合并,他建议我可以先和大黄蜂 CEO 李祖闽(Joe)聊聊。

和 Joe 第一次见面是在虹桥火车站的一家肯德基里碰头,当时我看不太懂打车这个项目。那次碰面,我们聊的却不是出租车,聊的全是专车。两年多前的那时候,做这一块的不多,真正意识到这是个大机遇的且投入资源的创业公司比较少。Joe 跟我讲了许多他对未来专车的构想,一下子就挑起我非常大的兴趣,简单说就是 High 了:)。

Joe 也跟我讲了现在公司在技术上碰到的一些瓶颈,限制了业务的开展,比较痛苦,我们原定半个小时的碰面,结果一聊聊了 4 个多小时后,两人意犹未尽,又一起打车回市区聊了一路,下车的时候我和他约好第二天就去大黄蜂报到。

故事就这样展开了。。。

定时炸弹

2013 年 12 月 26 日,刚入职的第一天,我看到了打车大战满地销烟的惨状,快的、滴滴、大黄蜂等多家打车公司刚刚在上海打过几波大战,当时大黄蜂打车在上海市场出租车市场的占有率可以排进前三。快的大黄蜂合并后,虽然明确大黄蜂未来的战略方向转做专车业务,同时也上线了第一版本的专车系统,并将部分出租车请求转发给快的打车。但出于种种因素考虑,还是把一大部分的工作重心依然留在出租车上面,并没有完全放弃出租车业务。

我初进大黄蜂,又恰逢临近春节,专车系统刚刚上线不久,我们想要在上海做一次“春节 50/100 元专车接送机场(虹桥、浦东两个机场)”的活动,但原来的产品及部分开发人员出现了一些波动,正在陆续办理离职手续,留下的开发人员状态也不太稳定,好在专车系统的即将离职的同学还比较靠谱,被我拉着讲了一个周末的数据库表结构及代码,于是我就是在边看代码边熟悉系统的基础上,进行业务开发,技术总监写代码不算什么,其实后面重构上线前期我还做过一整周的测试

2014 年春节很快过去,快的和滴滴在全国掀起一波补贴大战,大黄蜂的出租车业务在上海市场协同快的也侧面参与了一些,但大部分精力已经开始转向专车业务,我对原来的系统也已经比较了解,当时的系统情况大致是这样:

当时出租车主要开了两个城市,上海和广州,各部署一套系统,数据库、缓存、Web 服务、API、定时任务都在两地部署,由中心库负责定时同步主要的数据,比如用户信息等,但因为两地市场开拓的时候,运营策略不同,比如各项优惠、加急令、司机补贴等政策在两地各有不同,于是就维护了两套 PHP 代码,大致逻辑相似,细节又各有不同。

而专车系统是后来开发,以 Java 为主要开发语言,基础数据(用户、优惠券、订单等)依然依赖于出租车数据库,但主要数据库和代码部署在上海,因为专车只开了上海市场,所以暂时没有什么影响。这样的系统架构限制了当时的业务发展,也给未来留下了许多定时炸弹,下面我们会展开讨论。

但在这里需要申明一点:看到这样的系统结构,确实存在许多不合理性,单纯一张九十几个字段订单表就能干掉一大票观众,但我要为其辩护,在当时打车大战初期,业务的发展是野蛮式的,每天各种补贴政策、活动的调整,开发人手严重不足,技术完全是被业务拖着跑,相信经历过创业这个阶段的人都会有深刻感触。

很显然,这样的系统架构已经不能满足当前的业务需求,越往后拖,隐患越大,定时炸弹越多,我评估下来,主要存在这么几类大的问题:

1、多地保存数据,多地多份代码不可维护。

  • 多地逻辑代码冗余:代码无法维护和管理,添加一个业务逻辑要同时改两份码,或者只改一份,但下一次增加新业务逻辑时,因为两个地区的代码逻辑差异越来越大,需要非常小心,坑越挖越深;
  • 数据同步问题:上海的乘客到广州不能下单、优惠券不见了,反之亦然,上海的乘客出差去外地后,也不能下上海的机场、车站的预约订单,甚至不能登陆;
  • 并发冲突:两套数据的维护,一不小心就出现数据不一致的问题,无法合并,也留下被攻击的隐患;

2、无法快速开城,每开一个城市都要部署一套存储和代码,准备硬件、进机房、部署、调试,效率太低,还要做好数据的同步,及当地的新政策的业务开发,开一个城市需要一个月左右的开发周期。

3、数据库表结构和代码许多地方都是堆出来的,不可维护,比如一张订单表有九十几个字段;PS: 你没有看错,就是九十几个字段。

4、手机端通过轮询接口调用 API,为了快速获取成单、通知、补贴政策调整等信息。但毫无疑问,这个对于手机的资源消耗(流量、电量)很大,也增加服务器的开销。

5、公共服务和业务代码耦合太紧,比如优惠券、支付等模块;

6、专车司机公里数计算不准确,出租车司机带有打表器,专车司机主要靠手机 GPS,手机会有信号不准,接受不到 GPS(跳点、断点、隧道、高架)等情况;

7、系统压力大,活动一上来,慢查层出不穷,各个状况出现;

8、API 接口没有加密机制,容易被刷,用户身份容易被窃取;

9、无法适应专车灵活多变的业务场景,每做一个活动,都需要 2,3 周的开发;

还有许多细节,比如轮询接口直接访问数据库、GPS 坐标系混乱、司乘价格绑定、重复上报 GPS、电子围栏不可维护、支付、定位、保险、第三方接口接入等,已不能满足业务发展,这里就不再一一列举。在这样的前提下,内部反复多轮沟通后,我们启动了重构计划。

和时间赛跑的重构马拉松

2014 年 4 月 9 日,我们正式启动了重构,重构目标就是在解决这些问题的基础上,完成整个系统的第一阶段的服务化工作,大致目标包括有:

  • 设计一套灵活的专车系统,以应对专车复杂的业务场景;
  • 整个系统,包括存储及服务集中部署,便于管理维护;
  • 需要支持出租车、专车两项业务的迅速开城;
  • 手机端和服务器的实时消息(包括接单、抢单、成单、通知、计费等)推送采用长连接;
  • 接口定义一套的新的数据协议,请求加密,防 token 窃取,请求防篡改;
  • 采用多级缓存方案,数据库、Redis、MongoDB、分布式本地缓存;
  • 引入分布式日志系统(重构后期来不及加入,只做了一部分,但后期为此吃足苦头,快的的兄弟们给了我们很大的帮助);
  • 公共服务及业务服务的抽象及服务化;
  • 南、北向接口分离,南向接口主要对接外部供应商,北向接口仅指出租车部分,主要面向第三方渠道、比如携程、去哪儿等。
  • 数据库分库、分表、读写分离;
  • 优化寻找周边司机,道路距离计算等算法;
  • 上阿里云;

第一阶段的服务化设计后的架构图,大致如下:

上图中大部分的设计都实现了,并取得了不错的效果,但也埋了坑。其中订单服务在重构中期因为出租车业务的停止,为了贪图调用方便,又把它合到专车核心服务,后续在订单量爆发的时候,为此吃足苦头。出租车司机 API 也因为方向问题停止维护。

在当时的环境下,重构这样的一个系统主要有这么几大挑战:

1、 时间不够:项目计划梳理需求和旧有系统逻辑 2 周,开发 & 测试 10 周,上线 2 周,预计在 7 月底左右上线。

2、 开发资源严重不足:前线的还在继续作战,原来系统还需要有人留下做维护性开发,真正能抽出来做后端系统重构的开发人员只有 5 个(包括我),4 个 Java 开发,1 个 PHP 开发,其中有 3 个都是新招的开发人员。APP 开发也只有 4 个人参加重构,同时负责 iOS、Android。

3、 对公共模块业务不熟悉:因为专车系统是搭建在原出租车系统之上,所以大部分公共模块都依赖出租车业务,而原出租车业务的开发人员流动比较大,代码也过了好几手之后,留下来的人员对其业务细节,遗留代码并不了解,这将对后续的数据迁移留下很大隐患;

4、业务复杂:如何设计一个灵活多变的专车系统,以适应快节奏的运营策略。专车因为其特性决定了它的业务复杂多变,随便举几个例子:

  • 策略 1:希望做接送机场订单一口价的活动,春节前,终点为虹桥 / 浦东机场,起点为全上海任意地区的,可享受 50/100 元一口价,春节后,起 / 终点倒置,为回程的乘客服务;
  • 策略 2:当某种车型不够用时,只有下机场单或者特定的好用户时可以看到;
  • 策略 3:高峰期时,高级车型可以向下接单,但司机收入不变,给抢单积极的司机更好的订单;
  • 希望在上海内环以内做一口价活动,20 元一口价,随便打车,但司机价格会根据活动情况分等级调整;
  • 策略 4:好的预约订单给抢单积极的司机,好的即时订单给近的司机;
  • 策略 5:多加一个专车产品,带有婴儿椅的车子,女性乘客可以打到;
  • 策略 6:打一个专车,如果时间超过 2 个小时,希望变成包车服务,但价格要有给乘客优惠;
  • 策略 7:我想让某个起点的乘客享受费用折扣,甚至免单,但平台按正常价格给司机计费;
  • 策略 8:每开一个城市,我想对机场、火车站的订单实行一口价策略;
  • 策略 9:在某些城市,有一部分司机是合作司机,一部分加盟司机,两者计费规则完全不同,需要满足;

基本上,这样的策略每个月都有,全国几十个城市,每个城市可能还不同,如果需要通过开发来满足这样的需求,那么几百人的开发团队都不够用,运营时间上也等不了。所以,如何设计一个高可用,灵活多变的系统来适应业务的需求,这是一个非常大的挑战。

5、技术挑战:剩下还有就是一些技术上的挑战,比如快速搭建一套分布式服务框架,如何快速找到周边的司机、如何通过道路拟合比较准确的计算道路距离、长连接的 QoS 如何保证、司乘两端心跳上报异常如何处理、如何防止心跳风暴、规则引擎的性能优化、发单 / 抢单处理队列的守护机制等。

如何解决这几个难题呢?

先说开发资源吧,开发资源属于硬伤,创业公司前期招人,招到好的人比较难。业务等不了,有句话说的好“有条件上,没有条件创造条件也要上”,这就是当时的情况,人就这么多了,边做边招吧,后面两个多月我们陆陆续续招了六七个开发人员,但新招聘的大部分经验还比较浅,但也基本上顶过去了。

再说到公共模块,当我入职一周左右的时候我就知道系统必须大规模重构,但当时因为种种因素提重构必然会给业务、团队造成比较大的影响,也会影响刚刚合并的团队信心,所以前期更多是花精力在整合团队和拖着专车系统往前走。

公共模块的代码都是在出租车业务系统,向原来的开发人员了解细节时,被告知许多历史遗留问题已不可追遡,只知道不要轻易去动,一动就崩。于是,重构计划开始后,我挑了一个对原出租车业务比较了解的哥们,拉着他两个人慢慢翻 PHP 代码,翻数据库表,通读一遍,才开始抽象公共模块及进行数据库设计。

其次,说到专车系统灵活多变的设计,我首先把专车业务的预估、选择车型、发单、抢单、撮合、做单、计费、通知等流程环节做了抽象,并固化,把可变的部分剥离。

  • 比如预估算价、显示车型、计费时将司机和乘客完全分开,实际上在业务抽象的角度来看,专车的乘客和司机发生的交易对象都不是对方,而是平台,这样就平台在运营过程中就具备非常灵活主导权;

  • 比如消息通知模块做了抽象,把不同阶段消息体抽象成模板,模板中带有变量,举个最简单的例子:如参加某个活动下单的用户和普通下单用户,在下单或计费时收到的短信内容不同,但实际只是短信模板不同,中间的价格用变量替换,有的甚至不发短信;

  • 比如某些特定场景,第一轮发单不希望发给某类司机,要第二、三轮才发给他,撮合成单时也根据不同维度的指标进行排序定义;

  • 比如将优惠券可用在不同业务场景定义成模板,再模板上增加 Scope,Scope 又反作用到产品上面;

  • 比如,对专车运营中最经常发生变化的预估、可见车型、发单、抢单、撮合逻辑,通过将乘客和司机的特征指标抽象,这个乘客、司机、订单三个纬度的特征指标抽象很关键,在后期和大数据结合,也可以将乘客司机的画像指标引入,再利用规则引擎来配置每个环节的变化,见下图:

    在将以上所有这些灵活配置的内容之上,又定义了大小产品的概念,把这些灵活多变的配置参数抽象成一个个产品,每个产品维护这些配置的参数或规则,从而达到运营策略和运行系统的隔离,实现了一套灵活的专车业务系统。

这些产品对应给乘客看到的其实是一个个车型,但看起来同样是经济型的车,在后台根据不同的条件已经被抽象配置成不同的定义规则,如机场订单的经济型和非机场的经济型就完全是不同的业务规则,无论从预估的价格、发单、抢单、撮合、通知等都完全不同。

这样的设计在重构上线后,业务系统大框架在两年时间基本没有动过,最多是增加为一些新的指标或者函数进行开发,但不会影响主流程,业务系统的架构非常稳定。

市场部门或是业务部门要上线一个新的运营策略,比如一号专车在 2015 年和 Uber 打战的时候,上线一号快车,在研发部门实际只用了两天就已经配置测试完毕,为了配合运营的工作,才拖了一周才上线。

限于篇幅因素,技术细节这里就不再多说,给大家看一个最小片段的机场单的产品命中规则

( 单 v 城市 ==1 ) && ( 函 v 电子围栏 (单 v 目的地, 上海浦东机场) ) && ( 单 v 渠道 ==0 || 单 v 渠道 ==1 || 单 v 渠道 ==201 ) && ( 单 v 类型 ==2 )&&( 单 v 入口 == 0 )&& !((单 v 用车时长 >=1)&&(客 v 版本号 >=4))&&(单 v 回调码 ==0)

题外话:在一次偶然的机会,和行业内的各家专车系统对标时,发现一号专车这种系统设计和 Uber 的设计思路非常类似,所以 Uber 才可以让各城市经理在不同城市开通不同车型做各种各样的活动,Uber 系统应该是经历了数年演化,而一号系统重构头尾只花了 2 个多月,实际上一号的指标维度非常多,有些甚至用自定义函数来组合使用一个指标,因为国内的运营策略变化实在太快太多了。殊途同归吧。

最后再说到时间、时间…. 时间啊!上面提的许多技术问题,如果从时间的维度上考虑,根本就不是问题,什么 GPS 距离计算算法不准、去噪及道路拟合算法不够优、流控还没有做、长连接服务质量不好、SQL 慢查优化,给我们时间,统统都不是问题。重构计划是 4 月 9 号开始, 我们在阅读旧有代码、梳理业务、设计新的数据库结构、搭建团队、搭 API 接口层框架、搭分布式服务架构(Thrift + ZK + DHF SRV Framework + Chukwa[实际没用起来])的过程中,很快就到了 5 月 1 号。

劳动节后,第一波炸弹来袭,听说其他几家打车应用也在做专车,天下武功,唯快不破,我们必须最先上线,于是计划调整改到 7.15 上线,下了死命令,好吧,干吧,需求不能变,时间变了! 临近 5 月中旬,新的需求来了,要求我们直接和快的打车端对接,至少要在重构上线后两周内也上,没有办法,在打车领域竞争的激烈程度超出所有的想象,业务发展的速度都是按天算的。

于是我们把上线时间又提前到 6.15,并计划 6.30 上线快的 APP 端的一号专车,时间,还是时间,需要提前梳理对接流程、接口定义及开发,人呢?时间呢?好吧,继续干吧!没有抱怨,也不谈梦想、更没有什么改造世界的想法,仅仅是一份信任、一个承诺,整个重构团队日夜加班,从 4 月 9 号计划启动,到 6 月 18 号上线,连续 70 天没有休息一天,前后端的重构团队都是全公司来得最早走得最晚的人,终于还是让系统上了线。PS:苦过笑过,留下的都是许多欢乐回忆,当值得书写留念。

上线前一天

上线前一天,虽然已经预演过两次,但大家心里都没有底,因为专车业务量刚刚起来,系统如果真的出问题,将会给对手们一个绝佳的机会。内部在讨论的时候,问的最多的一个问题是如果系统挂了,我们有什么预案,做了两套,一套是切回老系统,但会出现新旧数据不一致的问题,后续补数据非常麻烦;再一套是需要运营的兄弟们支持,系统只记录下单信息,然后出后台报表,由运营同学手工派单,再打电话通知乘客和司机接送,回到原始社会,这就是现实。

通宵不眠,迁移当天增量数据、服务上线、回归验证、强制升级,深更半夜,运营同事们也开着车在路上晃荡着帮忙路测,悦耳的新订单铃声,成单播报不停响起,终于熬过去了。

系统上线:快乐并痛着

系统刚上线,基本的业务流程虽然没有出什么大问题,但随着订单量的迅猛增长,迅速开城,业务变化,各种状况层出不穷:

  • 长连接 QoS 没有做好,订单撮合成功,但司机或乘客却没有收到推送通知;
  • 司机行驶距离根据 GPS+WIFI+ 基站三种制式的 GPS 坐标值,去噪算法做得不够好,计算出来的距离差异巨大;
  • 定位不准,司机有意或无意没有开 GPS、网络,导致发单距离太远;
  • 订单量上来,索引不够优化,慢查 SQL 层出不穷,数据库 CPU 百分百;
  • 当时上的是阿里云,阿里云的数据库专家在监控应用的时候,曾经给过一份数据库的诊断报告,非常客观的将我们数据库的问题类比成某宝 08、09 年的状态,惭愧;
  • 代码没有 Review,小分支的逻辑测试不到位,出现死循环,拖垮系统;
  • 当日订单超过 10W 的时候,司机做单时上报的心跳对后台存储(MongoDB、数据库)压力过大;
  • 因时间问题,日志系统没有上线,在跨服务的应用中,无法实时监控各服务运行异常并及时告警,为此付出很大代价;
  • Redis 在日订单过百万后,也扛不住压力了;

一方面前方捷报不断,另一方面后方销烟弥漫,快乐并痛着,不停的发布新版本,修复 BUG,优化系统,出现过好几次系统大规模宕机,大部分都是因为各种因素(不仅限于慢查)导致数据库不堪重负引起连锁反应,在订单过百万之后更是连续一周的时间,在每天的晚下班高峰期系统负载扛不住,当然后来在前后端团队通力合作下,都顺利优化顶过去了,大致回想一下,挑一些简单的列一下:

  • 优化道路距离优化算法;PS:高德地图的兄弟给了许多帮助;
  • 所有道路距离计算只取 GPS,基站及 WIFI 获取的点不做为道路计算使用,但听单可以使用 WIFI 的 GPS 点;
  • 优化寻找周边司机算法;
  • 提升长连接的通讯服务质量,在移动环境下网络不稳,需要双向确认及心跳包客户端打包机制;
  • 服务继续拆分;
  • 数据库分库、分表、一主多从、读写分离;
  • 多级缓存,优化缓存的使用,数据库只做存储,如 Redis Sharding 分 Memory 和 Persistence 两类等;
  • 设计了两层的限流熔断方案、服务降级策略等;
  • 旧的 SQL 全量 Review,新 SQL 必须 DBA 确认后方可上线;
  • APP 端也优化了访问策略;
  • 加上日志监控系统,监控系统整体运行状况;Ps:感谢快的兄弟们的支持;
  • 增加服务器,这一点我们做得不错,使用了不到一百台的 4 核 *2.8G CPU,16G 内存的服务节点,就挺过了数百万单的业务,且每个服务结点的资源消耗都在个位数;

还有很多细节已经回忆不起来,欢迎大家后续多交流。

一号专车的重构其实是重写,在业务不停往前奔跑的过程中,重写是下策,风险很高,要慎而又慎,好在当时的订单量还不大。大部分时候,系统重构应该尽量要在充分了解业务的基础上,采用分而治之,分阶段进步的方式来,开着飞机换引擎还好,但我见过开着飞机换飞机的重构计划,着实为对方捏一把冷汗,不知道最后结果如何了?当然,如果决定要动手,那还是越早做越好了。

后序

以上行文仅做为系统重构的技术回顾,重构过程艰难而痛苦,它不仅限于技术层面的难度。此后的过程中系统挺过了一轮又一轮浪峰的冲击,也逐渐趋于稳定,基本上算是完成了组织交给我的任务。

2015 年底,Joe 开始了他的新项目——四叶草车险,开始了另外一次从 0 到 1 的挑战之旅,他再次邀请了我,我于 2015 年 12 月 31 日离开滴滴快的,加入四叶草车险平台参与互联网保险的创业项目。

这一次挑战更大,保险业在中国是一个万亿级的市场。据了解,国内的比较大的传统保险公司,一家公司往往都有三、四百个系统在支撑业务运转。保险未来的变化极其复杂多样,我们才刚刚开始,未来还要迎接诸多挑战,在这个过程中,我们需要更多的人才加入,来和我们一起体验新的重构之痛(le)。说句老套的话,我们可以提供业界有竞争力的薪资以及和团队一起战斗成长的经验。

作者介绍

陈美珍(Frank),微信号 zhaocaimaolin,12 年的软件研发以及技术管理经验。擅长互联网的高并发、高可用的分布式系统架构设计,组建并带领团队完成项目的订单从零到数百万量级的突破。对大中型复杂系统的需求分析、抽象、架构设计、拆分、服务化设计及整合也比较擅长,有多年证券、电信等传统业务系统实战经验。


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们。

2016-08-23 17:134427

评论

发布
暂无评论
发现更多内容

GNURadio报错Unable to create context(windows10环境)

allu

问题总结

Python 绑定:从 Python 调用 C 或 C++

华为云开发者联盟

c c++ Python 函数 Python 绑定

网安行业这几个熟悉又陌生的名词,啥帽子都清楚啦?

郑州埃文科技

使用tar 命令进行文件的归档和压缩

学神来啦

云计算 Linux 运维 linux运维

什么?C语言也能try...catch!

实力程序员

吹水、面试、进阶齐飞!Github霸榜的阿里分布式设计实录也太香了

Java架构师迁哥

不愧是阿里内部“SpringCloudAlibaba学习笔记”看完直接斩获12家offer

Java 编程 架构 面试 微服务

Go 学习笔记之 数组

架构精进之路

Go 语言 7月日更

DataWorks赋能企业一站式数据开发治理能力

阿里云大数据AI技术

4轮技术面+1轮HR面,成功拿到腾讯40k*16的Offer ,详解面试流程和真题解析

Java 程序员 架构 面试

一位年薪 180 万的蚂蚁金服大佬扔给我的笔记,建议看完

Java架构师迁哥

我还是没有忍住,于是乎我开通了lua语言学习专栏!

李阿柯

lua 专栏

腾讯二面:Linux操作系统里一个进程最多可以创建多少个线程?

白亦杨

底层技术支撑智慧出行,汽车智能化发展下区块链大放异彩

旺链科技

区块链产业

RTC为何这么火?

anyRTC开发者

音视频 WebRTC RTC 实时通讯

【工作感悟】Android大厂高级面试题灵魂100问

欢喜学安卓

android 程序员 面试 移动开发

永续合约交易所开发,虚拟币合约交易系统源码

华为云薛浩:媒体业务进入全面云化时代,云原生成为必然选择

华为云开发者联盟

云原生 媒体 音视频 华为云

我删库跑路失败了

程序员鱼皮

Java c++ Python Linux 服务器

【工作感悟】2021最值得加入的互联网公司有哪些

欢喜学安卓

android 程序员 面试 移动开发

金九银十面试必备,“全新”突击真题宝典,阿里腾讯字节都稳了

Java 编程 程序员 架构 面试

银行业智能运维的探索与实践

云智慧AIOps社区

银行数字化转型 智能运维

教你给场景添加天空盒,超简单!

ThingJS数字孪生引擎

大数据 大前端 开发 可视化 数字孪生

智邦国际ERP系统31.99版本发布,解锁精准高效协同管理模式!

叶落便知秋

前端性能优化实践 | 百度APP个人主页优化

百度开发者中心

大前端 百度app

免费分享JDBC与MyBatis的优秀图书

Java入门到架构

Java

在数据库中如何查询表的创建时间?

华为云开发者联盟

数据库 日志 视图 GaussDB(DWS) 查找对象

统一缓存帝国 - 实战 Spring Cache

悟空聊架构

缓存 passjava 悟空聊架构 7月日更 Spring Cache

HashMap从入门到精通,原创好文,值得收藏!

wljslmz

Java hashmap java8 HashMap底层原理

KDD CUP 2021首届图神经网络大赛放榜,百度飞桨PGL获得2金1银

百度大脑

神经网络 百度

GitHub星标70K阿里大佬手写的Spring Boot实战手册

Java架构师迁哥

50天10万行代码,一号专车系统重构细节回顾_语言 & 开发_陈美珍_InfoQ精选文章