2024年Web前端最全Rust跨平台探索:前端中的后端,Web前端事件分发面试

最后

面试题千万不要死记,一定要自己理解,用自己的方式表达出来,在这里预祝各位成功拿下自己心仪的offer。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

大厂面试题

面试题目录

image.png

进程间通信可以使用很多方式来进行消息的传递,比如大家熟悉的管道(pipe)。然而,Eletron 使用了 web worker API postMessage 相同的 structured clone algorithm 来做 IPC 数据的序列化和反序列化。这个方法效率和 JSON 差不太多,在传输大量数据时同样会有性能问题,所以 Electron 推荐使用 CSS animation,而非常不建议做 JS anination。

3. 基于 Canvas 绘制

Canvas绘制是实现UI跨平台的主流思路:

  • 平台渲染: 用 JS 来调用原生 UI, 这是 React Native 采用的方式。优点是大部分时候性能足够好;缺点是 JS bridge 需要适配所有支持的平台,当平台侧UI控件想要在RN中使用,需要开发者花费额外精力去适配。
  • 统一渲染: 用其他技术来模拟原生 UI。这是 Cordova / Electron 采用的方式。优点是代码简单,UI 直接在第三方渲染器(webview)中渲染出来;缺点是 UI 性能受 JS 单线程及 webview 本身渲染性能的影响,在复杂交互时往往表现不佳。

当大多数选择统一渲染方案的技术栈只是把目光停留在了webview ,人们忽略了其实所有的 UI 渲染,最终都是在 canvas 上一个像素一个像素填充出来的。如果做一套系统,略过 dom/css/js 复杂的渲染逻辑,直接定制好各种各样的控件,将其绘制到 canvas 上,是不是可以鱼与熊掌兼得?

做到这点的要数 flutter 了。它使用 chrome 底层的图形渲染引擎 skia,从底向上设计出来一套可以高效工作的控件库,比 webview 性能高的同时,又不依赖平台侧的控件。

image.png

现有跨平台方案中的问题

目前所有这些方案的着眼点还是局限在UI层的跨平台,那么业务逻辑代码怎么办?用JS这样的 UI 层的语言撰写难以保证运行时效率,最终还是要诉诸于 native 语言实现,原本一种语言统一天下的初衷,最终发现要学习三种语言,iOS、android、JS/dart 各来一套(flutter可能做得稍微强一点儿,但是依然需要借助 channel 调用平台侧的服务)。

“相比UI跨平台,如何在业务逻辑层跨平台是一个容易被忽略但更值得被关注的问题。”

那么为什么逻辑层跨平台技术进展如此缓慢呢?一个主要原因是没有一个合适的语言工具,很难找到一门语言能够同时覆盖这么多平台的原生语言的优势。

在 Rust 成熟以前,C/C++ 几乎是跨端做业务逻辑的唯一的选择。用 C/C++ 实现一次,然后在各个端上用静态链接的方式编译到 app 中。当然这免不了要做很薄的一层接口:每个平台原生语言到 C/C++ 的桥接。

但是 C/C++ 的代码(相对于 java/kotlin/swift来说)的撰写难度较高,跨平台编译链接有很多坑要踩,最终会遮掩所谓「一次撰写,到处链接」的好处。

如今有了Rust, Rust 有不输于任何一门现代语言的依赖管理和生态,有非常完备的跨平台编译系统和跨语言FFI支持,而 Rust 本身的不依赖运行时的内存安全和并发安全性,还有几乎最高质量的 webassembly 支持,使其成为 C/C++ 跨平台的完美替代品。除了 rust 本身的跨平台工具链之外,Rust 生态里还有专门为简化与 iOS 原生语言互操作的工具 cargo lipo(封装 C FFI),以及为与 java 互操作的 jni,甚至还有专门针对 Android 的 android-ndk-rs。

接下来,我们需要的就是一套组织各个平台原生语言和 Rust 互操作的思路,来解决通用性的问题。

前端中的后端

所谓前端中的后端,就是在前后端分离的基础上,进一步把前端中偏 UI 的业务逻辑和偏数据处理的业务逻辑分开。而掌管数据处理的这部分功能,我们管它叫前端中的后端。

基本架构

无论是前端架构中被广泛使用的 MVC 还是 MVVC 模式,其第一个 M,Model(包含数据,状态,以及业务逻辑),就是我们要分离出来统一处理的「后端」。借鉴之前提到的 bridge 模式,可以构想出来这么一套前端代码的前后端分离的模型:

