以互联网思维做好客户端软件

2023-11-01

加入爱奇艺的时间不长,但我感受到的震撼却不小。在外企打拼了十几个春秋,今年终于有机会进入一家国内顶尖的互联网企业,真真切切地有一番不太一样的体验。

不过,我今天并不想说在外企工作与国内企业的差别。目前,我负责“爱奇艺PPS影音”PC客户端软件的研发。也许有人会有疑问:怎么还在做PC软件?大家不都一窝蜂似的转去做移动开发了吗?然而,大家要明白的是,虽然PC行业已经风光不再,但PC饱有的体量仍然是巨大的,并且PC自有其不可替代的价值;PC软件还要继续做,今天我想说一说的是,怎样以互联网思维来做好客户端软件。

说起互联网,大家自然便会想起网站。(顺便提一下,爱奇艺就是以网站起家的;现如今,爱奇艺的服务已经覆盖包括PC、MAC、手机、平板、电视、机顶盒等各种终端。)想必大家也知道网站与客户端软件各有优劣吧,比如:网站可以运行在任何设备的浏览器上,不需要用户安装,也不麻烦用户升级,能在各个终端保持统一的用户体验;而相比之下,原生的客户端软件运行得更快,并且能够充分利用本地资源为用户带来更加强劲、炫目的功能。(推荐阅读Jeff Atwood的一篇博文:App会取代网站吗?)我们的客户端软件是用C++写的,性能自然不必多说。而我们公司的互联网基因,也促使我们把网站的众多优点融合进了客户端软件。

先说说研发流程吧。互联网行业最大的特点就是变化快。我们求新,必须快速迭代,快速试错。网站采用的是这种开发模式,我们的客户端软件开发也可以。我们采用了Scrum敏捷开发流程——两周一次迭代,每两周发布一个版本。我们称之为“小步快跑”——把大功能拆小,分阶段实现,追求微创新。比较一下传统的软件开发模式:先制定一份详尽冗长的PRD,然后是动辄1~3个月(甚至半年)的开发周期,再加上一个较长的稳定期来修复足够多的bug,等到发布产品的时候,市场环境早就不一样了……互联网环境容不得如此慢的节奏!


上面说到了快速试错。那么,怎么试呢?又怎么知道我们是对还是错呢?这就要依赖数据啦!网站有它的先天优势,可以很方便地收集到这些数据:用户在网站上停留了多久,点了什么网页,在网页上点了什么按钮,用户使用的是什么浏览器,同时有多少人在线,访问的峰值出现在什么时间段,等等。我们在客户端里也加入了类似的投递代码。我们还有强大的数据统计和分析团队的支持,让我们对客户端软件性能以及用户行为了如指掌。我们很容易就能知道客户端软件的启动耗时、崩溃率、用户在我们客户端里看了哪些视频、播放是不是有卡顿等信息。在我们尝试做了一个新功能、但又不确定用户是否会喜欢的时候,我们也可以通过一个小渠道发布这个版本,然后在后台观察各种统计数据,以此来帮助我们决定是否应该继续开发这个功能,或者在后续迭代里需要在哪些方面做改进。

