写点什么

苏宁流量数据采集体系的演变

2018 年 11 月 02 日

苏宁流量数据采集体系的演变

1. 前言

在当今这个互联网时代,人们在网上进行工作、消费、娱乐、社交等行为所花费的时间越来越长,在互联网中、每时每刻都会产生海量的用户行为数据。对各大互联网公司而言,便捷、准确、全面地采集用户行为数据,并用以支撑经营分析、改善用户体验,已经日趋重要。

近年来,苏宁业务规模高速增长,已覆盖了零售、金融、文创、体育、物流等多个业态,在 2017 年大促期间、仅苏宁易购业务便是实现了销售额 7 秒破亿的记录。在数据经营的战略下,苏宁大数据中心数据采集团队正逐步建立标准、通用的的海量用户行为采集方案,服务于多业态、多业务场景,并致力为苏宁大数据体系打下坚实的数据基础。

本文主要介绍苏宁用户行为采集体系的发展历程,同时分享苏宁在日志采集上的部分经验和探索过程。

2. 早期的行为日志采集方案介绍

2.1. 基于苏宁易购业务的日志采集方案

与各大电商网站类似,苏宁的用户行为采集体系是在苏宁易购 PC 版的基础上发展起来的。

早期,我们提供了基于 PC 浏览器页面的用户行为采集方案,为苏宁易购网站采集页面浏览、点击事件等基本日志,支撑基础的网站分析(如网站来源分析、页面访问量分析、站内页面来源去向分析、站内访问路径分析、页面元素点击量分析等)。

随着网站业务场景的日趋完善和网站分析的逐步细化,我们与分析人员共同定义了诸如曝光、搜索、注册、购买等各种类型的页面事件日志,以满足各类特定场景下的数据分析需求。

在移动互联网高速发展和智能手机广泛普及的背景下,我们也提供了面向手机浏览器页面和手机 App 的用户行为采集方案。手机 App 的日志采集沿用了浏览器页面的日志分类模式,即基础的页面浏览日志和各种类型的页面事件日志,并新增了其特有的 App 启动日志。至此,苏宁用户行为采集体系初具雏形,但仍主要面向苏宁易购业务。

2.2. 日志采集的实现方案简介

2.2.1. 浏览器页面日志采集

与业界的网页日志采集方案相同,苏宁的浏览器网页日志采集工作是由开发人员植入页面 html 文档中的一段 JS 脚本完成的,在文中,我们将这个 JS 脚本称为“采集 JS”。

页面浏览日志,采集 JS 会自动在普通页面(与单页面进行区分)加载完成时触发该日志的参数采集和日志上报,即仅需将采集 JS 正常植入页面 html 文档即可,无需额外的人工干预。页面浏览日志是计算页面 PV、UV、跳出率、转化率等一系列指标的基础,是网站分析中最为重要的日志。考虑到页面日志采集,尤其是站外投放着陆页日志采集的准确性,我们要求页面将采集 JS 在页面头部引用,并尽可能地将其加载时序提前。同时,我们将“页面 dom 文档树加载完成”作为页面加载完成的判断节点,这在网站页面图片日益丰富的当下,是很有必要的。

对于单页面的页面浏览日志,考虑到其页面间的跳转并不会重新加载页面,即无法自动触发页面浏览日志的采集,故该场景下、需暴露特定的传参方法供页面调用、以实现手动触发页面访问日志的采集,这也是业界普遍的做法。

页面事件日志,采集 JS 暴露了多种传参方法供页面调用,在页面调用这些传参方法时会触发特定事件日志的参数采集和日志上报。考虑到页面事件类型极高的多样性,我们将页面事件划分为了通用事件和自定义事件。

通用事件包含曝光、点击、搜索、注册、购买等覆盖场景较多且日志量较大的事件类型,用以满足同类业务通用的分析需求,我们为每一类通用事件均提供了特定的传参方法(即调用点击事件的传参方法、仅会触发点击事件日志的采集和上报);而自定义事件则支持业务方根据具体的业务场景自行定义(我们提供了自定义事件的管理后台,供业务人员注册事件名称和需要采集的参数等信息),以满足个性化的分析需求,我们为自定义事件提供了统一的传参方法,调用该方法时须传入“事件类型”这一参数,用以区分不同的自定义事件。

