- 博客(155)
- 收藏
- 关注
原创 面经——中国科学院软件研究所C++一面
7.C/C++中,指针很灵活,有没有遇到指针方面的问题,怎么解决的。5.在学习过程中,有需要什么有技术含量的问题么?6.Linux查看磁盘占用情况的命令。3.项目中遇到那些问题,怎么解决的。
2025-10-20 16:28:29
95
原创 面经:冰川网络游戏服务器开发——C++一面
5.hashmap中存放大量游戏数据,现在需要扩容,但直接扩容会导致卡顿,怎么处理这个卡顿。3.vector中存了100W个数组,需要将第50W个数据删除,怎么做高效。6.如果你的服务器项目突然间cpu打满了,你如果定位问题。7.1000发子弹,和50架敌机,怎么设计数据结构。4.map怎么让自定义类型做key值。一面,四十分钟左右,面试老师很友好。2.用过stl容器么。
2025-10-14 17:09:47
170
原创 MySQL存储过程
用户自定义变量,用一个@表示用户自定义变量在当前会话有效,通常用来定义一些查询的中间结果,或者表示一些条件,方面后面的查询使用在定义用户自定义变量时,既可以使用 = ,也可以使用:=,但=又可以用来作为判断等于,所以为了避免歧义,推荐使用:=如果在select后面直接使用 = 则表示比较,不是赋值。
2025-10-03 22:04:33
1030
原创 Git之远程仓库
之前我们使用的都是本地git仓库来进行管理文件的。但git其实是一个分布式版本控制器,我们之前只使用了git的版本控制功能,却没有体现出分布式!同一个git仓库,可以克隆到不同的机器上,并且每一个机器上都是一个完整的git仓库,如果两个开发人员对代码进行了修改,想要其他人看见,只需要将自己的修改提交,并推送到远程,让另一方重新拉取最新的代码即可。
2025-08-01 16:32:29
838
原创 Git之本地仓库管理
在学习工作中,我们经常会遇到改文档的场景。一个文档可能会被我们修改多次,而最终真正使用的可能是最先的几版。而如果我们直接在原文档上修改,就会导致无法找到最先的几次。这也就导致我们要对我们所有的版本进行维护,而Git就是一个版本控制器。git会为我们创建一个仓库,用来保存、管理、记录我们对各种格式资源的修改。而这个git仓库是要依托于一个目录的。
2025-07-31 21:01:55
1409
原创 项目——在线五子棋对战
点击匹配,匹配成功的玩家不会进入游戏房间,原因是在添加用户到在线管理模块时,误使用了session id每次服务器启动,同意玩家只能进行一次游戏,无法进行第二次匹配。问题在于:获取连接出错,从游戏大厅出来时并没有将连接从游戏大厅管理中删除。在本项目中,我了解到了WebSocket协议以及MySQL、json、gdb等的基本使用。了解了网络开发的基本流程,并且简单了解了怎么调式多线程以及网络代码。
2025-07-24 17:37:30
1032
原创 多路转接select、poll、epoll
select在实现多路转接的过程中,其实是完成等的工作。select替我们等待我们想要关心的文件描述符,当指定文件描述符上的指定事件就绪后,select就会返回,此时我们再读的时候就不会阻塞了。
2025-06-26 16:25:57
702
原创 5种IO模型与非阻塞IO
IO在网络通信中是并不可少的。无论是发送报文到网络中,还是从网络中接收报文,都是IO。而IO也有多种模式,如阻塞IO,非阻塞IO,异步iO等等...
2025-06-25 16:03:23
1027
原创 日志项目——性能测试
我们通过write将消息其实是写到了缓冲区中,当缓冲区满了或者什么条件满足了才会往磁盘上面进行刷新。这就导致了,同步是直接将消息写入到内核缓冲区中,而异步先写入到用户缓冲区,再写入到内核缓冲区,这样就导致效率降低了。因为异步日志会将所有的消息放入到内存中,内存可用空间会一直减少。通过统计总条数和总耗时,来计算单位时间内打印了多少条日志消息,以及单位时间内打印了多少kb的消息。需要注意的是,这里的多线程指的是生产者线程,也就是说对于异步写日志来说,只有一个消费者线程。异步单线程多线程进行性能测试。
2025-06-21 11:10:57
836
原创 日志项目——代码设计
一条日志消息需要有时间,并且日志落地的具体位置还不一定存在。所以,我们需要使用:实用类用来获取当前时间,以及创建日志落地的目录。创建路径时,需要一级一级目录的创建,有了上级目录才能创建下级目录。
2025-06-21 10:13:04
1020
原创 日志项目——日志系统框架设计
对输出日志的等级进行划分,以便于控制日志的输出(在具体项目测试时,可以打印调试日志用来debug,而当项目上线后,就不应该在打印debug日志,而只在乎致命的错误)。并且提供了将等级枚举转换成字符串的功能。有了以上几种等级,我们便可以随心设置,当我们设置等级为OFF时,所有的日志消息都无法被打印。
2025-06-04 16:21:40
609
原创 项目前置知识——不定参以及设计模式
运行结果:但是当我们只传入一个格式字符串,而没有后面的不定参,此时该宏就会出错这是因为只传入一个fmt,此时LOG会被替换成为 ->可以看到,多了一个逗号,此时printf解析时,就会出错。所以,为了避免这个问题,我们需要在使用__VA_ARGS__时前面加上##,##的作用就是在不定参为空时,删除逗号。
2025-06-03 15:17:03
993
原创 NAT、代理服务、内网穿透
NAT技术是为了解决IPv4协议中,IP地址不足的问题。NAT能够将私有IP对外通信时转为公网IP,私有IP可以重复,但在同一内网中是唯一的,而公网IP在全球内都是唯一的。我们在进行消息路由的过程中,NAT技术会将我们的源IP地址一直进行替换,当替换到出入口路由器(进入公网)之后,就不再进行替换了。并且,一个出入口路由器里面的内网环境非常复杂,里面可能包含了多个重复的内网IP,如果这些内网IP同时访问公网中的同一个服务器,那么它们源ip替换的时候,不就变成了相同的两个报文了?
2025-05-26 16:03:12
1429
原创 传输层协议TCP
TCP协议是传输层的另一个知名协议,它是面向连接、可靠的、面向字节流的一种传输层协议。TCP协议在操作系统内部,通过确认应答、超时重传、流量控制、三次握手、四次挥手等机制,解决了在网络通信时的可靠性、效率等问题。
2025-05-23 11:18:49
1349
原创 传输层协议UDP
UDP是在网络协议中传输层的一种协议。它位于操作系统内部。我们在网络基础那里了解过,UDP是一种无连接,不可靠,面向数据报的协议,其设计目标是高效传输数据,而非保证可靠性。它直接将应用层数据封装成UDP数据报发送,不建立连接,不确认数据,不重传丢失报文,适用于对实时性要求高(如直播)或数据量小(如DNS查询)的场景。
2025-05-18 22:06:44
1392
原创 应用层协议http
在互联网世界中,HTTP(HyperText Transfer Protocol,超文本传输协议)是一个至关重要的协议。它定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或传输超文本。
2025-05-17 18:36:54
1813
原创 【Linux】序列化与反序列化、会话与进程组、守护进程
协议其实就是结构化的数据。但是再网络通信中,我们不直接发送结构化的数据给对方。我们一般会将,然后通过网络在发送出去。而接收方收到之后,要对,即还原成结构化的样子。那么我们可以直接发送二进制对象么,这个结构化数据双方都能认识啊?可以,但不建议。可以是因为在操作系统内部,协议都是直接传递的结构体,因为所有的操作系统都是C语言写的。不会存在差异。不建议是因为通信双方可能是不同的语言实现的,这导致它们对结构体的对齐规则可能有差异。导致接受的数据可能不完整。
2025-05-16 18:01:38
905
原创 【Linux】网络基础与socket编程基础
协议其实就是一个结构体!!!在两个主机在进行通信的时候,其实就是A主机填充结构化数据,然后通过网络协议栈发送到网络,再通过网络发送到B主机的网卡。B主机在从底向上将该结构化数据拿出来,因为该结构体是一个协议,所以AB主机都能认识,B主机就可以拿到A主机发送的结构化数据。因为协议是分层的,所以每一层都有协议,同层之间可以认识对方的协议。
2025-05-15 21:33:22
1156
原创 【Linux】日志与策略模式、线程池
在了解了线程的基本概念和线程互斥与同步之后,我们可以以此设计一个简单的线程池。线程池也是一种池化技术。提前申请一些线程,等待有任务时就直接让线程去执行,不用再收到任务之后再创建线程。
2025-05-04 11:44:58
958
原创 【Linux】线程同步与互斥
在生产者和消费者模型中,一共有三种关系(生产-生产,消费-消费,生产-消费),两种角色(生产者和消费者,都由线程来承担),1个交易场所(1个共享的内存空间)。
2025-05-02 14:18:35
897
原创 【Linux】线程
我们可以想想之前的FILE* fp = open;打开一个文件,其实就是为我们申请了一个FILE结构体对象,充当用户级缓冲区。所以对于在库中定义了线程,可以理解为我们使用pthread_create创建一个新线程,本质上就是为我们申请了一个strcut tcb结构体对象。我们之间还说过,线程共享地址空间,但仍有自己独立的资源。比如独立的栈空间,独立的存储位置。
2025-04-27 16:51:52
760
原创 【Linux】信号
我们将1~31号信号全部都进行自定义步骤,然后借助shell脚本,向该进程发送1~31号信号,判断那些信号会被自定义捕捉,那些信号不会!std::cout << "我是" << signal << "号信号" << std::endl;int main()// 自定义捕捉所有的普通信号i<32;return 0;i=1;sleep 1;((i++));done我们看上图,9号信号和19号信号是不可以被自定义捕捉的。
2025-04-21 22:30:47
1190
原创 【Linux】进程池bug、命名管道、systemV共享内存
我们在之前进程池的创建中是通过循环创建管道,并且让子进程与父进程关闭不要的读写段以构成通信信道。但是我们这样构建的话会存在一个很深的bug。我们在销毁进程池时是先将所有的信道的写端关闭,让其子进程read返回值为0,并退出,此时我们在进行等待子进程,就完成了销毁的行为。按照我们实现的逻辑图来看,我们可以对一个信道先进行关闭在进行子进程的回收,然后再对下一个信道进行关闭操作。但是因为这个bug的存在,如果我们将关闭信道和回收子进程放在一起时,就会导致进程死循环。
2025-04-15 19:46:24
952
原创 二叉树——队列bfs专题
我们之前遇到过二叉树的层序遍历,只需要用队列先进先出的特性就可以达到层序遍历的目的。而这里不是二叉树,也就是说让节点的孩子入队列时不仅仅是左右孩子了,而是它的所有孩子。而我们看这棵多叉树的构造,它的孩子是存储在数组中的。所以我们在让孩子入队时只需要依次让数组中的所有节点入队列即可。而这道题的要求是返回一个二维数组,数组的元素就是每一层的层序遍历结果。
2025-04-06 22:04:42
630
原创 【Linux】进程间通信、匿名管道、进程池
是指在操作系统中,不同进程之间进行数据交换和同步的机制。由于每个进程通常拥有独立的内存空间,进程间无法直接访问对方的内存,因此需要通过特定的机制来实现通信和协作。
2025-04-05 22:25:17
696
原创 【Linux】ELF文件与库的加载
了解了动静态库的制作与使用后,我们直到库本质上就是.o文件的集合。我们在开发过程中,也经常将所有的源代码先编译成.o后统一进行链接,为什么不直接将所有的.c源文件编译成可执行程序呢?
2025-04-02 18:43:25
1233
原创 【Linux】动静态库的制作与使用
我们学习c/c++至今,每一次代码的编写都使用到了c/c++的标准库。库其实就是将一些常用的方法总结了起来,并进行实现,之后当我们再需要使用该方法时,就直接使用库中实现好的即可。所以,库其实就是常用方法的二进制集合。本质上,库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。静态库Linux(.a) windows(.lib)动态库Linux(.so) windows(.dll)1.动静态库中,其实根本不需要包含main函数,所有的库不论动静,本质上都是源文件对应的.o目标文件。
2025-03-31 17:00:43
861
原创 【Linux】Ext文件系统
在之前,我们已经了解了进程以及文件IO方面的知识,但是这些都是在内存中进行的。而文件在加载到内存之前都是存储在外设——磁盘(disk)中的。那文件是怎么在磁盘中存储的呢?我们在下面一起讨论。
2025-03-30 10:59:09
848
原创 【Linux】基础IO
首先我们已经知道,在Linux下,一切皆文件。文件 = 文件内容 + 文件属性,所以一个文件的内容为0kb,但是其也占磁盘空间。所以对文件的操作其实就是对文件的内容和属性进行一系列的操作。对文件操作,需要先打开文件,而打开文件的不是别人就是进程。所以对文件的操作,本质上是进程对文件操作。一个进程有可能同时会打开多个文件,且一个文件可能同时被多个进程打开。所以操作系统要对打开的文件进行管理——先描述,在组织。C语言里面的库函数fopen/fclose等文件操作的函数,本质上是对系统调用的封装。
2025-03-27 13:02:49
1167
原创 自定义minshell
我们在前面已经了解了进程的概念,以及如何进行进程控制。接下来我们就使用这些知识,来自己实现一个shell即命令行解释器!!!
2025-03-24 21:26:35
776
原创 进程控制~
我们可以通过./cmd来运行我们的程序,而我们运行的程序就是bash进程常见的子进程。当然我们也可以通过fork()系统调用来创建进程。NAMESYNOPSISfork会对子进程和父进程返回不同的返回值,对子进程返回0,对父进程返回子进程的pid,如果返回值小于0,则说明子进程创建失败。
2025-03-19 21:04:17
933
原创 栈(LIFO)算法题
注意,我们需要重复处理,而不是处理一次相邻的相同元素就结束了。对示例来说,如果只进行一次处理,结果为aaca,但是处理之后又出现了相邻的重复元素,我们还得继续处理,最后结果就是ca。解法:借助栈来模拟我们可以将字符串中的元素依次入栈,元素入栈前判断是否与栈顶元素相等,如果相等就弹出栈顶元素,继续判断下一个元素。等到字符串全部入栈,栈中的就是最终答案。但是我们没有必要弄一个stack出来,因为这样最终结果是逆序的,我们可以采用string来模拟栈的行为。
2025-03-16 22:08:23
777
原创 字符串算法题
题目要求找出所有字符串的公共前缀,如果没有公共的前缀就返回空字符串。我们以第一个字符串为标准,依次比较所有字符串的每一位,如果都相同,则比较下一个位置,如果不同,那么前一个位置就是最长的公共前缀。在纵向比较的时候要避免越界,因为第一个字符串的长度有可能比后面的字符串长,所以除了字符不相等外,i越界,也是一个判断条件。两个两个字符串进行比较,用它们得出的前缀和与第三个字符串继续比较。重复该过程。如果在某一个比较过程中发现前缀和的长度变为0,那就说明所有字符串没有公共的前缀和。
2025-03-16 20:57:40
959
原创 【Linux】进程
按课本上来说,一个正在执行的程序的实例就是一个进程;按操作系统内核来说,使用了CPU资源的实体,就是一个进程。这样说还是有点抽象。程序其实就是一个又一个的二进制文件,当它们还没有被运行时存储在磁盘中,所以我们通过./cmd的方式,将它们加载到了内存中,此时内存中就会有一份该程序的代码和数据的拷贝,那么一个程序被加载到了内存中是否就是一个进程呢?首先我们要知道的是,可能同时有多个程序被加载到了内存中如果这些都是进程的话,那么操作系统就要对这些进程管理,而操作系统对任何软硬件的管理都是先描述在组织。
2025-03-15 16:34:05
721
原创 哈希表算法题
因为数组是无序的,所以我们无法直接使用双指针。找两个数之和为target,我们可以固定一个数x,然后在其前面找有没有一个数等于target-x。如果没有,我们x就走到下一个位置。然后重复找前面有没有一个数等于target-x的过程。这个算法是否正确呢?答案是肯定的。因为如果我们从后往前看的话,就知道,其实就相当于是个反向的暴力。我们在反向遍历的过程中,一直在找该数的前面有没有target-x的这个数出现过。
2025-03-15 12:34:40
665
原创 链表算法题目
cur2指向头节点,cur1指向空,然后用cur2遍历原链表,遍历的同时,让cur2的next指向cur1,实现逆置,然后让cur1走到cur2的位置,然后cur2走到下一个位置。所以我们也要保证进位不为0。返回的过程中,将该层的head的next的next指针指向自己即head的前一个节点的next指针指向自己,此时就达到了后一个指向前一个,接着将head的next指针指向空,避免成环。简单来说,对于原链表来说,每两个一组的节点,第一个节点是新链表的第二个节点,第二个节点是新链表的头节点。
2025-03-08 21:20:39
1004
原创 【Linux】冯诺依曼体系结构-操作系统
我们所使用的计算机,如笔记本等都是按照冯诺依曼来设计的:截止目前,我们所知道的计算机都是由一个一个的硬件组装起来的,这些硬件又由于功能的不同被分为了输入设备,输出设备,存储器和cpu。:键盘,鼠标,话筒,摄像头,网卡,磁盘等等……:显示器,网卡,磁盘,打印机等等……而存储器其实就是我们所说的内存,而CPU是由运算器和控制器组成的。
2025-03-04 16:48:51
917
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