- 博客(61)
- 收藏
- 关注
原创 初识Qt——常用控件之QWidget的属性_2
运行程序后,界面上有四个按钮,它们的focusPolicy分别被设置为Qt::StrongFocus、Qt::ClickFocus、Qt::TabFocus和Qt::NoFocus。styleSheet属性用于设置控件的样式表(QSS,Qt Style Sheets),其语法与CSS类似,可以控制控件的背景色、文字颜色、边框、圆角等外观效果。选中控件后,在属性编辑区找到styleSheet属性,点击右侧的「...」按钮,会弹出样式表编辑对话框,在其中输入QSS代码即可实时预览效果。
2026-09-22 21:00:00
143
原创 初识Qt——常用控件之QWidget属性_1
控件(Widget,也常译为"部件"或"窗口部件")是Qt中所有用户界面元素的基础。在Qt中,控件就是一个继承自QWidget的类。QWidget是所有控件的基类,它提供了:绘制自身的能力(paintEvent)处理鼠标/键盘事件的能力(mousePressEvent、keyPressEvent)管理子控件的能力(父子关系、布局)与用户交互的能力(信号槽)// 几乎所有界面元素都是 QWidget 的子类QWidget // 基类。
2026-08-18 09:00:00
218
原创 初识Qt——信号和槽
自定义槽函数其实就和自定义一个普通的函数没什么区别//widget.hQ_OBJECTpublic://自定义一个槽函数private:push->setText("按下");//使用自定义的槽函数delete ui;//设计一个弹出窗口提示,显示“按钮被按下!QMessageBox::information(this, "提示", "按钮被按下!");
2026-08-13 17:30:43
228
原创 初识Qt——创建第一个Qt项目
运行后,它会让你登录Qt账户,然后你可以按需选择安装需要的Qt版本、编译器和模块,适合网络稳定的开发者。声明一个名为Ui::Widget的类,但这个类不在当前文件中定义,它的定义在ui_widget.h中(由 UIC 编译器从.ui文件自动生成)。QWidget —— 表示一个控件.(窗口上的一个具体的元素.输入框,按钮,下拉框,单选按钮,复选按钮....)。使用QtCreator 创建项目,会自动的生成一些代码出来,生成的代码就包含一个类,此处就是要选择这个自动生成的类的父类是谁。
2026-08-12 10:50:36
209
原创 初始Qt——了解Qt背景
库是开发者的工具,是否使用以及怎样使用是开发者说了算,但是框架是在你开发前就已经写好了的,并且规定了你该怎么写,你只能在他的规则之下去开发。框架其实就相当于代码的主要骨架,大佬已经帮我们把代码的主要骨架都已经写好了,我们只需要在此基础上扩展功能,所谓是站在巨人的肩膀上了,这样我们写代码出错的可能性也会降低,提高开发效率。Qt在这些解决方案相较于其他方案是比较好用的,商业公司的产品用的比较多,不仅开发出来的程序运行效率不低而且还能够跨平台(支持Windows、Linux、Mac以及嵌入式系统)
2026-08-10 10:41:32
181
原创 UDP Socket编程的三级跳:简单到复杂的优雅过渡
本文介绍了基于UDP协议的网络编程实现,分为基础篇、进阶篇和实战篇三个部分。基础篇实现了一个简单的UDP回显服务器,详细解析了核心代码结构;进阶篇扩展为字典查询服务,增加了配置文件读取和翻译功能;实战篇构建了多线程聊天室系统,封装了网络地址类,实现了消息路由和转发功能。文章通过代码示例展示了UDP服务器的创建、绑定、收发消息等核心操作,并逐步升级功能,最终实现了一个支持多用户实时聊天的网络应用。每个部分都包含完整的代码实现和运行效果演示。
2025-12-20 13:08:28
929
原创 初识网络
当同一网段内的设备通信时,首先通过ARP协议将目标IP地址解析为对应的MAC地址,然后数据被封装成以太网帧,通过交换机基于MAC地址表进行智能转发——已知目标则定向发送,未知则广播查询,最终只有目标设备接收并处理该数据。通过定义统一的 struct sockaddr 作为API接口类型,各协议使用自己具体的结构体(如IPv4用 sockaddr_in),在函数调用时强制转换为 sockaddr* 类型,并依靠结构体首部的地址族字段来区分具体协议类型,从而实现多协议支持的统一接口。客户端使用端口号发起连接;
2025-12-09 01:53:36
819
原创 【Linux】线程池
shared_ptr大部分操作(增加引用计数,复制,读取等)都是安全的,因为它的引用计数操作是原子的,但是如果是对指针本身做修改就可能不安全;一个函数是线程安全的意味着:当多个线程同时执行这个函数时,无论操作系统如何调度这些线程,函数总能产生预期的正确结果,不会出现数据竞争、脏读、死锁等问题。A保持自身资源的同时请求B的资源,B保持自身资源的同时又请求A的资源,造成死循环。是指两个或多个进程(或线程)在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力干涉,这些进程都无法继续推进。
2025-11-28 11:30:00
1744
原创 【Linux】日志与策略模式
每次遇到<<都会循环进入<<重载函数,直到<<结束,临时变量就要被析构了,然后调用LogMessage的析构函数进行刷新策略——把前面得到的_loginfo内容通过我们激活的刷新策略刷新出来。所以可以显示当前文件(main.cc)和当前行号(9),然后进入Log类的()重载函数中,得到一个LogMessage临时变量,期间会调用LogMessage的构造函数,且进入<<重载函数中。在大型软件工程中,日志不仅仅是一个文件,它是一个完整的子系统,是系统的“神经系统”,负责将内部状态不断地反馈出来。
2025-11-24 20:45:00
772
原创 【Linux】信号量
信号量是一种用于控制多个线程/进程对共享资源访问的同步机制,本质上是一个计数器(记录了资源的剩余数量),配合两个原子操作:P 操作(等待/获取):sem_waitV 操作(发布/释放):sem_post我们申请信号量的本质其实就是预定资源,申请信号量、释放信号量的前提是要看到同一个信号量,那么信号量本身共享资源,所以PV操作必须有原子性,信号量其实就是相当于资源的锁。
2025-11-21 06:00:00
856
原创 【Linux】线程同步
当队列满时,往队列⾥存放元素的操作也会被阻塞,直到有元素被从队列中取出(以上的操作都是 基于不同的线程来说的,线程在对阻塞队列进程操作时会被阻塞)(假如顾客去超市买东西的时候刚好是供应商供货给超市的时候,而你要买的东西虽然在供应的货物里面但还没上架,那么你还是买不到你想要的东西,如果你强行拿了,可能导致超市的货物数量出错)我们前面的示例传递的是整数类型的数据,但是我们线程间通信的时候不仅可以传递整数、浮点数、字符这样的数据,还可以传递函数、类对象这样的数据,从而实现给线程派发任务的功能。
2025-11-18 05:00:00
1475
1
原创 【Linux】线程互斥
经过分析,我们能够明白,真正加锁的步骤就是xchgb,但lock的每一步都可能会切换线程,如果在xchgb执行后切换线程,锁资源会被抢夺吗?我们可以设想:假如线程A刚执行完xchgb这一步CPU就切换到线程B,那么线程A要保存自己的上下文数据(下一步要执行if语句,寄存器%al数据=1......),并且此时的mutex中的数据被交换后变成了0,所以此时线程B再执行加锁步骤时,%al寄存器和mutex中的数据都是0,则会加锁失败,直到切回线程A,才能进入if语句。这样的情况是合理的,但是导致了饥饿问题。
2025-11-16 19:59:28
959
原创 【Linux】初识线程
当进程第一次访问某个虚拟地址,但该地址对应的数据还在磁盘上(比如程序的代码段、数据段),会触发缺页异常,操作系统需要将磁盘上的对应数据加载到物理内存,建立虚拟地址到物理内存的映射;页表也是内核中的一个数据结构,本身也是要占内核空间的,如果将虚拟地址空间和物理空间按照字节单位来映射,假如内核空间为4GB,那么就是4*1024*1024*1024字节,页表每一项至少要存储虚拟地址空间地址(四字节)和物理地址(四字节),每个页表项就占8字节,整个页表要占8*4GB大小,这都超过内核空间大小了,所以这肯定不行。
2025-11-13 19:40:50
1036
原创 【Linux】信号处理
操作系统的所有活动,从进程调度到设备管理,都是由这些中断所触发。:ISR(Interrupt Service Routine中断服务程序,一个处理中断事件的函数) 一开始通常会用汇编指令继续保存所有通用寄存器的值,形成一个完整的“陷阱帧”(一个在内核栈上完整保存了被中断的任务在陷入内核前一瞬间的CPU所有寄存器值的数据结构)。时钟中断可以理解为一种固定在每个CPU核心上的“警报器”,这个警报器以固定的时间间隔(例如10ms)响一次,每次一响,CPU就必须停下手中的活,立刻去执行操作系统内核的调度代码。
2025-11-10 07:00:00
945
原创 【Linux】信号保存
在进程控制块 (task_struct) 中维护了两个位图来表示每个信号的未决(pending)和阻塞(block)状态,每个位图的比特位位置对应信号的编号(如1对应SIGHUP,2对应SIGINT),其中pending位图记录该信号是否已送达进程但尚未处理(1表示信号待处理),block位图则标识该信号是否被进程屏蔽(1表示信号被阻塞)。当信号产生时,系统会检查block位图,若未被阻塞则根据handler表中的处理方法处理信号,若被阻塞则在pending位图的对应信号位置为1,待解除阻塞后再行处理。
2025-11-06 18:20:54
894
原创 【Linux】信号产生
用一段比较官方的话来说就是:当程序执行除零、访问野指针等这类非法操作时,会触发CPU级别的硬件异常,操作系统接收到这些异常后,会向违反规则的进程发送相应的信号(如SIGFPE用于算术错误,SIGSEGV用于内存访问违规),而默认的信号处理行为就是终止进程并生成核心转储,因此程序表现为崩溃。有的时候我们是因为程序出错了导致的异常退出,程序因自身bug出错导致退出,这个时候我们通过信号可以知道出了什么错,但我们还想知道出错的位置在哪里,即。底层操作系统监控这些条件,并在条件满足时自动向进程发送相应的信号。
2025-10-31 21:01:29
466
原创 【Linux】初识进程信号
进程之所以会产生,本质上还是用户的操作导致的,因为用户想要做某些操作,所以开启了一个个进程,所以进程操作其实就是为了实现人的操作。这些信号发生的时候我们就明白应该做什么,这说明我们能够识别这些信号,而我们之所以知道这些信号代表的意思,是因为我们被教育/训练过,所以记住了这些信号的特征以及处理方法,并且在没有信号产生的时候,我们就知道这些信号应该怎么处理。从根本上说,信号是为了在一种“异步”的场景下,让一个进程知道发生了某件重要的事情,并催促它立即去处理,所以信号是由事件通知产生的。
2025-10-27 11:34:56
655
原创 【Linux】进程间通信
在 Linux 世界中,进程是资源分配和调度的基本单位。通常情况下,每个进程都拥有自己独立的虚拟地址空间,这意味着一进程无法直接访问另一个进程的数据。但现实中的复杂任务往往需要多个进程协同工作,这就引出了一个核心需求——进程间通信。本文将深入探讨 Linux 下的几种经典 IPC 机制,理解它们的目的、发展历程以及工作原理。
2025-10-25 20:43:15
916
原创 【Linux】动静态库
我们在使用ldd命令时,可以看到我们可执行程序所依赖的标准库,说明系统应该默认会去标准库路径(/lib64)下查找我们所使用到的库,那么我们想要系统或加载器能识别到我们自己的库,是不是只要把我们自己的库文件和头文件拷贝到标准路径下就可以了呢?我们通过-I、-L以及-l选项是在告诉编译器我们的库文件和头文件所在位置,我们的系统并不知道,当我们的程序编译链接形成可执行文件时,已经和编译器没有关系了,所以我们的系统去找库的时候找不到我们自己的库。结果是会报错找不到库,我们静态链接的前提是必须有静态库。
2025-10-19 12:56:06
713
原创 【Linux】动态链接和动态加载
内核:你在Shell中输入 ./my_program 后,内核的加载器首先工作。它读取ELF文件头,发现这是一个动态链接的可执行文件(因为包含INTERP 段)。内核为进程创建虚拟地址空间,并将程序本身的代码段(.text)、数据段(.data)等LOAD 段映射到内存中。内核根据INTERP 段指定的路径,将动态链接器(例如 /lib64/ld-linux-x86-64.so.2)这个特殊的共享库加载到内存。内核不执行程序的 _start,而是直接将控制权跳转到动态链接器的入口点。
2025-10-14 10:37:03
981
原创 【Linux】理解链接过程
ELF文件中的每个LOAD类型Segment(需要加载的段)在程序加载时,都会在内核中创建一个对应vm_area_struct结构体,该结构体继承了Segment的虚拟地址范围、访问权限和文件偏移等关键信息,成为该段内存在内核中的运行时管理单元。这里的两次call就是指我们调用了两次函数(printf 和 run),前面的数字e8其实就是用十六进制代表call命令,后面跟着的一串零其实应该是调用的函数地址(暂时为0),因为此时编译器是不知道函数地址的,和其他的模块链接后才知道函数地址。
2025-10-12 18:30:19
809
原创 【Linux】认识ELF格式文件
ELF(Executable and Linkable Format)是Linux系统中可执行文件(.exe)、目标文件(.o)、共享库(.a)和核心转储的标准文件格式。ELF头(ELF Header):描述文件的基本属性,如目标架构、入口地址、段头表和节头表的位置程序头表(Program Header Table):列举了所有有效的段(segments)和他们的属性。
2025-10-09 20:23:49
830
原创 Ext2文件系统
当需要读写大量连续数据时,如果数据都存储在同一个柱面上,硬盘就可以在第一个盘面读写完后,无需移动磁头臂,直接切换到第二个盘面的磁头继续读写,然后再切到第三个...这样大大减少了磁头寻道的时间,极大地提高了读写速度。有时候编译项目时,我们可能会访问几百个文件,如果我们每次访问文件都要做一次完整的路径解析,而路径解析需要读取磁盘上的目录内容,那就意味着要做很多次磁盘访问,磁盘I/O操作比内存操作慢数万倍!如果这个文件时目录文件的话,那么就存储的是目录的结构信息(即文件名到 inode 号的映射关系)。
2025-10-04 20:43:04
1059
原创 【Linux】基础 I/O
打开文件的方式不仅仅是fopen,ifstream等流式,语言层的方案,其实系统才是打开文件最底层的方案,fopen、fwrite...都是封装的系统文件。这是因为我们把1号文件描述符重定向到普通的磁盘文件中,刷新方式从行缓冲变成了全缓冲,我们写的内容肯定没有装满缓冲区,所以没有刷新,此时我们可以手动刷新一下,就可以让内容刷新出来了。这里我们重新写了一个重定向的文件,本来是想实现和前面一样的功能,将printf打印的内容打印到log.txt文件中,但是这里我们什么都没看到,这是为什么呢?
2025-09-30 15:01:28
838
原创 【Linux】再识进程(Ⅱ)
父进程需要知道子进程的终止状态(比如它是正常退出还是被信号杀死的,退出码是多少),否则子进程可能会变成“僵尸进程”,占用系统资源导致资源的浪费。理解 exec 最关键的一点是:它并不创建新的进程,而是将当前进程的内存空间(包括代码、数据、堆栈等)完全清空,然后加载并执行一个新的程序文件,所以进程的id并不改变。:创建一个新的进程(子进程),子进程是父进程的副本,拥有和父进程相同的代码、数据段(若读写数据:写时拷贝)、堆栈等。进程终止的本质是释放系统资源,释放进程申请的相关内核数据结构和对应的数据和代码。
2025-09-26 14:00:20
1550
原创 【Linux】初识进程(Ⅰ)
冯诺依曼体系的核心思想就是存储思想:计算机的程序和程序所处理的数据一样,都以二进制的形式存储在同一个存储器中。功能: 负责执行所有的算术运算和逻辑运算。例子: 加减乘除、与或非比较等操作。功能: 是整个计算机的指挥中心。它从存储器中读取指令,进行分析,然后向其他部件发出控制信号,协调各部件步调一致地工作。运算器 + 控制器 = 中央处理器,也就是我们常说的 CPU。功能: 用于存放程序和数据。所有信息(指令和数据)都以二进制形式存储在此。
2025-09-22 19:36:08
1063
原创 Linux开发者三剑客:git、gdb、cgdb
目录1. 下载git/gdb/cgdb2. 认识git/gdb/cgdb2.1 git2.1.1 创建项目2.1.2 git三板斧2.2 gdb2.3 cgdb3. gdb/cgdb的基本操作3.1 操作总结这个命令大家可以直接AI,下面是我用Deepseek生成的,大家直接根据自己的系统下载就行,有问题也可以问AI。git 是一个开源的分布式版本控制系统(Distributed Version Control System, DVCS)。它由 Linus Torvalds 为管理 Linux 内核开发而创
2025-09-16 09:25:02
798
原创 【C++】C++11介绍(Ⅱ)
C++98设计的一个智能指针叫 auto_ptr ,它的特点是在拷贝时把被拷贝对象的资源管理权交给拷贝对象,但这样可能会使被拷贝对象悬空,从而报错。默认生成的移动构造/移动赋值重载,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。如果你没有实现移动赋值重载函数,且没有实现析构函数、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。是一个通用的函数包装器,可以存储、复制和调用任何可调用对象。
2025-09-13 19:28:00
941
原创 【C++】C++11介绍(Ⅰ)
定义:能够出现在赋值运算符左侧的表达式,代表一个可标识的内存位置(有明确的存储地址),可以被修改或取地址。特点具有持久性(在内存中占据一定空间,生命周期较长)可以被赋值可以使用运算符取地址。
2025-09-12 09:15:01
1174
原创 【C++】用哈希表封装unordered_XX
所以相同的内容我就不再赘述了,本篇主要就是展示一下大致思路,代码部分偏多,大家可以一起试试实现一下哦!
2025-08-26 21:27:04
478
原创 【Linux】编辑器vim的使用
我们可以直接用键盘上的光标来上下左右移动,但正规的vim是用写英文字母「h」、「j」、 「k」、「l」,分别控制光标左、下、上、右移⼀格。• 「#」:「#」号表示⼀个数字,在冒号后输入⼀个数字,再按回车键就会跳到该行了,如输入数字 15,再回车,就会跳到文章的第15行。• 「/关键字」:先按「/」键,再输入想寻找的字符,如果第⼀次找的关键字不是想要的,可以 ⼀直按「n」会往后寻找到您要的关键字为止。」键,再输入想寻找的字符,如果第⼀次找的关键字不是想要的,可 以⼀直按「n」会往前寻找到您要的关键字为止。
2025-08-15 13:05:11
1391
原创 【C++】哈希表的实现
当key是string/Date等类型时,key不能取模,那么我们需要给哈希表增加⼀个仿函数,这个仿函数支持把key转换成⼀个可以取模的整形,如果key可以转换为整形并且不容易冲突,那么这个仿函数就用默认参数即可,如果这个key不能转换为整形,我们就需要自己实现⼀个仿函数传给这个参数,实现这个仿函数的要求就是尽量key的每个值都参与到计算中,让不同的key转换出的整形值不同。当负载因子超过某个阈值(通常为0.7-0.8,下面代码实现用的是0.7)时,哈希表的性能会显著下降,此时需要进行扩容操作。
2025-08-13 20:05:28
688
原创 【Linux】关于权限的概念
注:但实际上所创建的文件和目录权限往往不是你上面设置的,因为创建文件或目录的时候还会收到umask的影响。假如默认权限是mask,但实际创建的文件权限是:mask&~umask。写(w—write):对文件来说,修改文件的权限;读(r—read):对文件来说,读取文件内容的权限;执行(x—execute):对文件来说,执行文件的权限;文件和文件目录的所有者所在组的用户:g --- Group。注:只有文件的拥有者和roo才可以改变文件的权限。- : 向权限范围取消权限代号所表示的权限。
2025-08-12 09:04:24
437
原创 【C++】map和set的封装
因为map和set的元素类型不同,所以在比较大小时,所依据的key表示方法就不一样,为了解决这个问题,我们使用一个KeyOfT的类型来解决这个问题。前面我们已经实现了红黑树,直接将我们实现的红黑树拿过来使用,各位可以先看一下小编下面这篇博客内容,再和这篇文章联系起来。在map和set中key值都是具有唯一性的,所以我们需要保证key不能被修改,这个问题可以用const来解决。最后就是实现map中的 [ ] 功能。在map和set中直接套用就可以了。
2025-08-11 08:00:00
471
原创 【C++】红黑树实现
红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,通过特定的规则确保树的高度始终保持在对数范围,从而保证插入、删除、查找等操作的时间复杂度为 O(log n)。
2025-08-06 14:32:56
550
原创 【C++】AVL树实现
AVL树是一种自平衡的二叉搜索树(BST),由G.M. Adelson-Velsky和E.M. Landis在1962年发明,是最早的自平衡二叉搜索树之一。AVL树在二叉搜索树的基础上增加了一个平衡条件:对于树中的任意节点,其左子树和右子树的高度差不超过1。这个高度差称为平衡因子(Balance Factor)。
2025-08-03 02:15:43
774
原创 【C++】set基本用法
通常 set 是用红黑树(一种自平衡二叉查找树)实现的,这保证了高效的查找、插入和删除操作。:set 中的元素总是按照特定的排序准则自动排序,默认是升序排列。:set 中的每个元素都是唯一的,不允许重复。
2025-07-29 01:32:37
375
原创 【Linux】基础指令(Ⅲ)
r 递归处理,将指定目录下的所有文件和子目录一起压缩。将../show/test.tar.gz目录下的文件解压缩到当前文件。语法:zip 选项 压缩包名.zip 目录/文件。:指定文件名,f后面直接跟文档名,不要加别的选项。-d 指定解压目录(默认当前目录)语法:whereis 命令名/二进制文件。用于在目录树中根据指定条件查找文件或目录。-a 全部信息,综合以上所有信息。语法:find 选项 文件/目录。语法:tar 选项 文件/目录。
2025-07-28 14:06:24
499
原创 【C++】map基本用法
C++ 标准模板库(STL)中的关联容器,它存储的元素是键值对(:查找、插入、删除操作的时间复杂度为 O(log n):元素按照键(key)的升序自动排序。:内部通常实现为红黑树,保证操作效率。:每个键只能出现一次。
2025-07-21 15:17:41
551
原创 【C++】二叉搜索树
二叉搜索树(Binary Search Tree, BST)是一种二叉树数据结构,其中每个节点的值都大于其左子树中所有节点的值,且小于其右子树中所有节点的值。这一性质递归地适用于所有子树,使得中序遍历BST会得到一个严格升序的序列。如下图:这就是一个简单的二叉搜索树。
2025-06-07 17:14:27
516
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