“这些项目不是什么赚大钱的项目,但是它们足够有趣。”丨关于 Geek Online 2020 编程挑战赛,选手们如是说

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同...
继续阅读 »

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同寻找 IM 和 RTC 技术的更多落地场景,开辟更多使用途径。

本届 Geek Online 2020 编程挑战赛以《后疫情时代,通信云技术的创新及实践》为主题,也是希望借此机会鼓励开发者挖掘关于实时音视频和即时通讯技术的更多创意。通过近 2 个月的激烈角逐,在近百份参赛作品中,15 支队伍突出重围,闯入总决赛。

其中,缘拼、红鲤鱼与绿鲤鱼与驴、youwe young、萍水相逢的生活、MAXFLOAT 五组参赛团队分获了最终的奖项。

在比赛中,他们不仅夺得奖杯、获得声誉,也赢得了丰厚的奖金;而在比赛后,我们也采访了其中的三组选手,和他们聊了聊参赛前和赛后的一些“独家记忆”。



      lPc6q1vIgtC3pM40__thumbnail.png

“作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。”

冠军团队:缘拼

选手:康帅 杨桢 张晨博

1、请介绍一下自己/团队

我们是来自内蒙古师范大学计算机科学技术学院蚂蚁工坊的大三在校生,团队中有两名前端开发工程师和一名后端开发工程师,擅长 uniapp 以及微信小程序开发,有多个企业合作项目开发经验。我们都热爱编程,热爱生活,有创意并愿意将其付诸于实际。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。而在比赛的设计过程中,我们一开始决定的项目名称是约拼,但是经过几回队内讨论后,认为陌生人社交,更多靠的是缘分,而不是按部就班,所以改名为缘拼。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

受当前疫情影响,人们的活动范围很是受限,但受限并不意味着无趣 —— 基于 RTC 技术,我们有了一个设想:用户可以发帖自由提问,而帖子增加的同时会创建一个直播连麦群聊,用户可以在其中畅所欲言,足不出户却一见如故,共同探讨问题的解决方法。

4、对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

对于我们来说,这次参加编程挑战赛意义重大,参加编程挑战赛不仅给我带来了莫大的鼓舞,也让我自己对编程更加热爱,同时也意识到自身有许多可以进步的空间。而且这次获得冠军也是对我自身两年编程学习的一次肯定与激励,让我有更大的动力去向编程水平的顶峰发起冲刺。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

勇敢参加,迈出第一步才知道路顺不顺,有了竞争才能有进步。

6、提供一张照片或者能代表你们团队的图片吧

 

       LKAlADNHRPLUiivP__thumbnail.png      

 

三个男人,三台电脑,三个月,一个奇迹(缘拼)。




GLSHGa6TWXQxGklG__thumbnail.jpg       

“我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。”

亚军 & 突出贡献奖团队:红鲤鱼与绿鲤鱼与驴

选手:顾俊 陆禹淳

1、先介绍一下你的团队与本次大赛的作品吧

「红鲤鱼与绿鲤鱼与驴」是一个固定的团队,由三个人构成:熟悉前端、WebRTC方向的红鲤鱼(也就是我本人),熟悉后端、大数据方向的绿鲤鱼,以及熟悉视觉、法务方面的驴(希望不会用到法务方面)。这次比赛是由红鲤鱼与绿鲤鱼两名成员参与的,但仍沿用了团队名。

本次大赛的参赛作品「点解」,是一个面向程序员的解谜游戏。该谜题层次丰富如洋葱,第一层需要用户集成融云SDK、掌握融云的基本概念。第二层需要用户做一定程度的视频后处理。第三层需要用户做一些图像识别。整个过程需要像打游戏一样走出新手村、打怪练级、挑战大BOSS,最终拿到宝藏。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么

「点解」的核心是一个不断翻转的二维码。它的灵感来源于一个物联网界的著名协议。这个协议在一个加密的 WIFI 信道中,通过发送的包的长度来向并不拥有密码的客户端传递消息。这让我对于信道有了颠覆性的认知 —— 信道可以如此不走寻常路!于是我就构思了这个利用 RTC 信道降级传输元信息的通信方式。它不够精巧,但足够特别。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。

4、对于你个人来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

因为工作的原因,我平时会接触各种各样的、不同场景的实时音视频应用。看多了之后就有点审美疲劳。对我而言,很多音视频项目的「创新」,多多少少能够见到已有应用的影子。从另一方面来说,我作为一个 WebRTC 工程师,如果仍然拘泥于我见过的场景,或者说创新力度不够大的话,那么参加挑战赛又跟上班有什么分别呢?

所以其实像 GeekOnline 这样的比赛给了这样的项目一些机会,这些项目也许不是什么赚大钱的项目,但是它们足够有趣。而唯有在这样的场景下,这样的项目才有机会被买单,这样的项目才有机会被人看见。

那么为什么不做这样的项目呢?想赚钱去上班就好了啊。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

参加啊,大不了搞砸,怕什么。搞砸一次,浑身轻松。

6、提供一张照片或者能代表你们团队的图片吧

 

       vJLVQjzLzAOw5znq__thumbnail.png      

你看这个小人,其实是一半安卓,代表了程序员,它的“帽子”其实是一条吞了大象的蛇,取自《小王子》。



 jQnAbrcslfHJGuJm__thumbnail.jpeg.jpg

“就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。”

商业价值奖团队:MAXFLOAT

选手:张先红 华辰 杨小重 焉红霞

1. 请结合几个关键词介绍一下自己/团队

MAXFLOAT是一支有实力,有梦想,有创意,敢拼搏,即想即做的队伍。团队成员经验丰富,思维灵敏,活泼可爱,富有爱心。就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。

2. 能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

“宠宝儿”是一款为宠物服务的软件,面向的都是比较有爱心的群体,因此在整体风格上,定义为暖色调。而内容素材上,偏卡通化,使其具有治愈系能力。在功能架构上,我们尽量做到简约,不让用户在杂余的地方浪费时间。

分享个比较有趣的事。在开发过程遇到了一个问题,融云的同事帮忙找了两天,最后发现是两个方法太像了,作用差不多,调错了,那时心中顿时是万马奔腾啊,但是也比较感谢他们,他们的认真和负责,深深的打动了我。我觉得其它的比赛很难做到这点。

3. 如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

1)屏幕共享

对于直播,单纯的视频直播,只能看到摄像头前的东西,而考虑到医生在进行直播的时候,有时普及一些东西,需展示一些素材。如果接入商城,用户可能在直播推荐自己的一些产品,这个时候需要做产品展示,因此屏幕共享是必须的。但这个屏幕共享不是单纯的手机屏幕共享,而应该将多个硬件的屏幕结合,用户自己选择展示。

2)内部会议

后期如果接入宠物医院,这样就相当于面向企业了,因此会考虑为他们提供一些服务。

4. 对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

当我看到咱们融云举办的活动时候,报名时间已经过去差不多半个月,当时担心时间不够用,但是到最后,我还提前一个多星期提交了作品。所以我觉得,想做什么,那就动手去做吧,不要管其它的,做了再说,决定了之后,我们开始确立参赛的项目,是构思已经的宠物项目,而这一次,它有机会展现给更多的人。然后我们对功能的删减,确定要做哪些,大概需要多长时间,通过合理的规划,自己的努力和坚持,我们提前一个多星期完成了作品。而且之前,我们没有想过做直播方面的功能,而这次融云给了我们一个很好的思路。

5. 对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

之前我们没有参加过任何比赛,这次也是偶尔看到的,正好大家都比较感兴趣,就报名参加了。

对于那些观望的,其实也没什么好的建议,如果平时比较忙的话,那确实是没有精力在放到其它事情上了,但如果有兴趣,有精力,那么我建议,还是要多做多想,这样能更好的提升自己,如果瞻前顾后,那将一事无成。

6. 提供一张照片或者能代表你们团队的图片吧

 VtotPQXvY38Pzp7w__thumbnail.jpeg.jpg

星空代表着梦想,而我们有自己的梦想,我们想做那颗最亮的星。


这次比赛中取得的成绩,对于这些参赛选手来说都只是个开始,但正如他们所说,Geek Online 2020 编程挑战赛的这一经历,一定会是他们人生中的一次宝贵经验。

Geek Online 2020 编程挑战赛虽然是第一次举办,但已经收获了参赛选手以及观看决赛路演直播观众们的一致好评,融云作为专注于通信的 PaaS 云服务平台,想要通过底层的基础模块支持,帮助企业与开发者构建「云通信」的能力。

举办此次编程挑战赛的目的,也是希望让开发者们碰撞出技术的思维火花,加速潮流技术的应用创新,也为开发者们搭建了一个沟通、交流、合作的平台,希望能够掀起一股通信技术应用的探索与实践热潮。