上述的各类事件传参方法,须在用户触发对应的交互行为时调用。因此,我们要求页面前端开发人员将调用事件传参方法的采集代码植入目标页面、并与对应的交互行为进行绑定,这便是俗称的“埋点”。

日志字段,无论是页面浏览日志还是页面事件日志,我们均定义了标准的日志格式,主要包含采集时间、访客 & 会员信息、浏览器信息、页面参数和事件参数,这些字段信息主要来源于浏览器 cookie、页面全局变量和页面传参,而对于页面浏览日志和页面事件日志,也仅有事件参数相关字段存在差异,其余部分均相同。标准的日志格式,对于后续的 ETL 工作,将提供极大的便利,这也是我们所提倡的。

2.2.2. 手机 App 日志采集

对于手机 App 的日志采集,行业中主要有两种方案,即“App 自行采集参数、拼接日志、完成上报”和“App 集成特定的采集 SDK,由采集 SDK 来完成日志的采集和上报”。苏宁采用的是第二种更加普遍的方案,同时提供了 Android 和 IOS 两版 SDK 供各 App 集成,各 App 需在启动时完成采集 SDK 的初始化。

如上文所述,我们将手机 App 的日志分为启动日志、页面浏览日志、页面事件日志三类。同时,我们也对手机 App 端定义了标准的日志格式,主要包含采集时间、访客 & 会员信息、设备信息、页面参数和事件参数,这些字段信息主要来源于 SDK 主动获取或接口传参。与浏览器页面日志类似,手机 App 端的三大类日志,仅有页面参数和事件参数存在差异,其余部分均相同。

启动日志,采集 SDK 自动根据 App 的生命周期来判断 App 的启动和退出,无需人工干预。单独采集启动日志可以更准确地计算用户的启动时长,为分析人员提供准确的数据支持。

页面浏览日志,目前手机 App 采集页面浏览日志主要通过客户端调用接口来实现,而业界也主要有两种方案,即“页面进入时调用接口,发送日志”和“页面进入和页面离开时均调用接口,在页面离开时发送日志”。苏宁采用的是第二种方案,即页面进入和页面离开接口须成对调用,并支持在页面离开接口中传入需要额外采集的页面参数(如商品编码、搜索关键词、活动 ID 等)。该方案能够极大地提升计算页面停留时长的准确性和便捷性。

页面事件日志,与浏览器采集 JS 类似,采集 SDK 提供了多种传参接口供 App 调用,在调用这些传参接口时会触发特定事件日志的参数采集和日志上报。在手机 App 端,我们同样将页面事件划分为了通用事件和自定义事件,其划分方式和事件的管理方式与浏览器端完全一致。

2.2.3. 日志上报策略

移动客户端(iOS/Android)采集 SDK 原有的采集日志上报方案是,客户端初始化采集 SDK 时会设置统一的上报时间间隔。在设置的时间间隔内,SDK 采集到的用户行为日志都会暂存在客户端缓存内,到了上报时间点,采集 SDK 会将缓存内的所有类型日志进行合并、并上报到服务端统一的日志接收接口。大促期间,当流量峰值到达预警阀值的时,只能采用比较粗暴的降级方案。

采集方案设计之初,基于当时的业务场景,将移动端的日志类型分为启动日志、访问日志、注册日志、搜索日志、订单日志和自定义日志。随着近几年业务发展和变化,归类到自定义类型的日志越来越多,日志量也越来庞大(尤其是曝光日志),尤其在大促期间日志量陡增十几倍的情况下,就会导致了下游处理自定义日志时需要消耗越来越多的资源和时间,导致数据延迟也越来越大,对下游的数据产品造成很大影响。

2.3. 小结

本部分简单介绍了早期苏宁用户行为采集方案的设计思路和实现方案。而在业务范围不断扩张、前端 & 客户端技术不断更新、业务场景不断丰富的过程中,原有方案也暴露出了诸多问题,如“Hybrid 应用中 H5 和 Native 日志打通”、“手动埋点工作量过于繁重”等等。在下一部分中,我们将着重介绍近两年苏宁用户行为日志采集方案演进过程中的经验。

3. 苏宁用户行为日志采集方案的演进和探索

3.1. 更多业态 & 更多终端

更多业态,早期的用户行为采集主要面向苏宁易购单一业务,在数据采集的实践过程中,页面事件日志类型的划分均基于电商业务,例如购买事件日志、商品加入购物车日志、商品库存日志等等;页面浏览日志、页面事件日志中涉及的埋点内容及其规范,也都是基于电商业务制定的。