我们每两周对外发布一个版本。我们也深知,发出去的版本就像泼出去的水,也是我们未来必须背负的包袱。时间一长,客户端版本碎片化,几千万用户手上的版本多达几十种。我们固然可以通过软件自带的升级机制把最新版本的客户端送到用户手上,但出于种种原因,新版本能够做到高于90%的覆盖已经不错了,而这个数字绝对达不到100%。然而,网站却能做到。网站添加了新功能之后,一旦部署,顷刻之间就能被全世界的所有用户使用上。问题是,我们怎么在客户端里获得像网页那样的灵活性呢?我们的做法是,对于性能要求不高并且可能会频繁调整的部分,用HTML/JavaScript来实现,并在客户端里用内嵌浏览器打开这些网页;而对于性能要求高的部分,坚决采用我们强大的C++皮肤库来把网页本地化。一个很好的例子就是爱奇艺影视大全(http://v.iqiyi.com),在与网站保持协同的基础上,我们让它在客户端里表现出了更为卓越的性能。

在功能实现方面,我们时刻保持着一种意识:尽量不把业务逻辑在客户端里写死。否则的话,一旦业务逻辑有变,我们必须修改客户端的代码,然后再做全网升级,一来周期比较长,二来新版本也做不到100%的覆盖,结果就比较被动了。举一个VIP会员相关的例子吧。在客户端,我们有针对当前登录用户的类型来做不同会员套餐促销的需求,具体的业务逻辑是:如果当前是普通会员,则跳到白银套餐的购买页面(url1);如果当前是白银会员,则跳黄金套餐页面(url2);如果当前是黄金会员,则跳铂金套餐页面(url3)。一些经验欠缺的开发人员会把上述逻辑直接实现在客户端软件里,就像下图中左边所示的那样。遗憾的是,一旦VIP会员套餐的促销逻辑有变,比如,要改成对所有用户都推销铂金套餐,那就惨了!更灵活的实现方式应该像下图中右边那样,客户端只是调用一个相对固定的url(并带上必要的参数),而把具体的业务逻辑实现在服务器端。


当然,上面只是一个很小的例子。为了在客户端里获得足够的灵活性(不通过发布新版本就能满足业务需求),我们还给很多功能加上了云端配置。只要我们发现某些功能的用户体验不理想,随时都可以调整控制参数,甚至将其彻底关闭。我们始终牢记,我们在做的不是一个单纯、孤立的客户端软件——我们提供的是一种互联网服务。也因为如此,我们的客户端软件同时很好地支持了编辑运营(及时发布时事或专题、热门推荐、快速上线或下线节目等),以及灵活的广告策略控制。

PC软件真的没落了吗?其实不然!也许我们只是需要顺应潮流,改变一下自己的思维方式。我们相信,只要有用户存在,每个终端都是重要的。因此,即使没有聚光灯、鲜花或掌声,我们仍然在坚持不懈地努力做好产品,全心全意为我们的用户服务!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

以互联网思维做好客户端软件 的相关文章

  • python3学习之路 -- 4.9)迭代器

    1 for 变量 in 可迭代 pass 可迭代 str list tuple dic set open 可迭代的数据类型都会提供一个迭代器 这个迭代器会将数据类型中的数据逐一的拿到 2 获取迭代器的2种方案 1 iter 内置函数可以直接
  • 深入分析 (迪杰斯特拉算法) Dijkstra 算法实现原理

    迪杰斯特拉 Dijkstra 算法是典型最短路径算法 用于计算一个节点到其他节点的最短路径 它的主要特点是以起始点为中心向外层层扩展 广度优先搜索思想 直到扩展到终点为止 基本思想 通过Dijkstra计算图G中的最短路径时 需要指定起点s
  • Chrome开发者工具详解 (二)

    Chrome开发者工具详解 二 前言 一 Console面板 定位面页节点 Css选择器进行节点定位 事件监听 二 查看节点上注册的监听器 总结 前言 Console面板是与网页进行交互的控制台窗口 它用于DOM树对象信息和调试代码 掌握C

