编辑
2023-12-02
后端
00
go
package main import ( "fmt" "reflect" )
编辑
2023-12-02
后端
00

今天水群看到个奇怪的需求,要求用go去查数据库,需求就是用户执行任意sql然后把对应数据查询出来用表的形式展示,表类型,字段数量和类型都是不确定的,这种需求用动态语言python很容易实现,用go的话,有点麻烦也不太难,有同学说了动态增加结构体字段,这样的话好像不行。go也没有tuple这种类型就是说,但是可以用[]interface{}来模拟一下,再结合反射,就好了

go底层一般都是database/sql这个结构去操作mysql的,提供的接口是db.Query,看一下

编辑
2023-12-02
算法题
00
编辑
2023-12-02
JVM
00

JVM的内存分配器和内存分配机制是指在Java虚拟机中,如何为对象分配内存空间以及如何管理和回收这些内存空间的过程。

编辑
2023-12-01
linux
00

分段机制

linux规划进程空间使用分段的方法,我们来试试分段

image.png 分段机制下的虚拟地址由两部分组成,段选择子和段内偏移量。段选择子就保存在前面讲过的段寄存器里面。段选择子里面最重要的是段号,用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。虚拟地址中的段内偏移量应该位于 0 和段界限之间。如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。

例如,我们将上面的虚拟空间分成以下 4 个段,用 0~3 来编号。每个段在段表中有一个项,在物理空间中,段的排列如下图的右边所示。

image.png

在 Linux 里面,段表全称段描述符表(segment descriptors),放在全局描述符表 GDT(Global Descriptor Table)里面,会有下面的宏来初始化段描述符表里面的表项。

c
#define GDT_ENTRY_INIT(flags, base, limit) \ { \ .limit0 = (u16) (limit), \ .limit1 = ((limit) >> 16) & 0x0F, \ .base0 = (u16) (base), \ .base1 = ((base) >> 16) & 0xFF, \ .base2 = ((base) >> 24) & 0xFF, \ .type = (flags & 0x0f), \ .s = (flags >> 4) & 0x01, \ .dpl = (flags >> 5) & 0x03, \ .p = (flags >> 7) & 0x01, \ .avl = (flags >> 12) & 0x01, \ .l = (flags >> 13) & 0x01, \ .d = (flags >> 14) & 0x01, \ .g = (flags >> 15) & 0x01, \ }

通过分析,我们发现,所有的段的起始地址都是一样的,都是 0。这算哪门子分段嘛!所以,在 Linux 操作系统中,并没有使用到全部的分段功能。那分段是不是完全没有用处呢?分段可以做权限审核,例如用户态 DPL 是 3,内核态 DPL 是 0。当用户态试图访问内核态的时候,会因为权限不足而报错。

其实 Linux 倾向于另外一种从虚拟地址到物理地址的转换方式,称为分页(Paging)。

分页机制

Linux的页表机制是虚拟内存管理的核心部分,它负责将虚拟地址转换为物理地址。下面将详细介绍Linux的页表机制。

一、概述 Linux使用了分页机制来管理虚拟内存,将虚拟地址空间划分为固定大小的页,通常为4KB。每个进程都有自己的页表,用于将虚拟地址映射到物理地址。

对于物理内存,操作系统把它分成一块一块大小相同的页,这样更方便管理,例如有的内存页面长时间不用了,可以暂时写到硬盘上,称为换出。一旦需要的时候,再加载进来,叫作换入。这样可以扩大可用物理内存的大小,提高物理内存的利用率。