也希望全球 IM 和 RTC 开发者、编程爱好者与极客

收起阅读 »

2 个月激烈角逐,15 支队伍突围决赛路演!Geek Online 2020 编程挑战赛完美收官!

2020 春季的一场疫情,让远程办公和在线教育在全球范围内成为一种常态。疫情终将过去,但疫情为人们带来的新的工作及生活方式却将持续地影响着我们。后疫情时代,远程实时互动技术的重要性被提到了新的高度,下一代互联网通信云将如何作用于人们的工作和生活?融云作为全球领...
继续阅读 »

2020 春季的一场疫情,让远程办公和在线教育在全球范围内成为一种常态。

疫情终将过去,但疫情为人们带来的新的工作及生活方式却将持续地影响着我们。后疫情时代,远程实时互动技术的重要性被提到了新的高度,下一代互联网通信云将如何作用于人们的工作和生活?

融云作为全球领先的互联网通信云厂商,一直致力于 RTC 技术的创新和发展,并于近期举办了 Geek Online 2020 编程挑战赛,希望借此机会与全球开发者一道,共同寻找 RTC 技术的更多落地场景,开辟更多使用途径。

10 月 17 日,为期两个月的编程挑战赛迎来了最为紧张的决赛阶段, 15 支队伍进行了线上的路演答辩。

决赛路演,大屏直播互动

本届 Geek Online 2020 编程挑战赛以《后疫情时代,通信云技术的创新及实践》为主题,鼓励开发者挖掘关于实时音视频和即时通讯技术的更多创意。通过近 2 个月的激烈角逐,在近百份参赛作品中,15 支队伍突出重围,闯入总决赛,他们通过线上展示的方式和大家分享,角逐最后的冠军。

本次决赛的评委共有四位,分别是融云联合创始人兼 CTO 杨攀、思否联合创始人兼 CTO 祁宁、泰岳梧桐资本合伙人杨扬以及通过线上直播参与路演的评委云启资本董事总经理陈昱。

1.png
       
     

 

路演答辩借助了融云 RTC 技术搭建了一个实时互动直播平台,选手轮流进入融云实时音视频 - SealRTC 平台进行画面共享,四位导师也可以在平台内实时与选手视频交流互动。

 


       2.png
     

 

路演直播画面

部分参赛选手作品展示 & 评委点评


       3.jpg
     

 

冠军团队 - 缘拼

该团队成员擅长 uniapp 以及微信小程序开发,作品基于融云 RTC 技术。这是一款基于兴趣、基于地理位置的同城社交类小程序,可以语音、视频构建同城兴趣小组,并将线上兴趣转换为线下社交行为。相当于将豆瓣兴趣小组音视频化。




        4.jpg       

 

亚军团队 - 红鲤鱼与绿鲤鱼与驴

该作品由两位选手共同完成,分别是熟悉前端、WebRTC 方向的“红鲤鱼”和熟悉后端、大数据方向的“绿鲤鱼”。这是一款帮忙新手程序员迅速熟悉融云 SDK 的小游戏,通过识别二维码拼图的游戏,让了解融云的过程有趣味性。该作品层次丰富,第一层需要用户集成融云 SDK、掌握融云的基本概念,第二层需要用户做一定程度的视频后处理,第三层需要用户做一些图像识别。




     5.jpg       

 

季军团队 - youweyoung

获得第三名的团队包含了一位拥有前后端多年开发经验的选手。作品基于 Android 操作系统使用 RTC 混合开发,最终做出了音视频通话应用 —— IYI网络剧场,将角色扮演类的剧本杀游戏以视频形式展现,每个场景有不同的主题人物并且可以替换,人物则是以皮影、动画等形式展现,适用于远程视频讲故事或玩剧本杀,有一定新颖性。




       6.jpg       

 

科技创新奖团队 - 萍水相逢的生活

这支队伍只有一位选手,他是一个心怀想法的程序员,做的产品是一个基于事务的陌生人聊天系统,事务场景可以是租房加中介的联系方式、街头偶遇添加好友、发布大字报等,这款产品的设计思路旨在为大家生活提供便利的软件。




       7.jpg       

 

 

商业价值奖团队 - MAXFLOAT

MAXFLOAT 是一支有实力,有梦想,有创意,敢拼搏,即想即做的队伍。他们认为当前城市化生活环境下人与人的交流越来越少,宠物逐渐替代朋友成为更好的伙伴,养宠物的越来越多,但随之而来的是更多的问题,比如宠物的遗失、被抛弃造成了流浪宠物越来越多,而宠物的健康,有时也不能及时得到重视。因此他们做了一款以宠物招领、寄养、寻回、宠物医生等为主,以宠物信息普及、宠物疾病普及为辅的 APP 帮助广大宠物爱好者。






包含获奖团队在内的 15 组团队,作品各具特色,即为评委以及线上观众们展示了自身的产品创意,也展示了 RTC 技术在实际应用中的能力与延展性,很多选手的作品获得了评委们的高度评价。我们对获奖团队进行了单独的采访,内容会于后续发出,敬请期待。

在选手们精彩的分享以及答辩之后,四位评委嘉宾分别给出了对于参加本次比赛的感受。






“融云始于 IM,又不止于 IM。通过融云提供的技术以及服务能力,开发者们可以更加关注线上的优化与迭代,期待更多开发者利用融云SDK,开发更创新、强大的产品。” —— 陈昱






“本次的决赛中我有很多印象深刻的作品,有的非常符合开发者的口味,有的对于使用场景有着很深入的思考。因为疫情,通信云技术的需求正在变得越来越大、越来越丰富,有很多场景需要我们去开拓,很值得开发者们关注并付出行动。” —— 祁宁






“选手们有很多创意创新点都很好,将很多现实中生活化的场景融入到比赛中,也有一些具有极客特质的项目,这些都是融云自身生态开发能力非常好的体现。对于融云来说,开发者是宝贵的资源,而通信云的生态也需要非常广泛的群体参与,共同完善。” —— 杨扬






“很高兴的看到,决赛中有很多作品提到了人们的心理问题,除开产品技术本身,还致力于解决人文层面的诉求。基于 IM 的核心能力,选手们提供了很多在线的沟通场景,比如剧本杀、狼人杀等等,基于这些实时互动的模式,通信能力已经变成了现代应用的一种基础设施,能为产业、产品和应用场景提供帮助,这让我们既感到压力,也感受到了更强大的动力。” —— 杨攀

结语

通过选手们的展示,我们可以了解到通信云技术的发展和提升不仅仅可以作用于工作和学习,关于实时音视频和即时通讯技术的应用,还有更多创新的场景等待我们用全新的思维来发掘。

Geek Online 2020 编程挑战赛虽然是第一次举办,但已经收获了参赛选手以及观看决赛路演直播观众们的一致好评,部分选手在路演结束后已经联系主办方咨询第二届比赛的安排,想要提前报名。

融云作为专注于通信的 PaaS 云服务平台,想要通过底层的基础模块支持,帮助企业与开发者构建「云通信」的能力。举办此次编程挑战赛的目的,也是希望让开发者们碰撞出技术的思维火花,加速潮流技术的应用创新,也为开发者们搭建了一个沟通、交流、合作的平台,希望能够掀起一股通信技术应用的探索与实践热潮。

点击进入大赛官网,查看更多比赛信息


       4aQyJP5TdHkx0NXM__thumbnail.png       


收起阅读 »

iOS 性能优化:优化 App 启动速度

作者:Damonwong,iOS 开发者来源公众号丨老司机技术周报(ID:LSJCoding)Sessions: https://developer.apple.com/videos/play/wwdc2019/423/苹果是一家特别注重用户体验的公司,过去几...
继续阅读 »

作者:Damonwong,iOS 开发者

来源公众号丨老司机技术周报(ID:LSJCoding)

Sessions: https://developer.apple.com/videos/play/wwdc2019/423/

苹果是一家特别注重用户体验的公司,过去几年一直在优化 App 的启动时间,特别是去年的 WWDC 2019 keynote[1] 上提到,在过去一年苹果开发团队对启动时间提升了 200%

虽然说是提升了 200%,但是有些问题还是没有说清楚,比如:

  • 为什么优化了这么多时间?

  • 作为开发者的我们,我们还可以做哪些针对启动速度的优化?

所以我们今天结合 WWDC2019 - 423 - Optimizing App Launch[2] 聊一下和启动相关的东西

名词解释

先介绍一些和启动相关的名词。

Mach-O

Mach-O 是 iOS 系统不同运行时期可执行的文件的文件类型统称。主要分以下三类:

  • Executable - 可执行文件,是 App 中的主要二进制文件

  • Dylib - 动态库,在其他平台也叫 DSO 或者 DLL

  • Bundle - 苹果平台特有的类型,是无法被连接的 Dylib。只能在运行时通过 dlopen() 加载