随机推荐

  • 力扣第29天----第435题、第763题、第56题

    力扣第29天 第435题 第763题 第56题 文章目录 一 第435题 无重叠区间 二 第763题 划分字母区间 三 第56题 合并区间 一 第435题 无重叠区间 跟射箭那个差不多 排序 gt 相邻比较重叠 gt 边缘合并 gt 计数
  • 内存数据库简介-内存数据库性能排行

    内存数据库性能排行 内存数据库很多人还不知道 现在让我们一起来看看吧 在网络技术和计算机技术广泛普及的今天 数据库已经成为IT领域最重要的课题之一 所谓数据库 是指一种用于存储数据的库存 可以为IT开发者访问数据提供极大的便利 目前很多管理
  • eplan怎么生成端子图表_自定义EPLAN表格模板

    缘起 使用eplan制图 一个方便之处就是它能自动生成表格 如端子图表 插头图表等 但是有时候软件自带的图表模板又不符合我们的要求 想要自己定义表格 比如系统自带的端子图表是图1样式的 我想要的是图2样式的 如何做到呢 本文就以自定义端子图
  • 根据后序或者前序 + 中序建树的多种方法!

    根据 后序or前序 中序 建树的多种方法 以下例子都是实战题 值得收藏 值的学习 1 堆的方式 完全二叉树 利用了完全二叉树的特性 根结点i的孩子结点左孩子为2i 右孩子为2i 1 注意此时i是从1开始编号 但是每棵子树的根结点没有直接给出
  • python输入一个字符、如果是大写字母、转换为小写_python语言 输入一个字母 如果它是一个小写英文字母 则把它转换为对应的大写字母输出?...

    展开全部 char1 input 请输bai入一个小写英文du字母zhi if ord char1 gt ord a and ord char1 lt ord z print char1 upper else print 不是小写字母 da
  • JNI基本使用

    编译运行 首先介绍一些编写JNI的大致流程 可以直接调过这部分 生成头文件 这步可以不做 但是JNI对C C 函数的命名有严格要求 同时函数的命名会很长 所以还是直接生成头文件 然后从头文件里边复制函数声明 使用下面的命令生成头文件 记得代
  • SourceTree提交合并流程

    先写提交流程 缓存 提交 获取 拉取 解决冲突 提交 推送 下面和多分支开发合并 先保证 拉取到最新的 把项目切到主分支 鼠标点到被合并分支 右击选中 合并 到当前分支
  • ARM9/13——用C语言实现LED1/LED2/LED3灯点亮

    目录 代码 gpio h gpio c main c 运行效果 代码 gpio h ifndef GPIO H define GPIO H 1 RCC寄存器封装 用宏定义进行封装 define RCC AHB4 ENSETR volatil
  • 【Unity3D自学记录】Unity3D之KeyCode键值

    Backspace 退格键 Delete Delete键 TabTab键 Clear Clear键 Return 回车键 Pause 暂停键 Escape ESC键 Space 空格键 Keypad0 小键盘0 Keypad1 小键盘1 K
  • 为什么要在C ++ 11中使用“override”说明符?

    如果您知道Java 那么您可能已经很熟悉Java了 这对您来说可能是完全简单的 Override annotation 如果您一直使用C C 进行编码 那么这可能是新的 您可能会问自己一个问题 为什么在不必要的时候为什么要放一个额外的说明符
  • 数独基本规则_数独入门:你必须掌握的那些规则和技巧

    很多人想涉足数独领域 但苦于不知该如何入门和上手 甭愁了 北京市数独运动协会贴心地为菜鸟们总结了这一篇数独的元素 规则和技巧 满满的都是干货 如果你看完还觉得不够过瘾 那就移步至数独女王的达人攻略 接受高阶的训练和挑战吧 数独的规则 在空格
  • 获取OpenHarmony源码:从DevEco Marketplace获取(2)

    引言 OpenHarmony源码的获取方式有三种 从gitee GitHub等基于git的代码托管平台获取 从华为的DevEco Marketplace网站获取 从镜像站点获取 本文介绍如何在Ubuntu版本的DevEco Device T
  • 大数据知识目录

    第一阶段 安装虚拟机 第二阶段 Linux操作系统 第三阶段 zookeeper分布式协调服务框架 第四阶段 Hadoop分布式文件系统HDFS 第五阶段 Hadoop分布式计算Mapreduce和资源管理 第六阶段 数据仓库Hive 第七
  • 对于uts namespace共享的测试

    前言 单单以下列命令运行虽然是root 还不行 我们需要加 privileged 不然会报 hostname you must be root to change the host name docker run it uts host u
  • python写程序计算无穷级数_圆周率 π 展开 为 无穷级数

    圆周率 展开 为 无穷级数 其实 很简单 如图 可以用 黄色小三角形 和 橙色小三角形 以及 依此类推 下去 的 无数个 小三角形 来 逼近 圆面积 把 这个 无限逼近 的 圆面积 称为 S 因为 圆面积 r 所以 有 S r S r 即
  • 【VC++类型转换】CString和System::String类型的转换

    1 CString 转换为System String类型 这里的CString是指MFC的CString System String为CLR中的字符串类 我认为最简单的做法是 CString text System String str1
  • 【HBZ分享】Mysql的InnoDB原理

    没有配置主键时Mysql的InnoDB是如何做的 Mysql会使用自带的rowid作为主键 InnoDB的底层数据结构是什么 B Tree BTree的特点 MyISAM 非聚集索引 即 索引 和 对应数据 是分开的两个文件 找到对应数据后
  • 两年来主要工作框架图

    两年来主要工作框架图 包含了从MES到SAP的全程流程 从收集一线数据开始到汇总历史数据 归档 直到最后的BI DW分析展现 主要工作流程图
  • Java中正则表达式的使用

    在Java中 我们为了查找某个给定字符串中是否有需要查找的某个字符或者子字串 或者对字符串进行分割 或者对字符串一些字符进行替换 删除 一般会通过if else for 的配合使用来实现这些功能 如下所示 Java代码 public cla
  • 以互联网思维做好客户端软件

    加入爱奇艺的时间不长 但我感受到的震撼却不小 在外企打拼了十几个春秋 今年终于有机会进入一家国内顶尖的互联网企业 真真切切地有一番不太一样的体验 不过 我今天并不想说在外企工作与国内企业的差别 目前 我负责 爱奇艺PPS影音 PC客户端软件