当前位置: 首页 > backend >正文

[杂学笔记]浏览器多进程与多线程架构、wstring类型、哈希表、红黑树与哈希表的对比、C++标准库Random类

目录

1. 浏览器多进程与多线程架构

2. wstring类型

3. 哈希表

4. 红黑树与哈希表的对比

5. C++标准库Random类


1. 浏览器多进程与多线程架构

        现代的浏览器(如Chrome)采用的是多进程与多线程结合的架构设计的。

        多进程机制:Browser主进程用来管理界面、用户交互以及其他进程的创建和销毁等工作。Renderer渲染进程:每个标签页通常都是一个独立的进程,负责页面的解析渲染以及脚本的执行等操作。CPU进程:处理3D图形和硬件加速等。插件进程:隔离第三方插件的功能。

        优势在于:稳定,单个标签页崩溃的时候不会影响整个浏览器的运行;安全,因为进程之间的独立性,所以不同服务之间无法随意的互相访问数据,防止恶意代码的数据窃取;

        多线程机制: 每个进程内部有包含多个线程共同完成任务,例如渲染进程中:GUI渲染线程:解析HTML/CSS、布局和绘制等操作;JS引擎线程:执行JavaScript代码;事件触发线程:管理事件队列(如点击、定时器等);异步HTTP线程:处理网络请求

        优势在于:响应速度块,异步任务不阻塞主线程;高效渲染,多线程并行处理DOM构建以及样式的计算等。

        通俗来讲浏览器就像是一个工厂,工厂里面有很多小车间,也就是一个个的进程,每一个车间里面还有很多员工,也就是一个个的线程,进程分工合作。

        这样的好处在于:一个车间坏了,其他车间继续照样工作。例如:某个网页卡死了,不会影响其他网页继续操作;工人各司其职,避免打架竞争工作。例如:UI工人绘制网页、JS工人执行JS代码、网络工人:下载网络资源,不阻塞页面加载。这样的话就可以实现,页面先绘制加载出来,对于图片、视频等资源,用户可以一边浏览,网页一边加载;安全又高效,不同网页之间数据隔离,同时可以充分使用CPU多核心资源。

        总结来说就是:多进程保安全、多线程提速度。

2. wstring类型

        wstring和string类型的语法,操作逻辑基本上没有什么区别,他是一种宽字符的字符串,每个字符的类型是wchar_t类型,大小根据不同的平台下有所差异,但基本上都是2byte。在存储汉字、日文等多字节的文字的时候,使用wstring类型会比较方便,因为string类型是单字节字符串存储容器,对于多字节无法很好的处理,例如提取单个汉字等操作就无法实现。所以wstring可以很好的对多字节的文字进行字符界别的处理了。

        无论是英语、中文还是其他文字都是一样的,底层都是二进制数据,为什么不能通过改变解析string内部存放的数据格式的方式,来提取出来一个个的单字符呢?因为string是单字节容器,他所有的机制都是用来处理单字节的字符,例如字符串大小字段、迭代器遍历方式等。也不是不可以,但是靠string是完成不了的,需要我们手动的去实现了。

        优势:支持多语言字符集的存储,特别是在处理费ASCII字符表中的字符时,能避免字符编码问题和乱码的现象。

        劣势:也很明显,存储的是宽字符,所以说占用的空间就会多一些;数据一大,内存分配和拷贝等操作就会降低操作性能;而且跨平台的兼容性较差,需要考虑字符编码的问题。

        使用场景:当一个程序需要同时接收和处理多语言文本内容的时候,可以考虑使用wstring类型作为存储文本存储容器;本地的操作系统上的文件名以及路径上可能会携带非ASCII的字符,可以使用wsrting类型作为文件名类型;总结来说就是处理多语言的时候,或者要对非ASCII的字符进行单个字符操作的时候,可以考虑使用wstring类型。

3. 哈希表

        哈希表是用来存储映射关系的数据结构,根据关键值key,经过哈希函数映射到数据结构的某个特定位置来进行访问value值,通过这种方式可以加快查找的速度。

        但是会有哈希冲突问题,可能两个value值是不一样的,但是通过哈希函数的计算却映射到了相同的位置。

  • 开放寻址法:线性探测(从映射位置向后遍历式的寻找)、二次探测(以n^2的形式向前后依次寻找,n的取值为1,-1,2,-2……)

  • 再散列法:设计多个哈希函数,当发生冲突的时候,用其他的哈希函数再去重新计算映射位置,但是这样增加了计算的时间。

  • 链地址法:将哈希表中的每一个位置设计为链表。

  • 建立公共溢出区域:当发生冲突的时候,将元素存入公共溢出区域。

        哈希表会有一个变量是负载因子,也就是当前存放元素的个数/哈希表的容量,如果突破特定值的时候,就代表哈希表中的元素过多了,那么哈希冲突的概率就会非常大,那么无论是插入还是查找的时候,都会影响效率,所以会进行扩容操作,将哈希表的元素,重新映射到新的哈希表的指定位置。负载因子越小,哈希表的性能越好,但空间利用率越低;负载因子越大,哈希表的空间利用率越高,但性能可能降低。

        哈希表通常存放的都是kv结构的值,但是在判断一个元素是否存在的场景下或者该元素出现的次数等问题的话,在元素量少、且没有哈希冲突的情况下,可以只存放value值。例如判断一个字符串中出现了哪些小写字符。这样只需要开一个26大小的空间即可,而且不会出现哈希冲突问题。

