自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(32)
  • 收藏
  • 关注

原创 Golang--垃圾回收

再进行GC时由于黑色对象A不会再被扫描,其引用的白色对象B就会被当为垃圾被清理,导致A找不到B。将堆内存分为From、To两部分,程序执行时使用From空间,垃圾回收时扫描From空间将能追踪到的数据给复制到To空间,回收全部的From空间,From和To交换。在函数返回后,该函数调用栈会被销毁,一些不能在编译阶段就确定大小的对象、或生命周期超出当前所在函数的对象就不适合分配在栈上,需要分配在堆上。为每一个对象维护一个引用计数,每当引用该对象的对象被销毁,引用计数就减1,引用计数器为0则回收该对象。

2026-03-22 03:22:08 253

原创 Golang--内存管理

简单的内存管理思路堆内存管理主要就是做三件事:分配内存块、组织内存块、回收内存块。分配每次申请堆内存都从未分配内存中分割出一个小内存块,然后将所有内存块使用链表组织起来。同时需要一些信息来描述每个内存块基本信息,如:大小、是否被使用、下一个内存块地址等…这是一张图片,ocr 内容为:一个内存块包含3类信息:元数据、用户数据、对齐字段。这是一张图片,ocr 内容为:释放把需要释放的内存块从链表中取出来,标记为未使用。

2026-03-22 03:21:06 293

原创 Golang--协程调度