随着近年来苏宁业务近年来的极速增长,苏宁用户行为采集方案逐步覆盖了苏宁金融、PP 视频、PP 体育、龙珠直播、苏宁拼购、苏宁小店、苏宁推客、红孩子母婴等数十个网站和 App,这对于埋点规范的制定是一个不小的挑战。视频直播类业务,会重点关注用户播放视频的行为;O2O 类业务,会重点关注用户的定位信息;金融类业务,会重点关注用户的开户、查询基金理财产品等行为。

而随着业务场景的不断丰富,不同类型的业务场景也在进行着融合,例如电商 App 中逐步融入了视频直播功能、游戏功能。在此背景下,制定一个可拓展的埋点规范显得尤为重要,特别是对于业务类型高速扩张的互联网公司。

在分析电商类的用户行为数据时,往往会关注商品编码、店铺编码、订单编码等信息,并在埋点时将多个常用参数按照固定的规则拼接为一个字符串。这种方案在业务类型相对固定时,有着规则清晰、报文简洁等优势,但在业务类型越来越多、需要采集的业务参数也越来越多时,就会显得力不从心。因此,在做页面参数、事件参数埋点时,我们制定了 kv 键值对(key=value)格式的埋点规范,该方案扩展性强,可根据具体业务定义个性化的参数 key、根据实际需求增减埋点中 kv 键值对的数量。kv 键值对在日志中的存在形式,可以是常规的 json 格式、也可以是带分隔符的字符串形式。

更多终端,早期的用户行为采集方案仅面向浏览器页面和手机 App,随着业务的发展,我们也逐步上线了面向 PC 桌面客户端,面向各种小程序(微信、百度等),面向智能电视 App,面向智能硬件的用户行为采集方案。我们将 PC 桌面客户端、小程序、智能电视 App、智能硬件视为不同的终端。目前这些终端的用户行为采集方案均与手机 App 相仿,均提供专用的 JS 或 SDK 采集用户行为数据,JS 和 SDK 中均暴露了多样化的传参接口,供业务方调用、触发特定日志的采集和上报。

3.2. H5 与 native 日志打通

采集更多业态和终端的数据,可以帮助数据分析人员更好的理解用户行为、勾勒出完整的苏宁用户画像,其好处显而易见、但是也带来了诸多挑战,例如 H5 与 native 的日志打通。

Hybrid App 是目前主流的手机 App 类型,其中既有 native 页面、也有内嵌的 H5 页面。按照早期的采集方案,native 页面上的页面浏览日志、页面事件日志均由采集 SDK 采集和上报,而内嵌 H5 页面是在 App 的内置浏览器中打开的、故 H5 页面的日志均由采集 JS 采集和上报。由于采集方案不同,上报日志的格式、字段内容和接收服务器都是不同的,这对后续分析用户在 App 中完整的访问路径带来了诸多不便。

目前行业中有两种主流方案来解决 native 页面和内嵌 H5 页面日志隔离的问题。

方案 1,native 页面和 App 内嵌 H5 页面采用不同的采集方案,虽然可以正常的计算各个页面的 PV、UV、点击量等基本指标,但在还原用户在 App 中的完整行为时,会存在问题。故而可以利用浏览器 cookie 来存放一些标识字段,这种标识字段可以是用户的身份标识、也可以是设备唯一 ID 等可以准确匹配 native 页面日志的信息,App 的开发人员可以很容易地将这些信息写入内置浏览器的 cookie 中。在 JS 采集内嵌 H5 页面的各种日志时,只需要获取 cookie 中的特定标识并拼入日志字段,在后续处理数据时,即可通过上述特定标识将内嵌 H5 页面的日志与 native 页面的对应日志做关联,继而解决数据隔离的问题。