Mach-O 的基本结构如下图所示,分为三个部分:

  • Header 包含了 Mach-O 文件的基本信息,如 CPU 架构,文件类型,加载指令数量等

  • Load Commands 是跟在 Header 后面的加载命令区,包含文件的组织架构和在虚拟内存中的布局方式,在调用的时候知道如何设置和加载二进制数据

  • Data 包含 Load Commands 中需要的各个 Segment 的数据。

绝大多数 Mach-O 文件包括以下三种 Segment

  • __TEXT - 代码段,包括头文件、代码和常量。只读不可修改。

  • __DATA - 数据段,包括全局变量, 静态变量等。可读可写。

  • __LINKEDIT - 如何加载程序, 包含了方法和变量的元数据(位置,偏移量),以及代码签名等信息。只读不可修改。

Image

指的是 Executable,Dylib 或者 Bundle 的一种。

Framework

有很多东西都叫做 Framework,但在本文中,Framework 指的是一个 dylib,它周围有一个特殊的目录结构来保存该 dylib 所需的文件。

虚拟内存(Virtual Memory)

虚拟内存是建立在物理内存和进程之间的中间层。是一个连续的逻辑地址空间,而且逻辑地址可以没有对应的实际物理内存地址,也可以让多个逻辑地址对应到一个物理内存地址上。

Page Fault

当进程访问一个没有对应物理地址的逻辑地址时,会发生 Page Fault

Lazy Reading

某个想要读取的页没有在内存中就会触发 Page Fault,系统通过调用 mmap() 函数读取指定页,这个过程叫做 Lazy Reading

COW(Copy-On-Write)

当进程需要对某一页内容进行修改时,内核会把需要修改的部分先复制一份,然后再修改,并把逻辑地址重新映射到新的物理内存去。这个过程叫做 Copy-On-Write

Dirty Page & Clean Page

Image 加载后,被修改过内容的 Page 叫做 Dirty Page,会包含着进程特定的信息。与之相对的叫 Clean Page,可以从磁盘重新生成。

共享内存(Share RAM)

当多个 Mach-O 都依赖同一个 Dylib(eg. UIKit)时,系统会让这几个 Mach-O 的调用 Dylib 的逻辑地址都指向同一块物理内存区域,从而实现内存共享。Dirty Page 为进程独有,不能被共享。

地址空间布局随机化(ASLR)

当 Image 加载到逻辑地址空间的时候,系统会利用 ASLR 技术,使得 Image 的起始地址总是随机的,以避免黑客通过起始地址+偏移量找到函数的地址

当系统利用 ASLR 分配了随机地址后,从 0 到该地址的整个区间会被标记为不可访问,意味着不可读,不可写,不可被执行。这个区域就是 __PAGEZERO 段,它的大小在 32 位系统是 4KB+,而在 64 位系统是 4GB+

代码签名(Code Sign)

代码签名可以让 iOS 系统确保要被加载的 Image 的安全性,用 Code Sign 设置签名时,每页内容都会生成一个单独的加密散列值,并存储到 __LINKEDIT 中去,系统在加载时会校验每页内容确保没有被篡改。

dyld(dynamic loader)

dyld 是 iOS 上的二进制加载器,用于加载 Image。有不少人认为 dyld 只负责加载应用依赖的所有动态链接库,这个理解是错误的。dyld 工作的具体流程如下:参考:dyld启动流程[3]

Load dylibs

dyld 在加载 Mach-O 之前会先解析 Header 和 Load Commands, 然后就知道了这个 Mach-O 所依赖的 dylibs,以此类推,通过递归的方式把全部需要的 dylib 都加载进来。

一般来说,一个 App 所依赖的 dylib 在 100 - 400 左右,其中大多数都是系统的 dylib,因为有缓存和共享的缘故,读取速度比较高。

Fix-ups

因为 ASLR 和 Code Sign 的原因,刚被加载进来的 dylib 都处于相对独立的状态,为了把它们绑定起来,需要经过一个 Fix-ups 过程。Fix-ups 主要有两种类型:Rebase 和 Bind。

PIC(Position Independent Code)

因为代码签名的原因,dyld 无法直接修改指令,但是为了实现在运行时可以 Fix-ups,在 code gen 时,通过动态 PIC(Position Independent Code)技术,使本来因为代码签名限制不能再修改的代码,可以被加载到间接地址上。当要调用一个方法时,会先在 __DATA 段中建立一个指针指向这个方法,再通过这个指针实现间接调用。

Rebase

Rebase 就是针对“因为 ASLR 导致 Mach-O 在加载到内存中是一个随机的首地址”这一个问题做一个数据修正的过程。会将内部指针地址都加上一个偏移量,偏移量的计算方法如下:

  Slide = actual_address - preferred_address

所有需要 Rebase 的指针信息已经被编码到 __LINKEDIT 里。然后就是不断重复地对 __DATA 中需要 Rebase 的指针加上这个偏移量。这个过程中可能会不断发生 Page Fault 和 COW,从而导致 I/0 的性能损耗问题,不过因为 Rebase 处理的是连续地址,所以内核会预先读取数据,减少 I/O 的消耗。

Binding

Binding 就是对调用的外部符号进行绑定的过程。比如我们要使用到 UITableView,即符号 _OBJC_CLASS_$_UITableView, 但这个符号又不在 Mach-O 中,需要从 UIKit.framework 中获取,因此需要通过 Binding 把这个对应关系绑定到一起。

在运行时,dyld 需要找到符号名对应的实现。而这需要很多计算,包括去符号表里找。找到后就会将对应的值记录到 __DATA 的那个指针里。Binding 的计算量虽然比 Rebasing 更多,但实际需要的 I/O 操作很少,因为之前 Rebasing 已经做过了。

dyld2 & dyld3

 

在 iOS 13 之前,所有的第三方 App 都是通过 dyld 2 来启动 App 的,主要过程如下:

  • 解析 Mach-O 的 Header 和 Load Commands,找到其依赖的库,并递归找到所有依赖的库

  • 加载 Mach-O 文件

  • 进行符号查找

  • 绑定和变基

  • 运行初始化程序

上面的所有过程都发生在 App 启动时,包含了大量的计算和I/O,所以苹果开发团队为了加快启动速度,在 WWDC2017 - 413 - App Startup Time: Past, Present, and Future[4] 上正式提出了 dyld3。

dyld3 被分为了三个组件:

  • 一个进程外的 MachO 解析器


    • 预先处理了所有可能影响启动速度的 search path、@rpaths 和环境变量

    • 然后分析 Mach-O 的 Header 和依赖,并完成了所有符号查找的工作

    • 最后将这些结果创建成了一个启动闭包

    • 这是一个普通的 daemon 进程,可以使用通常的测试架构

  • 一个进程内的引擎,用来运行启动闭包


    • 这部分在进程中处理

    • 验证启动闭包的安全性,然后映射到 dylib 之中,再跳转到 main 函数

    • 不需要解析 Mach-O 的 Header 和依赖,也不需要符号查找。

  • 一个启动闭包缓存服务


    • 系统 App 的启动闭包被构建在一个 Shared Cache 中, 我们甚至不需要打开一个单独的文件

    • 对于第三方的 App,我们会在 App 安装或者升级的时候构建这个启动闭包。

    • 在 iOS、tvOS、watchOS中,这这一切都是 App 启动之前完成的。在 macOS 上,由于有 Side Load App,进程内引擎会在首次启动的时候启动一个 daemon 进程,之后就可以使用启动闭包启动了。

dyld 3 把很多耗时的查找、计算和 I/O 的事前都预先处理好了,这使得启动速度有了很大的提升。

App 启动

介绍完上面这一大堆名词之后,我们正式进入主题。

App 启动为什么这么重要?

  • App 启动是和用户的第一个交互过程,所以要尽量缩短这个过程的时间,给用户一个良好的第一印象

  • 启动代表了你的代码的整体性能,如果启动的性能不好,其他部分的性能可能也不会太好

  • 启动会占用 CPU 和内存,从而影响系统性能和电池

所以我们要好好优化启动时间。

启动类型

App 的启动类型分为三类

  • Cold Launch 也就是冷启动,冷启动需要满足以下几个条件:


    • 重启之后

    • App 不在内存中

    • 没有相关的进程存在

  • Warm Launch 也就是热启动,热启动需要满足以下几个条件:


    • App 刚被终止

    • App 还没完全从内存中移除

    • 没有相关的进程存在

  • Resume Launch 指的是被挂起的 App 继续的过程,需要满足以下几个条件:


    • App 被挂起

    • App 还全部都在内存中

    • 还存在相关的进程

