前端需要理解的跨平台知识
混合开发是指使用多种开发模开发App的一种开发模式,涉及到两大类技术:原生 Native、Web H5。原生 Native 主要指 iOS(Objective C)、Android(Java),原生开发效率较低,开发完成需要重新打包整个App,发布依赖用户的更新,性能较高功能覆盖率更高;Web H5主要由HTML、CSS、JavaScript组成,Web可以更好的实现发布更新,跨平台也更加优秀,但性能较低,特性受限。
跨平台开发是围绕着研发效能和用户体验两个主题去打造的,通过在两者之间进行取舍,诞生了多种跨平台解决方案。根据采用的渲染技术不同,跨平台解决方案分为Web 渲染、原生渲染和自建渲染引擎渲染。
1 JSBrigde 和 WebView
1.1 JSBrigde
原生Native与Web端相互通信离不开JSBridge。JSBridge是以 JavaScript 引擎或 Webview 容器作为媒介,通过协定协议进行通信,实现 Native 端和 Web 端双向通信(JS 向 Native 发送消息: 调用相关功能、通知 Native 当前 JS 的相关状态等。Native 向 JS 发送消息: 回溯调用结果、消息推送、通知 JS 当前 Native 的状态等。)的一种机制。
JavaScript 是运行在一个单独的 JS Context 中(例如,WebView 的 Webkit 引擎、JSCore)。由于这些 Context 与原生运行环境的天然隔离,可以将这种情况与 RPC(Remote Procedure Call,远程过程调用)通信进行类比,将 Native 与 JavaScript 的每次互相调用看做一次 RPC 调用。如此可以按照通常的 RPC 方式来进行设计和实现。
目前主流的 JSBridge实现中,都是通过拦截 URL 请求来达到 native 端和 webview 端相互通信的效果。
- 首先,需要在 webview 侧和 native 侧分别注册 bridge,其实就是用一个对象messageHandlers把所有handler函数储存起。
- 然后,在 webview 里面注入初始化代码:
(1)创建一个名为 WVJBCallbacks 的数组,将传入的 callback 参数放到数组内;
(2)创建一个 iframe,设置不可见,设置 src 为 https://__bridge_loaded__;
(3)设置定时器移除这个 iframe。
- 最后,在native 端监听 url 请求:
- 拦截了所有的 URL 请求并拿到 url。
- 首先判断 isWebViewJavascriptBridgeURL,判断这个 url 是不是 webview 的 iframe 触发的,具体可以通过 host 去判断。
- 继续判断,如果是 isBridgeLoadedURL,那么会执行 injectJavascriptFile方法,会向 webview 中再次注入一些逻辑,其中最重要的逻辑就是,在 window 对象上挂载一些全局变量和 WebViewJavascriptBridge属性。
- 继续判断,如果是 isQueueMessageURL,那么这就是个处理消息的回调,需要执行一些消息处理的方法。
1.2 WebView
WebView 是移动端提供的运行JavaScript的环境,是系统渲染 Web 网页的一个控件,可与页面JavaScript交互,实现混合开发。
简单来说,WebView 是手机中内置了一款高性能 Webkit 内核浏览器,在 SDK 中封装的一个组件。不过没有提供地址栏和导航栏,只是单纯的展示一个网页界面。
WebView 可以简单理解为页面里的 iframe 。原生 app 与 WebView 的交互可以简单看作是页面与页面内 iframe 页面进行的交互。就如页面与页面内的 iframe 共用一个 Window 一样,原生与 WebView 也共用了一套原生的方法。
其中 Android 和 iOS 又有些不同:
- Android目前是 基于 Chromium 内核。
- iOS 目前采用的是 WKWebView。
WebView 可以对url请求、页面加载、渲染、页面交互进行强大的处理。webview 去加载 url 并不像是 浏览器加载 url 的过程,webview 存在一个初始化的过程。为了提升init 时间,通常做法是 app 启动时初始化一个隐藏的webview等待使用,当用户点击需要加载URL,直接使用这个webview 来加载,从而减少webview init 初始化时间。弊端就是带来了额外的内存开销。
2 Web渲染
Web 渲染方案的有如下特点:
- 开发效率高:采用 Web 技术,对前端友好,一次开发,多端运行;
- 动态化好:Web 技术的天然动态特性支持,无需发版;
- 表现一致性佳:Web 页面除了个别元素和属性的差异、多屏适配外,其双端表现相对一致;
性能较差:页面采用 WebView 渲染,页面加载耗时长,功能受限于 WebView 沙箱,能力有限,难以承接复杂交互或是需要高性能的任务,整体用户体验差。
Web 渲染本质上是依托原生应用的内嵌浏览器控件 WebView 去渲染 H5 页面,并在原生应用中定义可供 H5 页面访问原生部分能力的接口 JSBridge,从而实现 H5 和 Native 双向通信,也进一步扩展 H5 端侧能力。因此,H5 App 的渲染流水线和 Web 页面渲染相一致。从 WebView 初始化到 H5 页面最终渲染的过程如下:
因此,Web 渲染性能上也存在首屏渲染优化问题,而且,还多出一个WebView 初始化的问题(可以通过 APP 启动的时候初始化一个常驻的隐藏WebView来处理)。
针对资源加载所带来的白屏问题,业界提出了离线包的优化方案。大体思路就是将原有从线上加载 H5 应用,提前下发到本地,通过 FileIO 或是内存等方式直接进行页面渲染,达到接近原生的用户体验。
在这基础上业内又提出 h5 容器的技术解决方案,h5 容器提供丰富的内置 JSAPI,增强版的 WebView 控件以及插件机制等能力,对原始版本的方案做了进一步功能高内聚和模块低耦合。
Apache Cordova 是一个开源的移动开发框架。它允许您使用标准 Web 技术 - HTML5、CSS3 和 JavaScript 进行跨平台开发。应用程序在针对每个平台的包装器内执行,并依靠符合标准的 API 绑定来访问每个设备的功能,例如传感器、数据、网络状态等。该框架的实现原理就是基于H5 容器Web 渲染技术。
Cordova 应用程序由几部分组成:
- Web App:应用程序代码的实现地方,采用的是 Web 技术,应用运行在原生控件 WebView 中。
- HTML Rendering Engine:应用的渲染引擎,即 WebView,该渲染引擎是页面和 Native 实现双向通信的桥梁。
- Cordova 插件:提供了 Cordova 和原生组件相互通信的接口并绑定到了标准的设备API上。这使你能够通过JavaScript 调用原生代码,这些核心插件包括的应用程序访问设备功能,比如:电源,相机,联系人等。
- Mobile OS:原生系统层,提供系统能力。
小程序是无需下载安装即可使用的轻应用。小程序也是基于Web 渲染方案,即采用 WebView 作为渲染引擎、JSBridge 的封装和离线包机制等,其最大创新之处在于将渲染层和逻辑层进行了分离,提供一个干净纯粹的 JavaScript 运行时,多 WebView 的架构使得用户体验进一步逼近原生体验。
小程序的渲染层和逻辑层分别由两个线程管理,渲染层采用 WebView 进行页面渲染(iOS 使用 UIWebView/WKWebView,Android 使用 WebView),小程序的多页面也由多 WebView 接管。逻辑层从 WebView 分离,使用 JavaScript 引擎(iOS 使用 JavaScriptCore,Android 使用 V8)单独开启一个 Worker 线程去执行 JavaScript 代码。逻辑层和渲染层之间的通信经由 Native 层中转,网络 IO 也通过 Native 层进行转发:
小程序采用的是多 WebView + 双线程模型。由多 WebView 构成的视图层为页面性能赋予更加接近原生的用户体验,单个 WebView 承载更加轻量的页面渲染任务(左侧为原始web渲染,右侧为小程序):
JavaScript 被单独抽离在 Worker 线程,限制了直接操作页面的能力(无法直接操作DOM),也就被约束在微信小程序的规范下。
小程序的组件分为原生组件和非原生组件,原生组件属于原生渲染的一部分,所以小程序算得上是 Web 渲染和原生渲染的融合。
综上来看,Web 渲染的发展经历了从 h5 + JSBridge + WebView,到 h5 容器的抽象提升,再到小程序三个阶段。
3 原生渲染
原生渲染的基本思路是在 UI 层采用前端框架,然后通过 JavaScript 引擎解析 JS 代码,JS 代码通过 Bridge 层调用原生组件和能力,最终,UI 的渲染通过 JSBridge 由原生控件直接接管,从而获得性能和体验的提升。代表的框架是 React Native,其整体架构图如下:
- React 层:利用 React 框架进行 UI 的数据描述,开发者使用 Class Component 或 Functional Component 进行页面开发,框架内部将会把页面描述转化为 ReactElement 这一代表的虚拟 DOM 的数据结构,用于运行时的 Diff 对比和消息收发等。
- [JS Bundle 中间产物]:RN 通过 metro 打包功能直接将整个 RN 应用打包为一个 JSBundle,通过 Bridge 层在 RN 应用初始化时加载整个 JS 包进来。
- Bridge 层:Bridge 是连接 React 和 Native 的中间层,React 层的 UI 需要通过 Bridge 层的 UIManager 接口实现原生控件的创建和更新,通过 NativeModules 接口实现原生能力的调用。
- Native 层:在 Native 层中,Native Modules 实现了与上层交互的原生能力接口,Native UI 实现终端实际的控件展示,Yoga 跨平台布局引擎实现了基于 Flexbox 布局系统的 JS 和 Native 的镜像映射关系。
视图层的渲染通过 UIManager 调 createView/updateView 等方法,基于 Yoga 布局引擎创建对应的 shadowView;逻辑层中涉及原生能力调用的部分通过 RCTBridge 对象转发到相应的原生接口。 Native 接收到 Bridge 层的消息,进行视图的更新或是功能处理。
整个 RN 的线程模型:
- Main 线程(UI 线程):应用的主线程,进行初始化和处理原生控件的绘制。初始化的内容包括加载 JSBundle、初始化 Native Modules 等原生能力模块、创建 JSCore/Hermes JavaScript 引擎。
- JS 线程:React 构成的 JS 代码运行在此线程,解释执行 React 代码,并将生成的布局或逻辑信息序列化后经由 Bridge 发送给 Native。
- Shadow 线程:主要用于构建 JS 与原生控件的布局镜像数据。
- Native Modules 线程:提供原生能力,这里采用的是多线程模型,iOS 端通过 GCD 实现,Android 端通过 AsyncTask 实现。
原生渲染直接接管渲染层,弥补了 Web 渲染方法在性能和体验上的不足。但是,在原生渲染架构中,页面的更新和事件的响应存在 Native 层和 JS 层的通信的时间成本,同时数据的交互需要频繁进行序列化和反序列化的转换,导致在一些 UI 线程和 JS 线程存在持续频繁交互的场景(动画、滚动等),RN等原生渲染的表现差强人意。
4 自建渲染引擎渲染
自建渲染引擎渲染通过自建渲染引擎方式,直接从底层渲染上实现 UI 的绘制,代表的框架是 Flutter,其架构设计如下:
- Dart App 层:以 Widget 为基本视图描述单元,构建起 UI 体系;
- Flutter Framework 层:内置基础的 Flutter 组件,并根据不同平台的视觉风格体系,封装 Material 和 Cupertino 两套 UI 库供上层使用;
- Flutter Engine 层:Flutter 框架的核心所在,包括 Dart 虚拟机、Skia 跨平台渲染引擎、文字排版、平台通道等,通过 Engine 层,建立起 Dart App 层和原生平台之间联系,从而实现二者的双向通信;
- Embedder 层:为 Flutter App 提供宿主环境、线程创建以及基于插件机制的原生能力扩展等。
Flutter 在打包的时候,将 Dart 业务代码和 Flutter Engine 代码基于 iOS/Android 不同平台分别进行打包。 Native 在启动时会通过调用 C++ 的各自实现(Java 通过 JNI,OC 天然支持)初始化 Flutter Engine 层提供的接口,创建 UI/GPU/IO 三个线程和实例化 Dart VM。Dart 业务代码在 Release 模式下采用 AOT编译(Ahead-of-Time Complier提前编译) 的方式进行编译,并运行在 Dart VM 中。
Flutter App 的线程模型:
- Platform 线程:主线程,由 Native 创建。负责平台 vsync 信号的回调注册,即当接收到从显示设备的 vsync 信号后,Platform 线程驱动 UI 线程的执行。
- UI 线程:负责响应 vsync 信号,执行 Dart 层代码,驱动渲染管线的运行,将 Widget Tree 生成 Layer Tree 并提交给 GPU 线程做进一步处理。
- GPU 线程:将 Layer Tree 转化为具体的绘制指令,并调用 skia 跨平台渲染引擎进行光栅化上屏。
- IO 线程:主要负责请求图片资源并完成解码,然后将解码的图片生成纹理并传递给 GPU 线程。
显示器在一帧 vblank 后,会向 GPU 发送 vsync 信号,Native 的 Plaform 线程接收到 vsync 信号后,执行绘制帧回调方法,即驱动 UI 线程进行 UI 绘制。
UI 线程中,Native 通过调用 C++ 的各自实现,将绘制指令通过 window 对象发送给 Dart 层,Dart 层会重构代表 UI 的数据树(Widget Tree、Element Tree 和 RenderObject Tree)并生成布局信息:
- Widget Tree 是直接面向开发者的 UI 元素的配置信息,Widget 是 Immutable 的,如果 Widget 的状态发生更新,会发生重建。实际业务场景中,Widget 会频繁触发重建。
- Element Tree 是 Widget Tree 和 RenderObject Tree 的桥梁,当Widget 发生变化后,会将其 Element 标记为 Dirty Element,在下一次 vsync 信号到来时进行渲染。当 Widget 挂载到 Widget Tree 时,会调用 widget.createElement 方法,创建其对应的 Element,Flutter 再讲这个 Element 挂载到 Element Tree 并持有有创建它的 Widget 的引用
- RenderObject Tree 是真正执行组件布局渲染的工作,通过 RenderObjectToWidgetAdapter 这个 RenderObjectWidget 建立起 Widget 、Element 和 RenderObject 三者之间的联系
根据布局信息生成一系列绘制指令的 Layer Tree,并通过 window 对象传递给 GPU 线程。
GPU 线程根据绘制指令和通过 Skia 这一跨平台渲染引擎进行光栅化,绘制成帧数据,将帧数据放在帧缓冲区,然后等待显示器上屏。
因此,以 Flutter 为代表的的自建渲染引擎的优势在于:
- UI 控件是直接采用 Skia 这一跨平台渲染引擎进行绘制:顶层使用 Dart 的语法进行 UI 的配置信息描述,并通过 Diff 算法优化渲染流程,生成 Layer Tree 后,再调用 C++ 的代码将布局信息发送给 Flutter Engine,Flutter Engine 直接通过 Skia 将 UI 控件绘制上屏。这里与原生渲染方案最大的不同点在于,Native 应用仅作为宿主环境,UI 控件不需要转化为原生控件,直接采用渲染引擎进行绘制,从而保证了双端的一致性和良好的性能与体验。
- Dart 在 Release下采用 AOT 的 编译模式:Dart 代码在 Release 采用 AOT 的编译模式转化为二进制代码,从而在 Dart 运行时环境中执行效率更高,性能也更为卓越。对比 React Native 来说,由于打包的是 JSBundle,所以在运行时仍是基于 JavaScript 运行时进行解释执行 JS 代码,因而产生较大的性能瓶颈。
- UI 层与原生层的数据交换性能更高。
相关文章:

前端需要理解的跨平台知识
混合开发是指使用多种开发模开发App的一种开发模式,涉及到两大类技术:原生 Native、Web H5。原生 Native 主要指 iOS(Objective C)、Android(Java),原生开发效率较低,开发完成需要重…...
《基于 Vue 组件库 的 Webpack5 配置》3.将 CSS 提取到单独的文件
使用 webpack 插件 mini-css-extract-plugin 需要额外安装 npm i mini-css-extract-pluginlatest -D; 同时打包 js 和 css 文件时,可参考 entry 高级用法; package.json 的配置如下 const { VueLoaderPlugin } require(vue-loader); // 可…...

2023CCF图形学启明星计划夏令营感想记录
这篇就是纯日记了,想记录一下参加这个夏令营的感想,中间的一些过程,毕竟这对我来说算是一段难忘的经历。 一、了解到的渠道 我个人是比较喜欢图形渲染的,之前也学过GAMES的课程,然后偶然的一天,GAMES101里…...

如何解决“缺失msvcp110.dll”错误,msvcp110.dll丢失要怎样才能修复
今天,我将为大家分享关于电脑提示msvcp110.dll丢失的3种修复方法。希望这些方法能帮助到正在遇到这个问题的朋友们。 首先,我们来了解一下msvcp110.dll文件的作用。msvcp110.dll是Microsoft Visual C 2010 Redistributable Package的一部分,…...