方案 2,上述方案具有便捷的特性,但后续的计算成本较高,且往往会出现 H5 页面的来源页丢失的问题。故而苏宁用户采集使用的方案如下

  1. H5 页面加载采集 JS 后,由采集 JS 判断 H5 页面的运行环境是手机浏览器还是特定 App,这里可以根据浏览器的 ua 或 navigator 中的特定标识进行判断,这个标识可以由 App 写入、也可以由采集 SDK 写入;

  2. 若 H5 页面是在手机浏览器中打开的,则 JS 采集日志所需字段信息并直接向服务端上报发送页面日志;

  3. 若 H5 页面是在特定 App 中打开的,则 JS 采集日志所需字段信息、并调用与采集 SDK 约定并由 SDK 提供的接口,将字段信息通过接口传给采集 SDK,这里需通过移动混合开发中常用的 JsBridge 来实现 JS 与 App 的信息互通;

  4. 采集 SDK 获取到采集 JS 传入的字段信息,识别日志类型、并将字段信息解析 & 拼接为对应的 App 日志格式,而后通过调用 SDK 内部的接口实现日志的上报。

该方案可以实现 SDK 上报内嵌 H5 页面的所有日志,较好地解决了 H5 与 native 日志打通时会遇到的诸多问题。同时,为了后续分析的便利,我们也建议为 App 与浏览器页面相关日志中的页面参数、业务参数制定标准、统一的埋点规范。

H5 与 native 日志打通的问题,其实不光在 Hybrid App 中出现,在各类小程序、PC 桌面客户端中均会遇到同样的问题,而其解决方案其实与 Hybrid App 中所使用的方案是基本相同的。目前苏宁内部各 App 均使用了相同的用户行为采集方案,在实现 H5 与 native 日志打通时,几乎所有的工作均由数据采集团队完成,无需前端、客户端开发人员介入。同时,日志格式的打通,也极大地节约了后续的计算资源。

3.3. 埋点无痕化

在用户行为采集的长期实践过程中,常常会遇到一个显著的问题。埋点,尤其是页面点击事件 & 元素曝光事件相关的埋点,需要开发人员将监测代码加在每一个监测点上,还需要保证这些代码跟监测点一一对应,这是一个庞大而繁琐的工作,且很容易出现错误或是遗漏。因此,业界一直有着埋点无痕化的诉求,常见的概念有“无埋点、全埋点、可视化埋点”,而苏宁用户行为采集团队在埋点无痕化上也尝试了诸多探索、积累了许多经验,目前我们将最终使用的方案称为全埋点方案。

点击事件无痕采集,页面元素的点击事件埋点,一直是无痕埋点实践中的重点。在开发人员为页面点击事件做手动埋点时,写入的埋点内容核心是每一个页面交互元素的 ID,这个 ID 可以是一串数字、也可以是具有字面意义的一个字符串,每一个元素的 ID 在当前页面中全局唯一,同时需要在配置后台为每一个元素 ID 命名。无痕埋点的核心思想就是页面交互元素的 ID 无痕化,无需开发人员手动写入(省去了人工码代码的步骤,也极大地减少了出错的可能),同时又可保证唯一。

页面交互元素的唯一 ID,这在浏览器网页和手机 App 中都很容易找到,譬如 html 文档中每一个 dom 元素的 xpath 或 css 选择器、又如 App 原生控件的控件路径,我们统一称之为元素路径。采集 JS 和采集 SDK 自动监听到页面中交互元素的点击事件后,获取对应的元素路径,将之拼入点击日志并上报,这就是最初版本的点击事件无痕化采集方案,事实上我们也完整地经历了这一初始阶段。关于自动监听页面交互元素的点击事件,前端或客户端开发人员习惯称其为 hook 点击事件,在网页端、Android 端、IOS 端均有对应的实现方法,在此就不再赘述。

点击事件可视化配置,根据上述方案采集到的点击日志,可以计算出每一个页面中各个元素路径对应的点击量,但事实上元素路径是几乎无法直接被数据分析人员(产品经理、运营人员或专业的数据分析人员)所理解的。故而,仅仅是点击事件无痕采集还无法体现出其价值,还需要搭配可视化配置(以及点击数据可视化展示)。我们将可视化配置的核心思想总结为所见即所得,即将采集到的元素路径还原到真实页面中去,与页面中实际存在的交互元素进行绑定,让元素路径以一个极易理解的形式呈现给数据分析人员。

实现点击事件可视化配置的方案对于浏览器网页和 App 略有差异,但都需要一个专用的可视化配置后台。

对于 html 页面,前端开发人员可以直接根据 xpath(或 css 选择器)定位到页面中的一个 dom 元素,并修改对应 dom 元素的样式、如在该元素上添加蒙层效果或修改背景颜色,这些效果都是在特定后台界面中实现的、并不会影响真实用户的体验。如下图所示,数据分析人员可以直观地了解到每一个元素路径对应到页面中的哪个位置。在此基础上,可以为元素命名、也可以将元素的点击量可视化地展示在页面中。