App 启动阶段

App 启动分为三个阶段

  • 初始化 App 的准备工作

  • 绘制第一帧 App 的准备工作及绘制(这里的第一帧并不是获取到数据之后的第一帧,可以是一张占位视图),这时候用户与App已经可以交互了,比如 tabbar 切换

  • 获取到页面的所有数据之后的完整的绘制第一帧页面

在这个地方,苹果再次强调了一下,建议「用户从点击 App 图标到可以再次交互,也就是第二阶段结束」的时间最好在 400ms 以内。目前来看,大部分 App 都没有达到这个目标。

下面,我们把上面三个阶段分成下面这 6 个部分,讲一下这几个阶段做了什么以及有什么可以优化的地方。

 

System Interface

初始化 App 的准备工作,系统主要做了两个事情:Load dylibs 和 libSystem init

在 2017 年苹果介绍过 dyld3 给系统 App 带来了多少优化,今年 dyld3 正式开发给开发者使用,这意味着 iOS 系统会将你热启动的运行时依赖给缓存起来。以达到减少启动时间的目的。这也就是提升 200% 的原因之一。

视频中只说优化了热启动时间,理论上对于 iOS 系统来说 dyld3 应该还可以优化冷启动时间,所以不知道是因为给 iPad 增加了多任务功能的原因,还是没有把所有功能开放的原因,作者只提了热启动这个原因暂时还不太清楚。

除此之外,在 Load dylibs 阶段,开发者还可以做以下优化:

  • 避免链接无用的 frameworks,在 Xcode 中检查一下项目中的「Linked Frameworks and Librares」部分是否有无用的链接。

  • 避免在启动时加载动态库,将项目的 Pods 以静态编译的方式打包,尤其是 Swift 项目,这地方的时间损耗是很大的。

  • 硬链接你的依赖项,这里做了缓存优化。

也许有人会困惑是不是使用了 dyld3 了,我们就不需要做 Static Link 了,其实还是需要的,感兴趣的可以看一下 Static linking vs dyld3[5] 这篇文章,里面有一个详细的数据对比。

libSystem init 部分,主要是加载一些优先级比较低的系统组件,这部分时间是一个固定的成本,所以我们开发人员不需要关心。

Static Runtime Initializaiton

这个阶段主要是 Objective-C 和 Swift Runtime 的初始化,会调用所有的 +load 方法,将类的信息注册到 runtime 中。

在这个阶段,原则上不建议开发者做任何事情,所以为了避免一些启动时间的损耗,你可以做以下几个事情:

  • 在 framework 开发时,公开专有的初始化 API

  • 减少在 +load 中做的事情

  • 使用 initialize 进行懒加载初始化工作

UIKit Initializaiton

这个阶段主要做了两个事情:

  • 实例化 UIApplication 和 UIApplicationDelegate

  • 开始事件处理和系统集成

所以这个阶段的优化也比较简单,你需要做两个事情:

  • 最大限度的减少 UIApplication 子类初始化时候的工作,更甚至与不子类化 UIApplication

  • 减少 UIApplicationDelegate 的初始化工作

Application Initializaiton

这个阶段主要是生命周期方法的回调,也正是开发者最熟悉的部分。

调用 UIApplicationDelegate 的 App 生命周期方法:

  application:willFinishLaunchingWithOptions: 
  application:didFinishLaunchingWithOptions:

和 UIApplicationDelegate 的 UI 生命周期方法:

  applicationDidBecomeActive:

同时,iOS 13 针对 UISceneDelegate 增加了新的回调:

  scene:willConnectToSession:options:
  sceneWillEnterForeground:
  sceneDidBecomeActive:

也会在这个阶段调用。感兴趣的可以关注一下 Getting the Most out of Multitasking 这个 Session,暂时没有视频资源,怀疑是现场演示翻车了,所以没有把视频资源放出来。

在这个阶段,开发者可以做的优化:

  • 推迟和启动时无关的工作

  • Senens 之间共享资源

Fisrt Frame Render

这个阶段主要做了创建、布局和绘制视图的工作,并把准备好的第一帧提交给渲染层渲染。会频繁调用以下几个函数:

 loadView
 viewDidLoad 
 layoutSubviews

在这个阶段,开发者可以做的优化:

  • 减少视图层级,懒加载一些不需要的视图

  • 优化布局,减少约束

更多细节可以从 WWDC2018 - 220 - High Performance Auto Layout[6] 中了解

Extend

大部分 App 都会通过异步的方式获取数据,并最终呈现给用户。我们把这一部分称为 Extend。

因为这一部分每个 App 的表现都不一样,所以苹果建议开发者使用 os_signpost 进行测量然后慢慢分析慢慢优化。

测量 App 启动时间

要找到启动过程中的问题,就要进行多次测量并前后比较。但是如果变量没有控制好,就会导致误差。

所以为了保证测量的数据能够真实的反应问题,我们要减少不稳定性因素,保证在可控的相近的环境下进行测量。最后使用一致的结果来分析。

条件一致性

为了保证环境一致,我们可以做下面这几个事情:

  • 重启手机,并等待 2-3 分钟

  • 启用飞行模式或者使用模拟网络

  • 不使用或者不变更 iCloud 的账户

  • 使用 release 模式进行 build

  • 测量热启动时间

iColud 账户切换会影响性能,所以不要切换账号或者不开启 iCloud。

测量注意点

  • 尽可能的使用具有代表性的数据进行测试

    如果不使用具有代表性的数据进行测试,就会出现偏差

  • 使用不同的新旧设备进行测试

  • 最后你还可以使用 XCTest 来测试,多运行几次,取平均结果

关于使用 XCTest 测试启动时间的信息,可以看一下 WWDC2019 - 417 - Improving Battery Life and Performance[7],但是我测试了一下,目前好像还有一部分 API 还没有开放出来,暂时还不能使用。

使用 Instruments 分析和优化 App 启动过程

优化方式

苹果给了我们三个优化方式的建议,整体思想和前面提到的各个阶段的优化差不多

Minimize Work

  • 推迟与第一帧无关的工作

  • 从主线程移开阻塞工作

  • 减少内存使用量

Prioritize Work

  • 定义好任务的优先级。

  • 利用好 GCD 来优化你的启动速度。

  • 让重要的事情保持优先

更深入的了解有关 GCD 的内容,可以看一下 WWDC2017 - 706 - Modernizing Grand Central Dispatch Usage[8]

Optimize Work

  • 简化现有工作,比如只请求必要的数据。

  • 优化算法和数据结构

  • 缓存资源和计算

使用 Instruments 分析 App 启动过程

当知道如何优化之后,我们需要针对我们的启动过程进行分析。Xcode 11 的 Instruments 为此新增了一个 App launch 模板,让开发者可以更好的分析自己 App 的启动速度。

 

运行后可以看到各个阶段的具体时间,根据数据进行优化,还能看到耗时的函数调用。

 

系统优化

去年苹果做了很多优化,下面这几个高亮的是和启动速度有关的优化

 

但是不知道是不是时间原因,在 session 中对于这部分的解释特别少,很难理解 200% 到底做了什么。

但是 Craig Federighi 在 The Talk Show Live From WWDC 2019, With Craig Federighi and Greg Joswiak[9] 中针对为什么优化了 200% 说了这样一段话:

Isn’t that crazy that was quite a discovery for us. No it turns out that over times as in terms of the way the apps were encrypted and the way fair play worked and so forth. The encryption became part of the critical path actually of launching the apps. I mean the processors are capable or up and through the thing that actually it was a problem. And then there are other optimizations that based on what was visible to system at certain things. And so it actually cut out optimization opportunities and so when we really identified that opportunity we said okay. We can actually come up with better format that’s gonna eliminate that being on the critical path, It’s going to enable all these pre-binding things. And then we did a whole bunch of other work to optimize the objective-c runtime to optimize the linker the dynamic linker a bunch of other things and you put it all together. And yeah that I mean a cold launch this is we’ve never had a win like this to launch time in a single release.

从这段话中,除了 dyld3 的功劳之外,减少对代码签名加密也是优化之一。

监控线上用户 App 的启动

Xcode 11 在 Xcode Organizer 新增了一个监控面板,在这个面板里面可以查看多个维度的用户数据,其中还包括平均启动时间。

 

当你通过 Instruments 分析完你的启动过程,并做了大量优化之后,你就可以通过 Xcode Organizer 来分析你这次优化效果到底怎么样。

当然你可以通过去年新出的 MetricKit[10] 获取一些自定义的数据,具体参照 WWDC2019 - 417 -Improving Battery Life and Performance[11]

总结