激活函数总结(二十):激活函数补充(SQNL、PLU)
激活函数总结(二十):激活函数补充 1 引言2 激活函数2.1 Square nonlinearity (SQNL)激活函数2.2 Piecewise Linear Unit (PLU)激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PR…...
Docker【部署 04】Docker Compose下载安装及实例Milvus Docker compose(CPU)使用说明分享
Docker Compose 下载安装使用说明 1.Compose说明1.1 Overview of installing Docker Compose1.2 Installation scenarios1.2.1 Scenario one: Install Docker Desktop1.2.2 Scenario two: Install the Compose plugin1.2.3 Scenario three: Install the Compose standalone 2.C…...
23种设计模式-7种结构模式
结构型模式简述 把类或对象结合在一起形成一个更大的结构。 装饰器模式:动态的给对象添加新的功能。 代理模式:为其它对象提供一个代理以便控制这个对象的访问。 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变…...

大数据Flink(六十七):SQL Table 简介及运行环境
文章目录 SQL & Table 简介及运行环境 一、简介 二、案例...
WPF使用依赖注入
现在依赖注入在.Net里面已经普及,自己常写一些简单的demo倒是无所谓,但偶尔写一点正式的工程,也免不了要使用一下,于是总结了一下在WPF里面使用依赖注入。 在写简单Demo时候,通常是在MainWindow的构造函数里面直接做初…...