对于 App 中 native 页面的点击事件可视化配置,业界主要有两种方案。一种是直接在手机上对 App 进行可视化配置;另一种是将手机屏幕中的内容投射到电脑屏幕上(在专用的后台中展示),在配置后台进行可视化配置。综合考虑了用户体验和方案的通用性,我们采用了第二种方案,该方案可以极小的成本、快速支持任意 App 接入点击事件无痕采集和可视化配置。我们在实践过程中,采用了如下方式:

  1. 启动需要可视化配置点击数据的 App,通过特殊手势(扫码亦可),可以开启采集 SDK 的截屏功能;

  2. 采集 SDK 对前台运行的 App 内容进行截屏,将图片发送给服务端,同时遍历出屏幕范围内的所有控件信息,获取控件的路径、坐标、尺寸,一并发送给服务端;

  3. 配置后台从服务端获取到截屏图片和控件信息后,在界面上绘制出当前 App 的页面、并在每一个控件的位置上添加边框效果(蒙层效果亦可);

  4. 由于点击事件无痕采集方案采集了控件路径、后台界面开发人员即可将其对应的点击量数据还原到真实页面中、同时亦可实现可视化地为每一个控件路径进行命名。

在点击事件无痕采集、可视化配置的实践过程中,仍有不少需要注意的细节,例如点击元素对应的业务参数如何事件无痕采集、如何快速地为一批元素 / 控件进行命名、在出现 App 页面控件复用时如何确保控件路径的唯一性和准确性等等,在探索 & 解决这些细节问题的过程中在此就不再赘述。

与点击事件相同,我们对浏览器网页中元素曝光事件的无痕化采集方案也进行了实践,该方案实现了自动监听页面图片元素的曝光并采集相关统计信息的效果。由于曝光日志具有日志量大、并发量大的特性,在开发过程中我们将重点放在了降低性能损耗上,并取得了不错的效果。在曝光日志的内容上,我们也做到了字段信息与点击事件一致,故而在点击事件无痕采集的基础上,可以不再需要重复配置,并快速实现数据可视化展示。

3.4. 日志安全

针对日志的加密方案,我们充分考虑了对称加密和非对称加密各自的优缺点:对称加密加密与解密使用的是同样的密钥,所以速度快,但由于需要将密钥在网络传输,所以安全性不高;非对称加密使用了一对密钥,公钥与私钥,所以安全性高,但加密与解密速度慢。虽然非对称加密很安全,但是和对称加密比起来,它非常的慢,所以还是要用对称加密来传送报文,但对称加密所使用的密钥可以通过非对称加密的方式发送出去。流程如下:

(1) APP 端首先生成了一个随机数作为对称密钥。
(2) APP 端向服务端请求公钥。
(3) 服务端将带版本号的公钥发送给 APP 端。
(4) APP 端使用该版本的公钥将自己的对称密钥加密。
(5) APP 端将加密后的对称密钥(带上公钥版本号)发送给服务端。
(6) 服务端使用对应版本号的私钥解密得到 APP 端的对称密钥。
(7) APP 端与服务端可以使用对称密钥来对沟通的内容进行加密与解密了。

3.5. 日志传输

通过后台的采集管理平台给不同 App 个性化地配置上报地址和各类型日志的上报时间间隔,App 初始化采集 SDK 之后,SDK 即调用上报配置接口,后台根据请求中 appKey 返回对应 App 的配置信息,SDK 根据获取到的配置参数进行日志上报。

原有的移动客户端 SDK 日志上报只通过时间间隔这种单一策略来控制日志上报的周期,通过实践我们发现这种策略存在风险,如果用户在很短的时间里(尤其在大促期间)进行了了大量行为操作,就会导致上报时合并出来的请求体过长,从而导致上传失败。

针对这种场景,我们增加了按日志条数上报的策略,如果缓存中的日志条数达到阀值,也会触发日志上报。目前这种时间间隔 + 日志条数相结合的上报策略能够更灵活更有效地支撑线上日渐复杂的采集场景,也是业界普遍采用的方案。