今年苹果提的很多优化建议其实在早几年都已经说过一遍了,属于老生常谈了。但是值得点赞的是新出的 Instruments 的 App launch 和 Xcode Organizer 的性能监控。

启动优化是一个需要经常反复做的事情,越早发现问题,越容易解决问题,如果你想给你的用户一个良好的第一印象,就赶快行动起来吧。

参考资料

[1]

WWDC 2019 keynote: https://developer.apple.com/videos/play/wwdc2019/101/

[2]

WWDC2019 - 423 - Optimizing App Launch: https://developer.apple.com/videos/play/wwdc2019/423/

[3]

dyld启动流程: https://leylfl.github.io/2018/05/28/dyld启动流程/

[4]

WWDC2017 - 413 - App Startup Time: Past, Present, and Future: https://developer.apple.com/videos/play/wwdc2017/413/

[5]

Static linking vs dyld3: https://allegro.tech/2018/05/Static-linking-vs-dyld3.html

[6]

WWDC2018 - 220 - High Performance Auto Layout: https://developer.apple.com/videos/play/wwdc2018/220/

[7]

WWDC2019 - 417 - Improving Battery Life and Performance: https://developer.apple.com/videos/play/wwdc2019/417/

[8]

WWDC2017 - 706 - Modernizing Grand Central Dispatch Usage: https://developer.apple.com/videos/play/wwdc2017/706/

[9]

The Talk Show Live From WWDC 2019, With Craig Federighi and Greg Joswiak: https://daringfireball.net/2019/06/the_talk_show_live_from_wwdc_2019

[10]

MetricKit: https://developer.apple.com/documentation/metrickit

[11]

WWDC2019 - 417 -Improving Battery Life and Performance: https://developer.apple.com/videos/play/wwdc2019/417/


收起阅读 »

一个APP如何适配多个Andiroid终端?

Android响应式方案响应式的核心是拉通多终端的适配规则,开发一套界面,一个APP兼容多尺寸终端设备的显示,能够根据用户的行为以及设备的环境(屏幕尺寸、屏幕方向、是否分屏等)进行相应的页面布局以及容器尺寸的调整,为用户提供更加舒适的界面和更好的用户体验。1&...
继续阅读 »


Android响应式方案

响应式的核心是拉通多终端的适配规则,开发一套界面,一个APP兼容多尺寸终端设备的显示,能够根据用户的行为以及设备的环境(屏幕尺寸、屏幕方向、是否分屏等)进行相应的页面布局以及容器尺寸的调整,为用户提供更加舒适的界面和更好的用户体验。

image.png

1  响应式SDK



App的每个页面支持响应式,开发成本是很高的。

响应式SDK,就是为了解决App在不同尺寸设备下的适配问题,把设备的屏幕信息、容器布局规则(列数、尺寸)、业务数据二次加工等行为进行统一管理,以适应新的屏幕尺寸。


image.png2  加载流程设计image.png

通用的页面加载流程,通常都是从数据返回开始,数据解析完成后,进行页面布局渲染以及容器布局渲染。响应式在通用加载流程的基础上,加入了响应式状态变化通知、响应式数据剪裁、响应式页面布局、响应式容器布局等流程。



具体加载的流程分为两种情况:


  • 用户请求数据

  • 屏幕尺寸发生变化


 

3  架构设计



优酷各个业务开发团队,使用了统一的业务架构,我们在统一架构的基础上进行响应式适配,提供了响应式SDK,拉通各个业务方不同页面的适配规则,确保了适配效果的一致性,同时提供了基础的响应式控件,降低业务方的接入成本,那么响应式架构具体是怎么实现的呢?


image.png

从结构上看,响应式由优酷统一架构、响应式SDK、响应式页面布局、响应式容器布局四部分相互配合完成。在这些基础上支撑了首页、频道页、播放页、会员页、搜索、个人中心等众多的业务场景。




优酷统一架构和响应式SDK,提供响应式架构能力。




响应式页面布局、响应式容器布局,提供响应式参考实现。




4  数据二次加工



响应式并不是简单的将现有Phone端的业务数据,投放到Pad、折叠屏上,单纯的进行UI页面适配。想要在不同尺寸设备上都能获得良好的适配效果,需要对Phone端的业务数据二次加工,进行数据过滤、数据映射、数据合并、数据补全等操作,才能更好的适配Pad和折叠屏。

响应式SDK只是负责把数据二次加工的协议规则定下来,具体的数据二次加工逻辑需要业务方自己实现。优酷的统一架构提供了数据切面的能力,在切面上增加数据二次处理的逻辑,实现了统一的数据处理。


数据过滤



大尺寸设备上,总会遇到一些复杂的,适配不了的,也不重要的组件,这部分组件可以根据具体情况过滤处理,例如:下图中的weex组件,在Pad上直接过滤掉,不显示。


image.png

数据映射



存在一些带交互的复杂组件或者Pad上适配效果较差的组件,可以直接映射成其他已适配的组件。例如:下图中的带视频预览的预约组件映射成普通的预约组件。


image.png

数据合并



相邻的两个组件,其中有一个组件无法很好的适配大尺寸Pad,可以尝试将其数据合并到其他组件内。

例如:下图中第1个组件宽度铺满页面宽度,在大尺寸上无法适配,第2个组件通过修改列数、尺寸就可以适配。Pad竖屏下,将第一个组件插入到第二个组件的首位,进行数据合并,按照第二个组件的进行适配,显示为3列2行,达到很好的适配效果。


image.png

数据补全



在横竖屏切换过程中,部分组件会遇到组件的数量,无法铺满屏幕的宽度,导致出现留白的问题。

例如:把手机上的6条数据,直接投放到Pad横屏下,就会出现下图的留白问题:


image.png

为了解决这一类数据缺失的问题,我们选择的解法是服务端多下发一部分业务数据,客户端根据具体的屏幕尺寸,动态调整显示的个数,确保显示效果。



例如:下图中手机上显示2列3行,共6条数据,到了Pad竖屏上显示3列2行,共6条数据,到了Pad横屏上会补全2条数据,显示4列2行,共8条数据。


image.png

5  页面响应式



响应式状态

响应式状态是页面响应式最基础也是最重要的一个能力,像横竖屏切换、分屏模式、折叠屏折叠打开,都会导致页面的宽高发生变化,产生不同的响应式状态,页面内的内容会进行重新布局以及组件尺寸调整,以适应页面尺寸的变化,铺满屏幕,达到更好的显示效果。

横竖屏切换:


image.png分屏模式

image.png

折叠屏:

image.png



获取响应式状态



响应式状态的定义,需要有一个具体计算的规则,在所有尺寸的设备上都按照统一的规则进行状态区分,那么不同的响应式状态是如何区分的呢?

首先定义标准手机屏幕的物理宽度为400dp(经过大量手机设备调试采样之后获得的手机标准物理尺寸经验值),那么响应式状态的变化,由两个比例阈值决定,一个是页面物理宽度与标准物理宽度的比例阈值1.67倍(物理宽度 = 像素宽度÷屏幕密度),另一个是页面高度与页面宽度的比例阈值1.25倍。那么这两个比例阈值是如何得来的呢?

(1)1.67倍是怎么来的呢?


image.png

在播放页的适配过程中,需要适配左右分栏的显示,我们认为左侧播放器的宽度是标准物理宽度,那么整个页面的宽度就是标准物理宽度的1.67倍,这样左侧播放器有足够的空间保障视频播放的体验,右侧的也有足够的空间保障评论的显示效果。


 
(2)1.25倍是怎么来的呢?


image.png

上图列举了竖屏华为Pad上,页面高度是页面宽度的1.6倍,播放器下方的视频内容操作区,显示的视频内容是足够多的。如果页面高度小于页面宽度的1.25倍,就会挤压视频内容操作区的高度,导致显示出来的视频内容过少,影响用户体验。




当页面物理宽度大于标准物理宽度的1.67倍,同时页面高度小于等于页面宽度的1.25倍,即为大屏状态,其他情况则为小屏状态。
 
不同的响应式状态

目前支持了小屏布局和大屏布局两种状态。
 
(1)小屏布局状态

折叠屏折叠、折叠屏分屏、Pad竖屏:


image.png

image.png

image.png

(2)大屏布局状态



折叠屏打开、Pad横屏:


image.png

6  容器响应式



容器响应式,主要解决在页面尺寸发生变化时,动态调整容器布局的列数以及坑位的尺寸,优酷统一架构提供了常用的响应式容器布局:轮播布局、网格布局、横划布局、瀑布流布局。业务方可以快速实现响应式的效果。


容器适配列数、尺寸的效果

image.png

列数适配


同一个容器,在不同的尺寸页面下,会根据页面的物理宽度动态适配,显示为不同的列数。

网络布局、横划布局、瀑布流布局都采用这一套列数适配的规则:

响应式适配后的列数 = 当前屏幕宽度÷(标准屏幕宽度÷标准屏幕宽度下的组件列数 )

响应式适配后的列数,并不能解决Pad横屏上部分组件列数过多,显示过密的问题,为了解决这类问题,提供了列数二次适配的能力。

如下图所示,左侧是直接根据规则算出来的Pad横屏下的列数8列,过于密集,显示效果不好,右侧是列数二次调整后,显示为6列。

image.png

适配效果:image.png

控件尺寸适配


由于不同屏幕尺寸下,容器内部会动态调整显示不同的列数,导致控件的尺寸也会发生变化,那么如何适配控件尺寸的动态变化呢,响应式基础控件能够很好的解决这一类问题。
<span style=&qu
收起阅读 »

X-Meetup | 与大咖共同探索云原生技术领导力最新实践!

当前已经进入到了云原生时代,但推及到落地实践环节,大部分企业还处于探索阶段,不同技术的落地难点不同,面对云原生的转型,开发团队应该做出哪些改变?Kubernetes、Docker等技术该如何协同,发挥最大化价值?机器学习是人工智能的核心,如何深入的了解机器学习...
继续阅读 »
当前已经进入到了云原生时代,但推及到落地实践环节,大部分企业还处于探索阶段,不同技术的落地难点不同,面对云原生的转型,开发团队应该做出哪些改变?Kubernetes、Docker等技术该如何协同,发挥最大化价值?机器学习是人工智能的核心,如何深入的了解机器学习在通信网络资源智能分配的方法?

10月31日(周六)下午13:00,由华为云与msup联合主办的云原生技术领导力沙龙将在北京市朝阳区白家庄东里23号锦湖中心F1-B1Maple Link枫湾团结湖办公社区(音乐空间)举办,届时华为、同程艺龙、美团等公司的5位业界大咖,将围绕云原生技术落地实践展开分享,帮助大家找到架构的演进的方向,提升技术领导力和竞争力。

活动详情


主题:云原生技术领导力沙龙
时间:2020年10月31日(周六)13:00-17:30
地点:北京市朝阳区白家庄东里23号锦湖中心F1-B1Maple Link枫湾团结湖办公社区(音乐空间)
形式:线下交流
规模:150人
适合人群:技术经理、技术总监、架构师、CTO

活动日程

1844-极客在线长图.png
收起阅读 »

前端音视频之WebRTC初探

今天,我们来一起学习一下 WebRTC,相信你已经对这个前端音视频网红儿有所耳闻了。WebRTC Web Real-Time Communication 网页即时通信WebRTC 于 2011 年 6 月 1 日开源,并在 Google、Mozilla、Ope...
继续阅读 »

今天,我们来一起学习一下 WebRTC,相信你已经对这个前端音视频网红儿有所耳闻了。

WebRTC Web Real-Time Communication 网页即时通信

WebRTC 于 2011 年 6 月 1 日开源,并在 Google、Mozilla、Opera 等大佬们的支持下被纳入 W3C 推荐标准,它给浏览器和移动应用提供了即时通信的能力。

WebRTC 优势及应用场景

优势

  • 跨平台(Web、Windows、MacOS、Linux、iOS、Android)
  • 实时传输
  • 音视频引擎
  • 免费、免插件、免安装
  • 主流浏览器支持
  • 强大的打洞能力

应用场景

在线教育、在线医疗、音视频会议、即时通讯工具、直播、共享远程桌面、P2P网络加速、游戏(狼人杀、线上KTV)等。

1.png

(有喜欢玩狼人杀的同学吗?有时间可以一起来一局,给我一轮听发言的时间,给你裸点狼坑,一个坑容错。)

WebRTC 整体架构

拉回来,我们看一看 WebRTC 的整体架构,我用不同的颜色标识出了各层级所代表的含义。

2.png

  • Web 应用
  • Web API
  • WebRTC C++ API
  • Session Management 信令管理
  • Transport 传输层
  • Voice Engine 音频引擎
  • Video Engine 视频处理引擎

我们再来看下核心的模块:

Voice Engine 音频引擎

VoIP 软件开发商 Global IP Solutions 提供的 GIPS 引擎可以说是世界上最好的语音引擎,谷歌大佬一举将其收购并开源,也就是 WebRTC 中的 音频引擎。

  • iSAC:WebRTC 音频引擎的默认编解码器,针对 VoIP 和音频流的宽带和超宽带音频编解码器。
  • iLBC:VoIP 音频流的窄带语音编解码器。
  • NetEQ For Voice:针对音频软件实现的语音信号处理元件。NetEQ 算法是自适应抖动控制算法以及语音包丢失隐藏算法,能够有效的处理网络抖动和语音包丢失时对语音质量产生的影响。
  • Acoustic Echo Canceler:AEC,回声消除器。
  • Noise Reduction:NR,噪声抑制。

Video Engine 视频处理引擎

VPx 系列视频编解码器是 Google 大佬收购 ON2 公司后开源的。

  • VP8:视频图像编解码器,WebRTC 视频引擎默认的编解码器。
  • Video Jitter Buffer:视频抖动缓冲器模块。
  • Image Enhancements:图像质量增强模块。

WebRTC 通信原理

媒体协商

媒体协商也就是让双方可以找到共同支持的媒体能力,比如双方都支持的编解码器,这样才能实现彼此之间的音视频通信。

SDP Session Description Protocal

媒体协商所交换的数据就是 SDP,说是协议,其实 SDP 并不是一个真正的协议,它就是一种描述各端“能力”的数据格式。

3.png

上图所示就是 SDP 的一部分,详细内容请参考:SDP: Session Description Protocol

https://tools.ietf.org/html/rfc4566

或者参考卡神的这篇文章:WebRTC:会话描述协议SDP

https://zhuanlan.zhihu.com/p/75492311

网络协商

ICE Interactive Connectivity Establishment 互动式连接建立

想要建立连接,我们要需要拿到双方 IP 和端口的信息,在当下复杂的网络环境下,ICE 统一了各种 NAT 穿越技术(STUN、TURN),可以让客户端成功地穿透远程用户与网络之间可能存在的各类防火墙。

STUN、TURN

STUN:简单 UDP 穿透 NAT,可以使位于 NAT(或多重 NAT) 后的客户端找出自己的公网 IP 地址,以及查出自己位于哪种类型的 NAT 及 NAT 所绑定的 Internet 端口。

我们知道,NAT 主要有以下四个种类:

  • 完全锥型 NAT
  • IP 限制锥型
  • 端口限制锥型
  • 对称型

前三种都可以使用 STUN 穿透,而面对第四种类型,也是大型公司网络中经常采用的对称型 NAT ,这时的路由器只会接受之前连线过的节点所建立的连线。

那么想要处理这种网络情况,我们就需要使用 TURN (中继穿透 NAT) 技术。

TURN 是 STUN 的一个扩展,其主要添加了中继功能。在 STUN 服务器的基础上,再添加几台 TURN 服务器,如果 STUN 分配公网 IP 失败,则可以通过 TURN 服务器请求公网 IP 地址作为中继地址,将媒体数据通过 TURN 服务器进行中转。

信令服务器 Signal Server

拿到了双方的媒体信息(SDP)和网络信息(Candidate)后,我们还需要一台信令服务器作为中间商来转发交换它们。

信令服务器还可以实现一些 IM 功能,比如房间管理,用户进入、退出等。

小结

本文我们了解了 WebRTC 优势及应用场景、WebRTC 的整体架构及主要模块构成以及 WebRTC 的通信原理。这些基础知识和概念是需要我们牢记的,大家要记牢~

参考

  • 《从 0 打造音视频直播系统》 李超
  • 《WebRTC 音视频开发 React+Flutter+Go 实战》 亢少军
  • https://webrtc.github.io/webrtc-org/architecture/
  • https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API
  • https://www.w3.org/TR/webrtc/


本文转自公众号“前端食堂”,作者霍语佳

收起阅读 »

为什么 HTTPS 是安全的?

1. HTTP 协议在谈论 HTTPS 协议之前,先来回顾一下 HTTP 协议的概念。1.1 HTTP 协议介绍HTTP 协议是一种基于文本的传输协议,它位于 OSI 网络模型中的应用层。HTTP 协议是通过客户端和服务器的请求应答来进行通讯,目前协议由之前的...
继续阅读 »

1. HTTP 协议

在谈论 HTTPS 协议之前,先来回顾一下 HTTP 协议的概念。

1.1 HTTP 协议介绍

HTTP 协议是一种基于文本的传输协议,它位于 OSI 网络模型中的应用层

1.png