玩转科技|了解AI平台桌面客户端—ChatBox
目录 前言 特性 编辑 为什么需要 ChatBox? ChatGPT Plus 平替? 下载 支持系统 功能图 使用教程 感受 展示 前言 今天小编又来了,推荐给大家一款开源的OpenAI API桌面客户端ChatBox,它支持 Windows、Mac 和 Linux。…...

visual studio 2022.NET Core 3.1 未显示在目标框架下拉列表中
问题描述 在Visual Studio 2022我已经安装了 .NET core 3.1 并验证可以运行 .NET core 3.1 应用程序,但当创建一个新项目时,目标框架的下拉列表只允许 .NET 6.0和7.0。而我在之前用的 Visual Studio 2019,可以正确地添加 .NET 核心项目。 …...

人工智能项目集合推荐(数据集 模型训练 C++和Android部署)
人工智能项目集合推荐(数据集 模型训练 C和Android部署) 目录 人工智能项目集合推荐(数据集 模型训练 C和Android部署) 1.三维重建项目集合 ★双目三维重建 ★结构光三维重建 2.AI CV项目集合 ★人脸检测和人体检测 ★人体姿态估计(人体关键点检测) ★头部朝向估计 …...
C# 服务HTTPS 对 请求被中止: 未能创建 SSL/TLS 安全通道报错
1.如果windows支持HTTPS的TLS协议,则可以直接跳过 (Tls12) [WebMethod(Description "获取HttpsPost加密服务.")] public string HTTPSPOST(String input,String sUrl) { Log.Add("ReceiveNotice", &qu…...

二级MySQL(七)——表格数据修改
1、修改表格中部分数据 将表格某一行的数据修改,这里用的UPDATE语句: UPDATE tb_student SET studentName 黄涛,native湖北,nation汉 WHERE studentNo 2014210103; 结果: 2、修改表格某一列全部数据 比如性别全部设置为‘女’ UPDATE…...
【日常积累】Linux下sftp搭建
概述 SFTP是Secure File Transfer Protocol的缩写,是安全文件传送协议。可以为传输文件提供一种安全的加密方法。跟ftp几乎语法功能一样。 SFTP是SSH的一部分,是一种传输档案至Blogger伺服器的安全方式。它本身没有单独的守护进程,必须使用s…...
【深入浅出C#】章节 9: C#高级主题:多线程编程和并发处理
多线程编程和并发处理的重要性和背景 在计算机科学领域,多线程编程和并发处理是一种关键技术,旨在充分利用现代计算机系统中的多核处理器和多任务能力。随着计算机硬件的发展,单一的中央处理单元(CPU)已经不再是主流&a…...
Windows Server服务器安全加固基线配置
一、账户管理、认证授权 一、账户 1、管理缺省账户 安全基线项说明:对于管理员账号,要求更改缺省账户名称;禁用Guest(来宾)账户。 操作步骤:进入控制面板-->管理工具-->计算机管理,在系统工具-->本地用户和组…...
基于NXP i.MX 6ULL核心板的物联网模块开发案例(4)
目录 5 4G模块测试 5.1 网络功能测试 5.2 短信功能测试 5.3 通话功能测试 5.4 GPS定位功能测试 5.5 程序编译 前言 本文主要介绍基于创龙科技TLIMX6U-EVM评估板的物联网模块开发案例,适用开发环境: Windows开发环境:Windows 7 64bit、Windows 10 64bit 虚拟机:VMware15.…...
英语——强调
强调句是英语中常用的一个重点句型,其基本结构是:It+be+被强调部分+that+句子其余部分。 第一节 强调句的基本用法 一、被强调的句子成分 在强调句型中,能够被强调的句子成分通常为主语、宾语、状语等,不能用来强调谓语动词、表语、补语、让步状语、条件状语等。当被强调…...

全流程R语言Meta分析核心技术教程
详情点击链接:全流程R语言Meta分析核心技术教程 一,Meta分析的选题与检索 1、Meta分析的选题与文献检索 1)什么是Meta分析? 2)Meta分析的选题策略 3)精确检索策略,如何检索全、检索准 4)文献的管理与清洗,如何制定文…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...

2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...