原有的移动客户端所有日志类型是合并在一起上报到服务端,再由服务端根据日志类型进行分流落地,考虑到苏宁用户行为日志的规模和复杂度,我们决定把日志分流从服务端向客户端迁移,从而降低了服务端日志处理过程中的分支判断消耗,并作为后续的计算资源调配的前提,提高资源利用效率。另外,日志在移动客户端分流也为大促降级方案的优化提供了必要的条件,大促降级方案实现了从原有简单粗暴的一刀切到现有的根据日志的重要程度进行相应的延时上报和分集群上报,达到了各类型日志互不影响的目的。

4. 总结

考虑到文章篇幅问题,本文仅介绍了苏宁用户行为采集团队在制定埋点规范、H5 与 native 日志打通、埋点无痕化、日志传输与日志安全上的一些探索过程和经验,其余如跨终端、业态打通用户标识,大促期间的日志分流等实践经验,将会在后续的文章中进行分享。当然,用户行为采集方案的种种探索和提升,都是以解决用户(数据分析人员、埋点实施人员、下游数据产品)痛点、提升数据质量为出发点的,而在公司不同的发展时期,我们需要优先考虑并解决的问题也不尽相同。作为用户行为数据分析、数据应用的底层支撑部分,苏宁的用户行为采集体系也在紧跟业务发展和行业技术发展的脚步,不断更新迭代,致力于更简单、更准确、更全面的用户行为采集方案,为苏宁大数据体系打下坚实的数据基础。

作者

许夏骏,苏宁易购 IT 总部大数据中心主要负责人之一。多年大数据行业背景,数学、统计学专业毕业,主导苏宁行为数据采集产品的设计和研发。苏宁行为数据采集产品服务于苏宁全产业上百个 App、网站、小程序和其他智能硬件产品,为各条线提供完善的流量数据分析解决方案,并为各条线的数据化经营提供稳定的支撑。

2018 年 11 月 02 日 14:331358

评论 2 条评论

发布
用户头像
有h5无痕埋点方案不
2018 年 11 月 08 日 07:59
回复
没有更多了
发现更多内容

代理模式

soolaugust

设计模式 代理模式 七日更

架构师训练营第二期 Week 10 作业

bigxiang

极客大学架构师训练营

冰河是谁?到底是干嘛的?

冰河

程序员 程序人生 架构师 冰河 冰河技术

第十周总结

孤星

Code Review实践

HQ数字卡

Code Review 七日更

第十周作业

孤星

架构训练营第九周作业

一期一会

微服务 dubbo

Dubbo 微服务调用过程

梧桐

第八周-作业1

Mr_No爱学习

讲的真透彻!Android开发了解这些自然无惧面试,成功入职阿里

欢喜学安卓

android 程序员 面试 移动开发

安全架构:反垃圾与风控

积极&丧

Spring 源码学习 10:prepareBeanFactory 和 postProcessBeanFactory

程序员小航

spring 源码 源码阅读

wildfly 21中应用程序的部署

程序那些事

程序那些事 wildfly wildfly21 应用程序部署 应用程序配置

行业寒冬:程序员怎样优雅度过35岁中年危机?跳槽薪资翻倍

欢喜学安卓

android 程序员 面试 移动开发

ARROW阿罗AOW币APP系统软件开发

开發I852946OIIO

系统开发

第五章学习总结

简简单单

工具词典:数据

lidaobing

数据 28天写作

区块链的核心技术是什么?

CECBC区块链专委会

区块链

Flink比Spark好在哪?

数据社

flink spark 七日更

日本准备推行AI婚配,年轻人会为“爱情算法”买单吗?

脑极体

第 10 周作业

Steven

计算机专业必看!记录一次腾讯Android岗面试笔试总结,讲的明明白白!

欢喜学安卓

android 程序员 面试 移动开发

我家有猫

熊斌

生活方式 七日更 我家有猫

数据仓库的前世今生

数据社

数据仓库 七日更

TypeScript | 第七章:配置文件说明

梁龙先森

typescript 前端 编程语言 七日更

第八周-学习总结

Mr_No爱学习

架构师训练营第二期 Week 10 总结

bigxiang

极客大学架构师训练营

提问开启创新-激发团队创新的提问法

Alan

个人成长 创新 团队文化 七日更 28天写作

框架VS架构,看两者异同

田维常

框架

七周七并发模型

田维常

并发

第五周 技术选型作业

简简单单

飞猪Flutter技术演进及业务改造的实践与思考

飞猪Flutter技术演进及业务改造的实践与思考

苏宁流量数据采集体系的演变-InfoQ