HTTP 协议是通过客户端和服务器的请求应答来进行通讯,目前协议由之前的 RFC 2616 拆分成立六个单独的协议说明(RFC 7230RFC 7231RFC 7232RFC 7233RFC 7234RFC 7235),通讯报文如下:

  • 请求

POST http://www.baidu.com HTTP/1.1Host: www.baidu.comConnection: keep-aliveContent-Length: 7User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36wd=HTTP
  • 响应

HTTP/1.1 200 OKConnection: Keep-AliveContent-Encoding: gzipContent-Type: text/html;charset=utf-8Date: Thu, 14 Feb 2019 07:23:49 GMTTransfer-Encoding: chunked<html>...</html>

<!--more-->

1.2 HTTP 中间人攻击

HTTP 协议使用起来确实非常的方便,但是它存在一个致命的缺点:不安全

我们知道 HTTP 协议中的报文都是以明文的方式进行传输,不做任何加密,这样会导致什么问题呢?下面来举个例子:

小明在 JAVA 贴吧发帖,内容为我爱JAVA
2.png

被中间人进行攻击,内容修改为我爱PHP
3.png

  1. 小明被群嘲(手动狗头)

可以看到在 HTTP 传输过程中,中间人能看到并且修改 HTTP 通讯中所有的请求和响应内容,所以使用 HTTP 是非常的不安全的。

1.3 防止中间人攻击

这个时候可能就有人想到了,既然内容是明文那我使用对称加密的方式将报文加密这样中间人不就看不到明文了吗,于是如下改造:

双方约定加密方式
4.png

使用 AES 加密报文
5.png

这样看似中间人获取不到明文信息了,但其实在通讯过程中还是会以明文的方式暴露加密方式和秘钥,如果第一次通信被拦截到了,那么秘钥就会泄露给中间人,中间人仍然可以解密后续的通信:

6.png

那么对于这种情况,我们肯定就会考虑能不能将秘钥进行加密不让中间人看到呢?答案是有的,采用非对称加密,我们可以通过 RSA 算法来实现。

在约定加密方式的时候由服务器生成一对公私钥,服务器将公钥返回给客户端,客户端本地生成一串秘钥(AES_KEY)用于对称加密,并通过服务器发送的公钥进行加密得到(AES_KEY_SECRET),之后返回给服务端,服务端通过私钥将客户端发送的AES_KEY_SECRET进行解密得到AEK_KEY,最后客户端和服务器通过AEK_KEY进行报文的加密通讯,改造如下:

7.png

可以看到这种情况下中间人是窃取不到用于AES加密的秘钥,所以对于后续的通讯是肯定无法进行解密了,那么这样做就是绝对安全了吗?

所谓道高一尺魔高一丈,中间人为了对应这种加密方法又想出了一个新的破解方案,既然拿不到AES_KEY,那我就把自己模拟成一个客户端和服务器端的结合体,在用户->中间人的过程中中间人模拟服务器的行为,这样可以拿到用户请求的明文,在中间人->服务器的过程中中间人模拟客户端行为,这样可以拿到服务器响应的明文,以此来进行中间人攻击:

8.png

这一次通信再次被中间人截获,中间人自己也伪造了一对公私钥,并将公钥发送给用户以此来窃取客户端生成的AES_KEY,在拿到AES_KEY之后就能轻松的进行解密了。

中间人这样为所欲为,就没有办法制裁下吗,当然有啊,接下来我们看看 HTTPS 是怎么解决通讯安全问题的。

2. HTTPS 协议

2.1 HTTPS 简介

HTTPS 其实是SSL+HTTP的简称,当然现在SSL基本已经被TLS取代了,不过接下来我们还是统一以SSL作为简称,SSL协议其实不止是应用在HTTP协议上,还在应用在各种应用层协议上,例如:FTPWebSocket

其实SSL协议大致就和上一节非对称加密的性质一样,握手的过程中主要也是为了交换秘钥,然后再通讯过程中使用对称加密进行通讯,大概流程如下:

9.png

这里我只是画了个示意图,其实真正的 SSL 握手会比这个复杂的多,但是性质还是差不多,而且我们这里需要关注的重点在于 HTTPS 是如何防止中间人攻击的。

通过上图可以观察到,服务器是通过 SSL 证书来传递公钥,客户端会对 SSL 证书进行验证,其中证书认证体系就是确保SSL安全的关键,接下来我们就来讲解下CA 认证体系,看看它是如何防止中间人攻击的。

2.2 CA 认证体系

上一节我们看到客户端需要对服务器返回的 SSL 证书进行校验,那么客户端是如何校验服务器 SSL 证书的安全性呢。

权威认证机构
在 CA 认证体系中,所有的证书都是由权威机构来颁发,而权威机构的 CA 证书都是已经在操作系统中内置的,我们把这些证书称之为CA根证书
10.png

  • 签发证书
    我们的应用服务器如果想要使用 SSL 的话,需要通过权威认证机构来签发CA证书,我们将服务器生成的公钥和站点相关信息发送给CA签发机构,再由CA签发机构通过服务器发送的相关信息用CA签发机构进行加签,由此得到我们应用服务器的证书,证书会对应的生成证书内容的签名,并将该签名使用CA签发机构的私钥进行加密得到证书指纹,并且与上级证书生成关系链。

    这里我们把百度的证书下载下来看看:

11.png
11.png

  • 可以看到百度是受信于GlobalSign G2,同样的GlobalSign G2是受信于GlobalSign R1,当客户端(浏览器)做证书校验时,会一级一级的向上做检查,直到最后的根证书,如果没有问题说明服务器证书是可以被信任的。

12.png如何验证服务器证书
那么客户端(浏览器)又是如何对服务器证书做校验的呢,首先会通过层级关系找到上级证书,通过上级证书里的公钥来对服务器的证书指纹进行解密得到签名(sign1),再通过签名算法算出服务器证书的签名(sign2),通过对比sign1sign2,如果相等就说明证书是没有被篡改也不是伪造的。

  • 这里有趣的是,证书校验用的 RSA 是通过私钥加密证书签名,公钥解密来巧妙的验证证书有效性。

这样通过证书的认证体系,我们就可以避免了中间人窃取AES_KEY从而发起拦截和修改 HTTP 通讯的报文。

总结

首先先通过对 HTTP 中间人攻击的来了解到 HTTP 为什么是不安全的,然后再从安全攻防的技术演变一直到 HTTPS 的原理概括,希望能让大家对 HTTPS 有个更深刻的了解。


收起阅读 »

又来?新增一门新的编程语言,真的学不动了