4. 红黑树与哈希表的对比

  • 插入和删除:红黑树需要保证元素的顺序性,所以在插入和删除的时候,可能会触发二叉树的自旋,所以插入和删除的时间复杂度是O(logN),而哈希表不需要考虑这些,插入和删除的时候可能会有哈希冲突的问题,所以插入和删除的效率是常数级别。 但是在插入的时候,如果说触发了哈希表的扩容的话,那效率就会非常差了,但是哈希表的扩容通常是二倍或者其他机制,但是每当扩容一次之后,想要在触发扩容就会更难一些,所以通常情况下也不会扩容太多次的。

  • 查找:红黑树的查找效率是O(logN),哈希表的查找效率还是常数级别的。

  • 内存方面:红黑树在插入节点的时候,只需要创建一节点空间就可以,不需要修改其他元素的内存位置。而哈希表需要通过扩容机制,在扩容的时候需要将所有的节点重新映射。而且哈希表会存放空间浪费的问题,具体取决于负载因子。

  • 有序性、哈希冲突问题

        红黑树适用于需要较高的查找效率,而且需要保持数据有序,需要进行有序遍历、范围查找的场景。例如:进程调度的优先级管理、内存地址管理、文件系统管理等。哈希表适用于需要极致的查找效率,不关心元素的插入是顺序。例如:字典、集合等场景。

5. C++标准库Random类

        C++11引入了Random生成随机数的类,该类有两个核心组件构成,一个是随机数引擎类,另一个是随机数分布类。

随机数引擎类:

        是可以独立运行的随机数发生器,他会生成某一类型的随机数,但无法指定随机数的范围,通常是不单独使用的。

  • std::mt19937:基于梅森旋转算法,数值在2^19937-1的范围内,适合通用的场景。

  • std::mt19937_64:64位版本下的梅森旋转算法。

  • std::liner_congruential_engine:线性同余生成器,性能高但随机性比较弱。

  • 其他......

随机数分布类:

        是一个需要基于随机数引擎类才能运行的类,他可以根据用户的需求,选择随机数引擎生成的符合条件的随机数进行返回。

  • 均匀分布

    std::uniform_int_distribution<int> int_dist(1, 100); // [1,100]整数均匀分布
    std::uniform_real_distribution<double> real_dist(0.0, 1.0); // [0,1)浮点均匀分布// 第一个函数只能传递int、long等整型模板,第二个函数只能传递float、double等模板
  • 正太分布

    std::normal_distribution<double> norm_dist(0.0, 1.0); // 均值0,标准差1
  • 其他......

随机数种子:        

        随机数引擎类在设置种子的适合,推荐使用std::random_device,该类是C++标准库中用于生成真随机数的生成器,其随机性的依据是物理事物,如硬件噪声、系统中断等生成的随机数,该种子具有不可预测性和唯一性。

使用案例:

#include <iostream>
#include <random>int main()
{std::random_device rd;                             // 随机数种子std::mt19937 gen(rd());                            // 以rd作为种子初始化随机数生成器std::uniform_int_distribution<int> dist(0, 9);     // 设置生成的随机数的范围for (int i = 0; i < 10; i++){// dist只是一个随机数分布类,在获取数据的适合要依靠随机数生成器才可以std::cout << dist(gen) << std::endl;}return 0;
}

http://www.xdnf.cn/news/7792.html

相关文章:

  • 影响镍钯金PCB表面处理价格的因素有哪些?
  • Spring事务简单操作
  • 【低代码】如何使用明道云调用 Flask 视图函数并传参(POST 方法实践)
  • vue-cli 构建打包优化(JeecgBoot-Vue2 配置优化篇)
  • Hadoop-HA高可用集群启动nameNode莫名挂掉,排错解决
  • digitalworld.local: FALL靶场
  • Mysql-数据闪回工具MyFlash
  • SQL查询, 响应体临时字段报: Unknown column ‘data_json_map‘ in ‘field list‘
  • leetcode 92. Reverse Linked List II
  • 张 Prompt Tuning--中文数据准确率提升:理性与冲动识别新突破
  • 分类算法 Kmeans、KNN、Meanshift 实战
  • maven之pom.xml
  • 【25软考网工】第七章(3) UOS Linux防火墙配置和Web应用服务配置
  • OpenHarmony外设驱动使用 (九),Pin_auth
  • 国产化Excel处理组件Spire.XLS for .NET系列教程:通过 C# 将 TXT 文本转换为 Excel 表格
  • 物业后勤小程序源码介绍
  • 【项目记录】准备工作及查询部门
  • python-leetcode 71.每日温度
  • Vue 3.0中核心的Composition API
  • 打造一个支持MySQL查询的MCP同步插件:Java实现
  • PCB智能报价系统——————仙盟创梦IDE
  • Python实例题:PyOt实现简易浏览器
  • leetcode字符串篇【公共前缀】:14-最长公共前缀
  • C语言-9.指针
  • “交互式“ PDF 与“静态“ PDF 表单的区别
  • liinux系统安装Helm
  • 系统数据对接-从获取到处理的全流程
  • PH热榜 | 2025-05-20
  • Ubuntu24.04安装Dify
  • YOLO中model.predict方法返回内容Results详解