Golang Slice、String and Arrary
之前面腾讯的时候问到 Slice 把我问懵了,还是太菜了,只是简单的了解了一下 Slice 的底层结构,但是经不起深挖,基础有点太弱了。 String底层结构一个字符串是一个不可改变的字节序列,字符串通常是用来包含人类可读的文本数据。和数组不同的是,字符串的元素不可修改,是一个只读的字节数组。每个字符串的长度虽然也是固定的,但是字符串的长度并不是字符串类型的一部分。由于 Go 语言的源代码要求是 UTF8 编码,导致 Go 源代码中出现的字符串面值常量一般也是 UTF8 编码的。 源代码中的文本字符串通常被解释为采用 UTF8 编码的 Unicode 码点(rune)序列。因为字节序列对应的是只读的字节序列,因此字符串可以包含任意的数据,包括 byte 值 0。我们也可以用字符串表示 GBK 等非 UTF8 编码的数据,不过这种时候将字符串看作是一个只读的二进制数组更准确,因为 for range 等语法并不能支持非 UTF8 编码的字符串的遍历。 Golang 中 String 的定义如下(reflect.StringHeader)在 Go 1.20 之后就被废弃了,因为...
Lock
Golang 锁的机制在说锁的时候主要是有两种锁,一类是乐观锁,还有一类是悲观锁。 悲观锁:默认 数据冲突时常发生 ,所以在操作之前就加锁,阻止其他线程同时访问该资源。常见场景是写多读少的情况,对数据一致性要求比较高的情况。 乐观锁:默认 数据冲突不常发生 ,所有直接操作,最后再通过版本号 / CAS 验证是否冲突,如果冲突了再重试。一般是适用于写少读少的情况,在线文档就是一种很好的案例。 我之前背八股文的时候认为 CAS 和 版本号机制是一种东西,但是好像不是那么一样。本质上,版本号机制是对于 CAS 机制的补充,是为了解决 ABA 问题。 CAS(compare and swap)CAS(比较并交换)是一种原子操作,在这个机制中有三个参数: 1. 主内存中存放的共享变量的值:V(一般来说都是内存的地址,通过这个地址可以获得对应的值) 2. 工作内存中共享变量的副本值,也叫做预期值:A 3....
hexo 图片无法正常显示解决办法
由于之前的文章都是写在 obsidian 的,虽然 obsidian 好用,但是还是想传到博客上面去,但是迁移的过程有点麻烦了。主要的问题就是 hexo 的图片问题。 图片可以在我的 cursor 里面正常预览,但是呢,我进行 hexo clean & hexo g & hexo s...
docker desktop 安装到 E 盘
安装由于一般来说,docker的安装路径一般是默认: Docker安装路径一般为 C:\Program Files\Docker,如果该路径有文件需要先删除。 本地镜像安装路径一般为 C:\Users\用户名\AppData\Local\Docker ,如果该路径有文件需要先删除下面是提供的两种有效的方法解决默认安装路径 方案一 ——软链接 1、软链接:linux中是存在有软链接这种机制的,软链接是一个指向另一个文件或目录的引用,类似于[Windows系统]中的快捷方式。如果文件移动或者被删除,那么软链接就失效2、硬链接:相较于软链接而言,硬链接就是创建文件的副本,如果文件移动或者删除,磁盘中还是存在有这文件的备份 Windows中是存在有这种机制的,我们可以在C盘中创建文件的软链接实现数据移动到其他盘 步骤1) 找到Docker原始安装路径与本地镜像安装路径 Docker安装路径一般为 C:\Program Files\Docker,如果该路径有文件需要先删除。 本地镜像安装路径一般为 C:\Users\用户名\AppData\Local\Docker...
docker 基本知识
docker 优势 对于传统虚拟机,有以下几个缺点: 1. 资源占用多,虚拟机启动的时候会独自启动一部分内存和部分磁盘,导致虚拟机运行的时候这些资源无法被其他程序占用,导致资源浪费 2. 虚拟机的启动慢 3. 冗余步骤多 docker的基本思想docker的基本思想是将软件以及相关关联的Lib打包在一起,做为一个容器,他们共享一个内核,相较于传统的虚拟机,简洁很多,简要图如下 docker的基本组成 镜像(Image):docker镜像就好比一个模板,我们可以通过这个模板来创建容器服务,tomcat镜像===>run==>tomcat01 容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。 容器(container):docker利用容器技术,独立运行一个或者一组应用 通过镜像来创建,启动,停止,删除,基本命令! 目前就可以把这个容器理解为就是一个简易的linux系统。 仓库(repository):仓库就是存放...
MIT 6.824
公开课课程网页:MIT6.824 Spring 2025 Lab1 MapReducemapreduce 是 google 提出的一种分布式模型,用于大规模的数据并行处理,核心思路就是 map 和 reduce 两个阶段,分别对应的是分片处理和汇总聚合。(简单来说就是拆分大问题,合并小问题)。 Papar这是 MapReduce 的论文 rfeet.qrk,其中主要的思想就是下面这张图 实现方案The design of a practical system for fault-tolerant virtual machines 主要的实现部分是在 src/mr中则介绍相关部分 coordinator.go实现流程主要是 MakeCoordinator() 对 master 结点进行相关初始化,另外这里我在这了解到 golang 的生命周期以及衍生的逃逸分析问题 Register() 这部分是接收来自 worker 节点的信息,每当有新的 worker 节点来的时候进行注册,为其分配相关的 ID,方便后面进行任务的申请 AssignTask() 此函数是接收...
Virtual Memory
虚拟内存(Virtual Memory) 是计算机系统内存管理非常重要的一个技术,本质上来说它只是逻辑存在的,是一个假想出来的内存空间,主要作用是作为进程访问主存(物理内存)的桥梁并简化内存管理。 物理地址:是真正的物理地址,内存地址寄存器中的地址。虚拟地址:程序访问的是这个地址。通过 MMU 将虚拟地址转换为物理地址后,再通过总线传到物理内存设备,进而完成相应的物理内存读写请求。 虚拟地址翻译为物理地址机制分段机制分段机制(Segmentation) 以段(一段 连续 的物理内存)的形式管理/分配物理内存。应用程序的虚拟地址空间被分为大小不等的段,段是有实际意义的,每个段定义了一组逻辑信息,例如有主程序段 MAIN、子程序段 X、数据段 D 及栈段 S 等。 简单来说,就是通过段表来进行映射虚拟地址和物理地址,包含: 段号:标识着该虚拟地址属于整个虚拟地址空间中的哪一个段。 段内偏移量:相对于该段起始地址的偏移量。 翻译过程就是: MMU...
Memory
TLB32 位的操作系统的寻址范围为 4G,64的操作系统用户空间和内核空间寻址范围为 128T 用户空间包含有五个部分,分别是 只读段,包含代码和常量 数据段,包括全局变量 堆,包括动态分配的内存,从低地址开始向上增长 文件映射段,包括动态库、共享内存等,从高地址开始向下增长 栈,包括局部变量和函数调用的上下文。栈的大小一般是固定的,一般是 8MB 每个进程都有自己的页表,记录相关的映射关系,大小一般是 4KB 虚拟内存向物理内存映射的关系图是: 其中 MMU(Memory Management Unit)是一种硬件模块,用于在 CPU和内存之间实现虚拟内存管理。 其主要功能是将虚拟地址转换为物理地址,同时提供访问权限的控制和缓存管理等功能。 放在整个大系统多核架构里面,每个处理器内置了MMU模块,MMU模块包含了 TLB 和TWU两个子模块。 为了加速内存映射,操作系统会将 TLB(Translation Lookaside Buffer)作为 MMU 页表中的高速缓存,进而提高 CPU 的内存访问性能 因此CPU读取数据的过程如图: Page...
Process and Thread
Process进程(process),指的是计算机中运行的一个实例。 进程是操作系统中最小的资源分配单元,接收来自 CPU 的调度。 PCB (Process Control Block)系统中每个进程都有一个相应的 PCB,其中包含与其执行、资源需求和状态相关的信息 主要结构如下: 进程 ID:PID 为 0 的是调度进程,是内核中的一部分,也称为系统进程;PID 为 1 的是 init 进程,是一个拥有超级用户权限的的用户进程;PID 为 2 的进程是页守护进程,负责支持虚拟储存系统的的分页操作。 程序计数器:跟踪下一条要执行的指令的地址 CPU 寄存器:储存CPU 寄存器的值进行上下文切换 进程状态 内存管理信息:跟踪分配给进程的内存 IO Status:指示当前分给进程的相关IO设备 会记信息:记录资源使用情况、执行时间和其他统计数据 相关状态 new:创建进程 ready:进程已处于准备运行状态,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行。 running:进程正在处理器上运行(单核 CPU...
GMP
GMP调度器 深入分析Go1.18 GMP调度器底层原理 总述 以下这部分是直接截取的腾讯技术工程的帖子中的内容。 为了解决 Go 早期多线程 M 对应多协程 G 调度器的全局锁、中心化状态带来的锁竞争导致的性能下降等问题,Go 开发者引入了处理器 P 结构,形成了当前经典的 GMP 调度模型; Go 调度器是指:运行时在用户态提供的多个函数组成的一种机制,目的是高效地调度 G 到 M上去执行; Go 调度器的核心思想是:尽可能复用线程 M,避免频繁的线程创建和销毁;利用多核并行能力,限制同时运行(不包含阻塞)的 M 线程数 等于 CPU 的核心数目; Work Stealing 任务窃取机制,M 可以从其他 M 绑定的 P 的运行队列偷取 G 执行;Hand Off 交接机制,为了提高效率,M 阻塞时,会将 M 上 P 的运行队列交给其他 M 执行;基于协作的抢占机制,为了保证公平性和防止 Goroutine 饥饿问题,Go 程序会保证每个 G 运行 10ms 就让出 M,交给其他 G 去执行,这个 G 运行 10ms 就让出 M 的机制,是由单独的系统监控线程通过...