来自| 开源中国 编辑 | 可可经万维网联盟 W3C 认证的 Web 语言有 HTML、CSS 与 JavaScript,而近日该联盟正式宣布 WebAssembly 核心规范(WebAssembly Core Specifica...
继续阅读 »

来自| 开源中国 编辑 | 可可


经万维网联盟 W3C 认证的 Web 语言有 HTML、CSS 与 JavaScript,而近日该联盟正式宣布 WebAssembly 核心规范(WebAssembly Core Specification)成为官方 Web 标准,这意味着 WebAssembly 成为了第 4 种 Web 语言。
微信图片_20201020160807.jpg
WebAssembly 简称 WASM,它是为基于栈的虚拟机设计的二进制指令格式,WASM 作为可移植目标,用于编译高级语言(如 C/C++/Rust),从而可以在 Web 上部署高性能客户端和服务器应用,同时它也可以在许多其它环境中使用。
WebAssembly 描述了一种内存安全的沙箱执行环境,该环境甚至可以在现有 JavaScript 虚拟机内部实现。当嵌入到 Web 中时,WebAssembly 将强制执行浏览器的同源和权限安全策略。
WASM 有多种实现,包括浏览器和独立系统,它可以用于视频和音频编解码器、图形和 3D、多媒体和游戏、密码计算或便携式语言实现等应用。
目前 1.0 版本的 Wasm 已经支持 Chrome、Firefox、Safari 与 Edge 浏览器。
对于 Web 来说,因为其虚拟指令集设计,WebAssembly 可让加载的页面以本地编译代码运行,从而可以提高 Web 性能。
换句话说,WebAssembly 可以实现接近本地的性能,并且优化加载时间,同时最重要的是,它可以作为现有代码库的编译目标。
尽管本地类型数量很少,但相对于 JavaScript 而言,性能的提高大部分归功于其对一致类型的使用。WebAssembly 对编译语言进行了数十年的优化,其字节代码针对紧凑性和流传输进行了优化。在下载其它代码时,网页便可以开始执行。网络和 API 访问通过附带的 JavaScript 库进行,安全模型则与 JavaScript 相同。
WebAssembly(简称 Wasm)是一种为栈式虚拟机设计的二进制指令集。Wasm 被设计为可供类似C/C++/Rust等高级语言的平台编译目标,最初设计目的是解决 JavaScript 的性能问题。Wasm 是由 W3C 牵头正在推进的 Web 标准,并得到了谷歌、微软和 Mozilla 等浏览器厂商的支持。
Wasm 具有运行高效、内存安全、无未定义行为和平台独立等特点,经过了编译器和标准化团队多年耕耘,目前已经有了成熟的社区。

设计目标

Ontology 目前支持的 NeoVM,具有简单轻量的特点,内置了整数、字节、结构、数组和字典等丰富的类型,由宿主完成数据的内存分配管理工作,因此很多功能可以通过少量的字节码完成。目前,很多的实用功能借助于原生合约实现,以系统调用的方式提供。

Runtime API 设计

Wasm 以模块的形式组织,模块内部主要包括类型定义、函数、全局变量、内存段、表和导入导出项。我们提供 Runtime 原生模块作为 Wasm 虚拟机和链交互的桥梁,在虚拟机启动时会默认加载该 Runtime 模块,供 Wasm 合约导入和调用。
由于 Wasm 只定义了内存块,没有内置内存分配使用的逻辑,所以要么由 Runtime 提供 malloc、free 等内存分配管理 API,要么由合约自身进行管理。经过细致比较分析,Runtime 管理会限制内存分配算法的升级:
由于内置在 Runtime 中,可能会导致硬分叉,比如老版本分配在内存10的位置,新版本分配在20的位置,很可能导致合约执行结果的不一致;
另外如果老版本的分配算法不够优化,导致合约执行时内存不足而执行失败,新的分配算法可能使合约执行成功,也会导致合约执行分叉。
因此将内存交由合约自身管理是一个扩展性更好的选项,同时也简化了 Runtime 的 API 设计。由于内存由合约管理,因此在 Runtime 需要向合约传递数据时需要由合约预先进行内存分配。
由于 Wasm 自身只支持 u32、u64等简单的类型,对于 Runtime 需要向 Wasm 传递复杂的数据结构时,我们定义了 Abi Codec 对数据结构序列化为字节数组的形式,写入 Wasm 内存,然后由用户合约还原出原数据结构。
小结
Ending 定律也称为终结者定律,它是 Ending 在 2016 年 Emscripten 技术交流会上给出的断言:所有可以用 WebAssembly 实现的终将会用 WebAssembly 实现。
WebAssembly,理论上能编译成 LLVM 的语言,都能编程成 WASM,从而在浏览器上运行。(这家伙是跑在浏览器上的汇编语言么?这是 Java Applet 的加强版么?)然后那些没有 Web 版的软件,理论上都能在浏览器上跑了。
Go 语言之1.11版本已支持 WASM。然后写了个 GO 程序可以在浏览器跑了,界面直接使用 HTML 输出。再看看那个只有浏览器的 Chrome OS。以前总是有评论说这系统太超前了,现在终于明白了。
有了 WASM,未来的操作系统真的只需装个浏览器了。
收起阅读 »

未来 10 年,软件开发涨工资的 8 个 技术发展趋势

英文 | https://medium.com/better-programming/software-developer-trends-of-2020-and-beyond-d1b955bc46b8     &nb...
继续阅读 »
英文 | https://medium.com/better-programming/software-developer-trends-of-2020-and-beyond-d1b955bc46b8
 
 


 
新的一个十年来到,随之而来的是对技术变革和趋势的兴奋之潮。软件开发已成为世界几乎每个部门不可或缺的一部分,因此软件开发的发展和变化对我们的生活产生了巨大影响。尽管我们无法始终准确地预测技术的发展前景,但我们仍有望在新的十年中延续一些趋势。
 

 
以下是我们预测并讨论的在未来10年里软件开发技术的8个开发趋势。
 


 



1、人工智能将继续占主导地位


尽管人工智能已经存在了很多年,但它每年都在不断增长和增强,成为全球许多技术的基础。开发人员预测,随着越来越多的行业在基础架构中采用AI,人工智能将继续占主导地位。
 
2020年的最大趋势表明,医疗保健,教育,旅游行业和社交媒体将使用AI来提供个性化的体验,帮助和预测服务。人工智能将成为整个行业新的竞争优势,改变我们对人类参与和资源的思考方式。深度学习框架Tensorflow 2.0预计将主导市场。
 


 

2、Python预计会随着AI和Ml的发展而崛起


 


 
从ML研究到视频游戏开发再到Web开发,Python一直被证明是一种流行且广受欢迎的语言。由于ML和AI的发展正在上升,因此预计Python将在这种稳定的增长和普及中继续发展,特别是对于令人印象深刻的创新,包括ML驱动的聊天机器人。
 
尽管“增长最快”语言的概念可能很难确定,但数据表明Python可能是块不错的蛋糕。Python不仅用于各种流行领域和工作,而且入门门槛低,并且由新一代开发人员培育而成的支持社区。
 

 


 

3、5G可能是为开发人员打开大门的下一个重要物种


 
5G将于2020年进入市场。这个令人兴奋,更快的网络带来了开发人员需要解决的新问题。尽管存在诸多弊端和争议,但5G仍有可能革新手持设备,并为开发人员进入分布式技术的底层打开大门。
 
它为开发人员提供了开发更强大的应用程序和增强现实功能的机会。总体而言,预计5G将改变整个世界-从为智慧城市提供动力,到改善交通系统,再到增加网络扩展能力。
 
当然,5G的处理能力还带来了开发人员必须解决的问题,例如
  最近对天气预报技术的关注
 
  对覆盖范围不佳的吐槽
  。不管面临的挑战如何,该技术都是有前途的,值得学习投资。
 

 

 


 

4、边缘和云计算的使用预计会上升

与5G一同出现的还有
  边缘计算
  的潜力:一种分散式计算基础架构。边缘计算的高度分布式模型可能有助于克服云计算的缺点。这些发展可能是计算和工业的未来。
 
事实证明,云计算对于公司基础架构至关重要,并且随着网络安全问题的持续存在,各行各业的大公司都将云作为解决方案。
 
最重要的是,到2020年底,
  全球公共云服务收入
  预计将从2278亿美元增长到2664亿美元。边缘计算预计将随着云计算功能的升级而增长。实际上,预计
  全球Edge计算市场
  将从2018年的14.7亿美元增长到2025年的268.4亿美元。
 


 


 

5、预计会有新突破的语言:Rust,TypeScript,Kotlin和Swift


 
在过去的十年中,已经创建了数百种编程语言。这种从过去的单一语言的转变使开发人员能够使用专门的语言来工作,这些语言更加侧重于开发人员的人机工程学和硬件的现代化开发。
 
种类繁多的编程语言可使开发人员
  增强能力
 
  增强行业实力
  ,并将我们的重点转向解决人类问题。
  StackOverflow研究
  表明,到2020年,排名前四的现代编程语言将为Rust,TypeScript,Kotilin和Swift,其中Rust在过去四年中连续第四位。
 


 


 

6、 Kubernetes成为Mesos和Docker Swarm的胜利者


 
随着云计算的兴起,容器化应用程序的兴起。在这里,Kubernetes显然是赢家。随着云技术继续与我们的世界融合,Kubernetes将成为各地开发人员的重要工具。研究表明,Kubernetes的受欢迎程度持续上升。
  开发人员预测
  ,到2020年,我们将看到此流行应用程序的最佳实践和标准化的兴起。
 

 

 

 


 

7、Web框架:React继续发光


 
React对Web开发产生了巨大的影响,它带来的创新对开发人员都非常有用。它已被证明是过去一年中最主要的JavaScript框架。而统计数据表明,这种情况将持续数年。尽管其他框架(例如Vue)提供了自己独特的功能,但是
  React
  由于其灵活性和健壮性而受到许多人的
  青睐
 
 
而且,由于React得到了Facebook的支持,因此它将作为Web开发的标准在业界不断上升。查看这些Google趋势,以了解自2017年以来React在全球范围内的关注程度。
 

 



 

8、降低软件开发入门的门槛:会有越来越多的自学成才的程序员

尽管对技术行业有普遍的认识,但是软件开发的供需之间还是存在差距。随着全球大学价格的上涨,越来越少的人选择计算机科学专业。预计在未来几年内,软件开发人员的进入门槛将降低,从而为自学成才的开发人员腾出空间。
 
此外,一些开发人员预测,LCCS开发(低代码,无代码开发)将为企业创新提供增长,而无需CS学位持有者。
 
在线学习平台是行业转移的原因之一。Educative为所有级别的开发人员提供大学水平的课程,以提高他们的编码技能,并以低廉,无压力的成本处理新语言。2020年的目标是使世界各地的人们能够在没有大学负担的情况下加入发展世界,学习编程的队伍中来。
 


收起阅读 »