这是一张图片,ocr 内容为:虚拟地址空间 GO 栈 MO ALLP[0] G0 STACK GO三&GO STACK.HI RUNG[256JGUINTPTR STACK.LO CURG&GO M *M &MO M & &MO RUNTIME.P RUNTIME.M RUNTIME.G GO, MO ,SCHED 数据段 ALLGS,ALLM,ALLP SCHED MAINMAIN MIDLE 代码段 RUNTIME.MAIN PIDLE 程序入口 RUNG RUNTIME.SCHEDT。

2026-03-16 12:06:50 478 4

原创 Golang--锁

原子操作是一种硬件层面加锁的机制,其可以保证一个协程操作一个变量时,其他协程/线程不能访问,但也仅限于对简单变量的简单操作。Go的atomic包来提供多种原子操作,达到并发安全。

2026-03-16 12:04:55 401

原创 Golang--多种数据结构详解

在Golang中,没有类的概念。故,所有提供给我们使用的结构如切片slice、map等_本质上都是封装好的结构体将这些数据结构看作是我们自己在代码中实现的结构体就可以很好理解其各种操作的原理。

2026-03-14 14:52:47 402

原创 Golang--多种控制结构详解

defer用于延迟函数的调用,每次defer都会把一个函数压入栈内,函数返回前再把延迟的函数取出并执行。defer规则defer的行为规则只有3条:延迟函数的参数在defer语句出现时就已经确定。最终打印0。延迟函数执行按后进先出的顺序执行,即先出现的defer最后执行。延迟函数可能操作主函数的具名返回值。return不是一个原子的过程,函数返回过程:将值存入栈中作为返回值->执行defer的函数->执行跳转。defer实现原理。

2026-03-14 14:52:15 422

原创 C++模版-函数模版,类模版基础

return a-b;

2026-03-13 15:03:45 238

原创 C++基础-类、对象

C++11中,基本类型成员变量可以在类中声明时给默认值。声明定义都在类中成员函数如果在类中定义,编译器可能会默认将其当成内联函数处理。类声明在.h文件中,成员函数定义在.cpp文件中.person.hpublic:private:int _age;person.cpp//在类外定义成员时,需要使用::指明成员属于哪个类域。

2026-03-13 15:02:44 345

原创 C++对象模型-函数

但是在虚继承,并菱形继承的情况下,多个直接继承的父类的赋值拷贝中都调用了虚基类的赋值拷贝,则会出现多次对虚基类子对象进行赋值拷贝的情况。或者说,当前调用的构造函数是在构造一个完整的对象时,虚基类的构造才会被调用,若是构造的只是某个完整对象中的子对象,则不会被调用。析构函数与构造函数类型,其也并不是在没有显式定义情况下就一定合成默认的,在必要情况下如:类内的自定义成员包含显式的析构函数、继承的父类包含显式的析构函数,才会合成一个默认的析构函数。,找到即停止,没找到则继续去上一级基类的类作用域中查找。

2026-03-12 15:06:31 212

原创 C++对象模型-对象存储,数据成员

或者可以这样理解,我们将继承来的父类子对象也看似该子类对象的成员的话,vptr其为绝对第一声明的成员变量。若当前对象是一个虚拟继承的子类对象,当存取从虚基类继承来的成员变量时,可能会延迟到运行时从虚基表中查询偏移量。布局上,按照继承的声明顺序排列,先声明的在低地址,父类对象排完了之后,才是当前对象的自己的成员。同一类内的非静态数据成员,在对象模型的布局中,根据声明顺序由低到高排列,无关何种访问控制符。p1,p2都为A1类型的指针,但是p1指向一个A1类型的对象,p2指向一个A2类型的对象。

2026-03-12 15:05:44 268

原创 C++新特性-列表初始化

C++11标准引入,扩大了用大括号括起的列表{元素1,元素2,...}的使用范围,使其可用于所有的内置类型和用户自定义的类型。可通过列表初始化对vector、list等容器进行初始化,而不再需要手动循环进行赋值,如:使用{}替代原本的()进行初始化,可避免歧义。如A a();是声明一个a函数,还是定义一个类型A的a对象,容易产生歧义,则可以统一使用A a{};进行初始化。struct C{}int main()// 可使用{}直接进行传参。

2026-03-11 14:36:19 70

原创 C++新特性-简化构造相关

C++11之前,C++没有提供一种复用同类型构造函数的方法,即无法让一个构造函数将初始化的一部分工作委托给同类型的另外一个构造函数。这种功能的缺失就造成了程序员不得不编写重复烦琐代码的困境。C++11标准支持了委托构造函数:某个类型的一个构造函数可以委托同类型的另一个构造函数对对象进行初始化。class Apublic:// 委托给A(int,int)进行构造private:int _a;int _b;double y_;

2026-03-11 14:35:47 238

原创 C++新特性-智能指针

智能指针基于RAII的思想设计。RAII:利用对象生命周期来控制程序资源。在对象构造时获取资源,在对象析构时释放资源,则不再需要显式释放资源,同时在对象的生命周期内,对该资源的访问始终有效。即将管理资源的责任托管给了对象。智能指针本质上就是使用对象对裸指针进行封装,在析构函数中delete该指针指向的内存,同时重载该对象的和->运算符模拟指针的操作。则在对象生命周期结束时,会自动调用其析构,即自动释放掉其管理的资源。

2026-03-09 15:28:04 253

原创 C++新特性-关键字、说明符相关

/ 此处有可能是"58"误写成58,而编译器不会给任何的错误提示。return 0;由于隐式的构造调用,func("58");被写成func(58);也并不会有任何的错误提示,使用explicit修饰A(int)则不会有相应的问题。同理,C++11中将explicit引入到了自定义类型转换中,在自定义类型转换运算符的函数前添加explicit说明符,则隐式的自定义类型转化则不被允许。

2026-03-09 15:27:12 322

原创 C++新特性-左值、右值、左值引用、右值引用

其本质是通过类型推导,若初始化源对象是左值则推导为左值引用,初始化源对象是右值则推导为右值引用。当对象B需要复制对象A时,需要为B分配对应的内存空间(主要是堆空间),再将A的内容复制到B的空间中。假如说,对象A只是一个临时对象,或者其之后将不再使用,则我们可以直接将属于A的堆空间直接移动给B,而不再需要申请并复制。使用不同类型引用操作其绑定对象时,其自描述的含义不同,或者说被赋予的权限和应当遵守的约定不同。对于右值,其本身不具有稳定的内存空间,则天生就带有可移动的性质,则可以使用右值引用绑定。

2026-03-08 14:47:25 333

原创 C语言-预处理

define源文件的任何位置都可以定义,与是否在函数内外无关。宏的作用范围,从其定义开始往后都是其有效范围。宏定义,也可使用gcc -D由编译器直接为我们定义。#undef用于取消宏预处理时,去注释和宏替换哪个先执行?int main()BSC printf("去注释先执行\n");printf("宏替换先执行\n");return 0;通过,查看test.o发现BSC后的语句保留。这是一张图片,ocr 内容为:故,去注释先执行。

2026-03-08 14:40:57 248

原创 C语言-函数栈帧、可变参数列表

首先弹出4字节数据,栈顶变化esp-4,同时将弹出的数据写入。将call的下一条指令(add)的地址压入栈中。寄存器保存着当前正在执行的指令的地址。跳转至call指令后给的地址执行。-4,再将eax的值写入。

2026-03-07 23:03:08 250

原创 C语言-指针与数组

定义数组时,其整体开辟空间,整体释放空间,而不应该将其看作一个个独立的元素。再在整体空间上,由低地址向高地址连续存储下标从小到大的元素。C语言中,函数也有地址。函数也是代码的一部分,在程序运行时也需要加载进内存以供CPU寻址访问代码。作为数组名代表了数组首元素的地址,其是一个字面常量,可直接使用该值运算。移动的步长就是其指向的数据的类型的大小。在语法上很相似,但是其寻址方案是不同的。数组元素个数也作为数组类型的一部分。多维数组在内存空间上也是线性的。但是其指向的数据的类型不同,类型的指针变量,定义在栈区。

2026-03-07 23:02:37 203

原创 C语言-多种符号介绍

->:字面字母转为换行。->:特殊引号转为字面的引号。关于回车和换行::换行,光标移动至下一行。:回车,光标回到当前行最开始。C语言中相当于执行了的功能。C99中规定,如字符称为整型字符常量,被看成是int类型。故的大小为4字节;左移:都是低位补0。右移:对于无符号类型,高位补0;有符号类型,高位补之前的符号位。运算带来的整型提升问题:cpu运算时,需要将数据从内存读取到cpu寄存器。在不同位数的计算机下,cpu寄存器大小也不同。32位计算机下,寄存器为32位。故运算char类型时,其大小为32位,即

2026-03-05 10:13:33 236

原创 C语言-多种关键字介绍

C90(C89)标准中,共有32个关键字。C99标准又新增5个。

2026-03-05 10:11:17 370

原创 Linux网络编程(6)--IO多路转接

阻塞、非阻塞、信号驱动的IO等待的时间都一样,仅IO效率上没差别。但整体上非阻塞式和信号驱动可以等的同时做一些别的事情。多路转接最高效,因为其等待的比重小了。阻塞、非阻塞、信号驱动、多路转接都参与了IO的过程,即称为同步IO。没有参与IO的两个阶段的任意一个阶段,即称为异步IO。OS的epoll模型中维护了一棵红黑树,一个就绪队列。int sock;// fd// 事件// 用于红黑树的字段node *left;// 用于就绪队列的字段node *next;node *prev;

2026-03-04 13:46:10 364

原创 Linux网络编程(5)--IP、MAC

同样当公网的响应消息经过该NAT路由器时,又会根据映射表将响应报文的(目的地址,目的端口)替换为内局域网中的(源IP,源端口)以发送给内局域网中正确的主机。内局域网使用私有IP的主机向公网网发送消息,需要经过路由器发送,NAT路由器会将该报文中的(源IP,源端口)替换为该路由器的(WAN口IP,分配的端口)。分片完全是不好的情况,对上层的TCP和UDP来说,并不关心下层的IP会不会分片,一个报文被IP拆成多个,其中只要有一个分片丢了,对端就需要重传整个报文。在局域网中,任何时刻只有一个主机发送消息。

2026-03-04 13:44:59 416

原创 Linux网络编程(4)--TCP

因为tcp保证可靠性的机制如:流量控制,超时重传等都在拥有连接信息的情况下才能更好的完成这些需求,即连接信息是tcp可靠性的数据基础,三次握手又是建立连接的基础。如果还继续重传这些报文,网络中有大量的主机,都采用这个策略,只会加重网络的故障问题。由于TCP是全双工的,A给B发送消息时,可能B也在给A发送消息,则一个报文ACK的同时可能也是携带数据的报文,故需要两套序号:序号和确认序号。拔网线,断电源:发送方知道网络异常会断开连接,但是接收方不知道,认为连接还在,会定期询问发送方,如果一直没回应就关闭连接。

2026-03-03 09:42:54 610

原创 Linux网络编程(3)--UDP

如果发送端调用一次sendto,发送100个字节,那么接收端也必须调用一次recvfrom接收100个字节,应用缓冲区接收不完的就丢弃。UDP的length字段只有16字节,故一个UDP数据报最大就64KB,如果要传大于这个大小的数据,需要应用层自己进行拆分。UDP的每次发送和读取都是一个完整的报文,上层交给UDP多长的报文,UDP都原封不动直接发送。由于在其报文格式中,端口号是16位的,故我们在调用上层系统调用时,端口号的参数为。UDP报文的前8字节为定长,故UDP报文的解包只需要去掉前8个字节就行。

2026-03-03 09:42:25 364

原创 Linux网络编程(2)--http、https

对信息使用Hash函数算法,计算出一串固定长度数据摘要,如MD5,SHA1等算法。摘要很难反推原信息,一般可用来比较两信息是否一致。https主要解决了通信中两方面的安全问题:数据监听、数据篡改。通过“使用非对称加密交换之后对称加密通信的密钥”的混合加密方式来防止数据监听,并保证了加解密的效率。通过第三方数据证书保证了数据不被中间人篡改的问题。

2026-03-02 11:40:45 328

原创 Linux网络编程(1)--网络socket套接字

两台主机之间的通信,本质是两台主机上的进程要进行通信。要进行进程间通信就先要进程看到同一份资源,即网络。故,通信就是进行IO,所有的上网行为,无非是要发送自己的数据(write)或者收到别人的数据(read)。在网络层,可使用公网IP地址在公网中标识一台唯一的主机。在传输层便采用端口号port来唯一标识一个进程,一个进程可以绑定多个端口号,但是一个端口号只能绑定一个进程(其实不够准确)。通过IP地址+port端口号,便能在全网中唯一标识一个进程。这种。

2026-03-02 11:40:21 911

原创 Linux系统编程(6)--多线程

假设一个全局变量x为1000,若线程A执行1、2步后还没来得及将数据写回就被切走,由于线程切换时,会保留其在寄存器中的上下文,则A的上下文中保存着x为999的数据等待写回内存;默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏。若一个资源的访问操作只需要一条汇编语句,则该操作可视为原子的,否则不是。由于线程切换时,会将寄存器中的自己的上下文带走,故拿到锁的线程即使在临界区中被切走,其他线程也只能看到内存中的mutex为0。

2026-02-28 11:21:04 921

原创 Linux系统编程(5)--信号

可使用kill -l命令查看信号列表。其中1-31号为普通信号、34-64为实时信号。任何信号发送的方式,都是通过OS以进程为单位,向进程发送。进程本身必对信号具有保存能力。信号保存在进程PCB中,使用一个int的32个比特位表示是否收到1-31中的某信号,1有,0没有。故,OS发送信号的本质就是OS修改PCB中的信号位图。当进程收到信号,不一定会被立即处理该信号。进程在处理信号(信号被捕捉)时,一般有三种操作(默认,自定义,忽略)。实际执行信号的处理动作称为信号递达。

2026-02-28 11:19:52 771

原创 Linux系统编程(4)--文件,基础IO

所谓的库,其本质是.o类型的可重定位目标文件的集合。为使用者提供.o作为方法的实现以供链接,提供.h文件作为方法的声明以及告诉使用者都有哪些方法,供使用者引用。将多个.o文件进行打包形成一整个库文件,方便使用者使用,则根据使用的打包工具和打包方式的不同,可分为静态库和动态库。

2026-02-27 21:18:47 245

原创 Linux系统编程(3)--程序地址空间

我们发现,父子进程在同一个地址下,读取到的数据却不同。故,我们可以确定,在语言中取得的地址并非真正内存上的物理地址,而只是虚拟地址。由于进程的独立性,以及进程之间的隔离性,从进程的视角来看,其总是独占整个系统的内存,但其实并不是。这样类似于给进程画饼的效果,便是通过程序地址空间完成的,其本质还是OS中软件形式实现的对于物理内存的抽象,称为虚拟内存。内核中,对程序地址空间的描述,通过结构体。

2026-02-27 21:18:19 760

原创 Linux系统编程(2)--进程

进程间通信一般指:进程间数据传输、资源共享、通知事件以及进程控制等。其主要用于使用多进程协同完成某种业务内容。由于进程具有独立性,想要让进程通信,OS就必须直接或者间接给通信的双方提供“内存空间”让要通信的进程可以都“看”到同一份公共的资源。则OS中不同模块提供的公共资源,便了产生不同的通信种类。SYSTEM V,更聚焦于本地通信。POSIX,可支持跨主机通信。顾名思义,共享内存就是某块专门设计用作进程间通信使用的内存,多个进程可对这同一个内存块进行操作。内核中并不只有一块共享内存。

2026-02-26 15:08:23 899

原创 Linux系统编程(1)--简单了解OS

好比在公司中,上层老板是管理者,下层员工是被管理者,而老板对公司的管理,对员工的管理,并不需要直接和员工交互(或者说咱底层员工其实见不到大老板几面😂)。” ,这样类似的多种问题,便需要操作系统(OS)来帮我们进行各种策略。内存是临时的数据存储,即断电数据丢失,硬盘是永久存储设备,但内存的读写速度比硬盘快多个数量级,这是物理层面上决定的。而要求用户直接使用系统调用及其麻烦,也就出现上层的多种工具封装了系统调用如shell(提供指令操作),c/cpp的库(提供编程操作),图形化界面等来简化用户使用OS的难度。

2026-02-26 14:59:08 711

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除