image.png

这个模型相对于传统的 UI 跨平台方案,其最大不同是:让所有的相关方处理自己最擅长的事情,而不要强行适配。和平台相关的代码,比如 UI,平台设备的访问等,用更擅长做这件事情的平台原生语言实现(或者 flutter),而平台无关的业务逻辑代码,算法,网络层代码,使用 Rust 来实现。这样,Rust backend 不用去花大量的精力去包裹平台的东西,而只需干好一个 backend 需要干好的事情。

通信方式

之前的 UI 方案,采用的都是 JSON 或者类 JSON 的序列化方案,JSON 是效率非常低下,且类型安全度比较低的一种序列化方案,在这样的场景下,我们还有更多更好效率更高类型更安全的方案,比如 protobuf,flatbuffers 等。

反序列化序列化
image.pngimage.png

以 Rust 和 Kotlin 之间做通信为例,使用 JSON 以及 Protobuf 的通信流程分别如下:

JSONProtobuf
image.pngimage.png

Rust 和 Kotlin 分别将定义好的 protos 编译成平台代码,然后可以在两端自由地传递 protobuf 的数据。

示例

比如要展示电影网站 Tubi 的首页,假设我们基于 clean architecture 的 MVP 结构实现此逻辑

  • 后端提供 API 获取电影列表 GET /api/v1/get_movies
  • 建立一个 TubiRepository 处理网络层的请求
  • 请求的响应被反序列化成 Category / Movie models,然后以 Entity 的形式交给 Use cases
  • 最后presentation layer 将结果被渲染到屏幕

image.png

这里,尝试对 Model层 用Rust实现,如下:

  1. 暴露给 native 层的方法是:getMovies()
  2. getMovies() 内部将参数序列化成 protobuf 传递给一个 Rust 函数 dispatcher
  3. dispatcher 反序列化请求后得知是一个 RequestGetMovies,随后被 dispatch 给 get_movies()
  4. get_movies()从本地 cache 里读取数据,读不到的话通过 reqwest 从远程 API 获取数据并缓存

image.png

从 native 开发者的角度,她就调用了一个 getMovies() 后返回了序列化好的 Movie,Category等数据结构,其它的细节不需要理会。

再举个例子,用户在观看视频的时候,客户端会定期向服务器汇报当前观看的位置

  1. API: PUT /api/v1/update_history
  2. 在 native 层暴露出一个 updateHistory() 的方法
  3. dispatcher 将其 dispatch 给 Rust 函数 update_history()

image.png

从上述的例子,我们大概可以看到在 Rust 侧我们可以处理的工作:

  1. 更高效的网络层:自动管理的连接池,更好的流控,更灵活的安全处理方式,以及,UI 侧无感知的网络层处理,比如有一天我们把 REST API 升级成 gRPC,API 层的签名采用 schnorr signature,或者 HTTP/2 升级到 HTTP/3。native 侧根本无需关心。
  2. 更好的数据管理。Rust 有丰富高效的数据结构,可以为每一种数据设置量身定制的方案。我们还可以做非常高效的数据缓存。
  3. 在此之上给数据的赋能。比如为 get_movies() 获取到的数据做简单的索引,方便数据在各个不同维度的展示和过滤。

如何持续维护?

如上,我们对前后端进行分离,由于双方基于 protobuf 实现通信,那么维护好 protobuf message 的定义非常重要。其中 Request 和 Response 是最核心的两个消息:

  • Request: one of 类型。里面包含所有从 native 侧调用 Rust 函数的请求接口,比如 RequestGetMoviesRequestUpdateHistory 等。
算法刷题

大厂面试还是很注重算法题的,尤其是字节跳动,算法是问的比较多的,关于算法,推荐《LeetCode》和《算法的乐趣》,这两本我也有电子版,字节跳动、阿里、美团等大厂面试题(含答案+解析)、学习笔记、Xmind思维导图均可以分享给大家学习。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

写在最后

最后,对所以做Java的朋友提几点建议,也是我的个人心得:

  1. 疯狂编程

  2. 学习效果可视化

  3. 写博客

  4. 阅读优秀代码

  5. 心态调整

a01373152bb4cd38bc6ad5cc8027.png)

写在最后

最后,对所以做Java的朋友提几点建议,也是我的个人心得:

  1. 疯狂编程

  2. 学习效果可视化

  3. 写博客

  4. 阅读优秀代码

  5. 心态调整

  • 14
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值