自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(807)
  • 资源 (7)
  • 收藏
  • 关注

原创 在Linux下制作软件安装包

目前,Linux操作系统的软件包主要有两种:Redhat系的RPM包管理机制和Debian系的Deb包管理机制。Debian系统的代表有Debian、Ubuntu等操作系统。在Linux下安装软件的实质是将可执行文件复制到环境变量PATH对应的官方路径下。

2025-12-03 19:24:53 325

原创 什么是内存踩踏及其危害

不写C程序的话,很少听过内存踩踏这一说。“内存踩踏”(Memory Trampling)是编程中一种严重的内存非法操作问题,本质是程序错误地覆盖了不属于自己的内存区域,导致数据被篡改、程序崩溃,甚至引发安全漏洞。它是比普通内存越界更宽泛的说法,涵盖多种内存非法写入 / 修改行为,常见于 C/C++ 等无内存安全检查的语言。这里就是典型的内存踩踏。

2025-12-01 23:38:08 156

原创 使用Valgrind检测内存问题(C语言)

在C语言编程里,最常见的内存问题就是使用了malloc分配的内存,忘记释放(free)造成的内存泄漏。今天介绍一个内存检测工具Valgrind。

2025-11-30 22:17:57 369

原创 什么是文件系统

比如说格式化U盘,文件系统会将U盘的存储空间划分为大小相等的逻辑块,文件系统会将U盘的存储空间划分为纯数据区和元数据区。纯数据区是真正存储数据的空间,而元数据区则是存储文件的相关属性如该文件在磁盘中的存储位置、文件长度、时间戳、读写权限、所属组、链接等信息。既然文件都对应一个inode,当用户对指定路径下的某个文件进行读写操作时,系统会到元数据区的索引节点表,打到与该文件对应的inode节点,并根据该节点信息就可以找到该文件磁盘上的具体存储位置。这里的格式化,实质就是让文件系统去管理这些存储空间。

2025-11-25 22:44:45 194

原创 什么根文件系统

Linux内核在初始化过程中,会创建一个根目录“/”,然后mount第一个文件系统到这个根目录下,这个文件系统就被称为根文件系统。其他的存储分区、磁盘、SD卡、U盘接着就可以mount到根文件系统的某个目录下。然后用户就可以通过文件接口访问各个存储设备。在Linux中,一个根文件系统会包含Linux运行所需要的完整目录和相关启动脚本、配置文件、库、头文件等。

2025-11-24 00:25:56 167

原创 进程内存空间的权限管理

Linux的内存管理子系统将整个内存空间划分为用户空间和内核空间。操作系统代码运行在内核空间,普通应用程序则运行在用户空间。每一个程序在运行时,都会通过页表映射到不同的物理内存空间。页表不仅饮食地址转换信息,还包含每一个进程中不同内存区域的访问权限信息。这种设计可以对不同用户进程映射到实际物理内存的地址空间进行权限管理。进程的内存空间是相互独立、隔离的。这就涉及到权限管理问题。MMU除了做地址转换外,它和页表还可以对不同的内存区域设置不同的权限,防止内存被非法访问,从而保证系统安全。

2025-11-24 00:09:21 162

原创 什么是MMU内存管理单元

一开始虚拟地址和物理地址的转换关系都是保存在地址转换表中的,但是试想一下,应用1大小为4KB,就至少需要4KB大小的空间来存储这个地址转换表信息,应用2为8KB,那至少需要8KB大小的空间来存储这个地址转换表信息。比如应用1和应用2都有相同的虚拟地址0x1000,那么当CPU执行到应用1时,会到0x1000去取指,经过MMU转换后,会到实际物理内存的0x40002000处取指令,执行到应用2时,也会到会到0x1000去取指,经过MMU转换后,会到实际物理内存的0x30002000处取指令。

2025-11-23 23:01:59 285

原创 什么是进程

本文介绍了Linux系统中进程管理的基本原理。操作系统通过进程(task_struct结构体)来管理程序运行,每个进程拥有独立的虚拟地址空间,通过页表映射到物理内存,实现内存隔离。为支持进程间通信,Linux提供了多种机制:管道(匿名/命名)、信号量、消息队列、共享内存、信号、socket和D-BUS等。这些机制利用内核共享空间或外部存储实现进程间的数据交换和同步,确保系统性能和多任务协同运行。

2025-11-23 14:32:38 213

原创 Linux中的线程是什么?

这些共享的资源为了保证程序的正确性符合逻辑,这共享资源会涉及安全访问和线程间同步的问题,一般通过互斥锁、条件锁、读写锁等锁机制来实现对资源的安全访问。我们再来说说线程池,虽然进程的多个线程可以共享进程的很多资源,如代码段、数据段、打开的文件,线程们也有自己的上下文环境,如各自的寄存器状态、栈、程序计数器等。线程的开锁除了线程上下文 切换带来的开销外,这里还有另一个开销,那就是线程的创建与销毁,尤其是频繁使用线程的场景下,这种开销会特别明显。

2025-11-23 00:12:06 256

原创 插入排序的原理和示例

1.选择排序的有序区中的元素的位置确定后是不变,因为它每次总是从无序区中选择最小的一个排到左侧,插入排序有序区中的元素位置是暂时的,只有排序完成后,才是固定的。插入排序要进行n-1轮,每一轮在最坏情况下的比较次数分别是1次,2次,3次,…2. 在插入排序排序后,原序列中相等元素的相对位置保持不变,所以它是稳定的排序,而选择排序则不然。由于插入排序也是原地排序,也没有借助额外的存储空间,所以它的空间复杂度为O(1).插入排序,不断从无序区取出一个元素,插入到有序区中。

2025-11-17 10:06:34 267

原创 选择排序的原理及示例

选择排序比冒泡排序有着交换次数更少的优点,但是它的缺点的是不稳定。这里的不稳定指的是当数列中有着多个值相等的元素时,选择排序有可能打乱了它们原有的顺序。也就是值相等的元素在数列中的相对位置不变,就是稳定,变了,就是不稳定。算法每一轮会选出一个最小值,再交换到左侧的时间复杂度是O(n),总共要迭代n-1次,所以时间复杂度为O(n。写算法的步骤,先用自然语言描述算法,第一步要做什么、第三步要做什么…,最后再用编程语言表达出来。因为该算法是原地排序的,并没有用到额外的存储空间,所以排序的空间复杂度为O(1)。

2025-11-16 00:02:17 222

原创 什么是协程

比如网络请求、文件读写等这些任务大部分时间都在等待I/O的完成(而不是CPU计算),在这一段时间,协程可以主动暂停,让其他协程执行,有效避免了让线程空等,提高了CPU的利用率。一个协程占用的内存不是很大,通常只有几KB,而一个线程中可以创建数万甚至数十万个协程(迸发规模巨大),而线程的内存占用通常以MB为单位,而线程的数量受到操作系统的限制。协程可以在执行过程中主动暂停(通过yield、await等关键字),同时保留其局部变量和执行状态,再将控制权交还给其他协程,之后可以从暂停的位置恢复执行。

2025-11-15 16:09:40 313

原创 自查C语言水平

标识符:用于给变量、函数、数组、结构体、宏等程序元素命名。命名规则:1.由字母(A-Z、a-z)、数字(0-9)、下划线(_)组成,必须以字母或下划线开头(不能以数字开头)。2.区分大小写。3.不能与 C 语言的关键字重名(否则会导致语法错误)。4.长度无严格限制,但编译器通常只识别前 31 个字符。举例:变量名:a、total、student。

2025-11-13 22:19:26 264

原创 C语言的运用

不同的领域对掌握C语言的要求都不同,例如从事嵌入式开发、驱动开发、Linux内核开发,不仅要求掌握基本C语言基本语法,还要对硬件电路、CPU、操作系统、编译原理等低层机制有完整的了解。其实并不是这个语言有多么的牛,而是因为android和移动互联网火了,而Java作为其主要的开发语言,自然也就火了。而真正的王者是C语言,自其诞生几十年来,一直是使用最广泛的编程语言之一。通过指针和位运算,可以修改内存寄存器,从而直接控制CPU和硬件电路的运行。正是由于这种特性,很多操作系统内核、驱动等都选用C语言来开发。

2025-11-13 18:25:25 259

原创 AWS服务分类

大多数AWS 服务都属于此类。

2025-08-04 22:22:30 261

原创 什么是AWS Region和AWS Availability Zones

每个AWS Region通常有三个Availability Zones,例如悉尼Region叫做ap-southeast-2 ,那么它的三个AZ分别中叫做ap-southeast-2 a,ap-southeast-2b,ap-southeast-2c。可用区(AZ)是一个AWS Region内一个或多个具有冗余电源、网络和连接的离散数据中心。AZs使客户能够操作生产应用程序和数据库,这些应用程序和数据库的可用性、容错性和可伸缩性都比单个数据中心高。在一个AWS Region内的所有可用区。

2025-08-02 23:34:51 1111

原创 C语言的内存分配:malloc和free

在ANSI C中,我们应该坚持使用强制类型转换,因为这样可以提高代码的可读性,否则,我们就不容易记住这个指针所指向的实际类型,这样的阅读性就大打折扣。malloc函数会找到合适的空闲内存块,这样的内存是匿名的,即malloc分配了内存后,不会为其赋名,返回动态分配内存块的首字节地址,我们可以将这个地址赋给一个指针变量,使用这个指针访问这块内存。和malloc函数一样, 在ANSI C之前,calloc函数也返回指向char的指针,在ANSI C之后,返回指向void的指针。静态内存的数量在编译时固定的。

2025-02-22 18:53:09 449

原创 C语言中的作用域、链接、存储期

外部链接的静态变量具有文件作用域、外部链接和静态存储期,这样的变量有时被称为外部存储类别,属于该类别的变量称为外部变量,定义时,只需要将变量放在所有函数的外面即可。属于自动存储类别的变量都具有自动存储期,块作用域且无连接,声明在块中或函数头的任何变量都属于自动存储类别。寄存器变量是存储在CPU中的,因其存储在CPU中,所以无法获取寄存器变量的地址。auto是存储类型说明符,这个说明在C和C++的用法是相同的,如果写的程序包含C和C++代码,则要避免使用这个说明符。具有文件作用域的变量自动具有静态存储期。

2025-02-19 22:34:33 786

原创 C语言的递归与尾递归

递归的优点为某些编程问题提供了很简单的解决方案,缺点是一些递归算法会快速消耗计算机的内存资源。有时递归算法不是很好阅读和维护。尾递归是最简单的递归形式,它的特点就是将递归调用放在函数的末尾,即正好在return语句之前。C语言允许函数调用自己,这种调用过程就叫递归。

2025-02-16 20:32:56 259

原创 C语言中的文件概念

另一种方式是存储文件的大小的信息,Unix使用这种方法处理所有的文件。操作系统的差异导致它有不同的底层I/O实现,这里的差异是多方面的,如系统存储文件的方式的不同,在有的系统上把文件的内容储存在一处,而文件的相关信息存储在另一处;在处理文件方面,不同的系统也可能表现出差异,如有的系统使用单个换行符标记行末尾,有的系统可能使用回车符和换行符的组合来表示行末尾。这样,不同的操作系统可以有不同的底层I/O实现,用户通过使用C标准的文件处理模型和标准I/O函数,就可以获得统一的使用界面。

2025-02-16 12:49:22 414

原创 C语言中的对象、左值、右值、序列点、副作用的概念

序列点是程序的执行点,在C语言中,语句中的分号标记一个序列点,在该点上,所有副作用都在进入下一步之前发生,即在一个语句中的赋值运算、递增运算、递减运算对运算对象的修改必须在程序执行下一条语句之前完成。sizeof以字节为单位返回对象的大小,它的返回类型是size_t这是一个无符号整型数,用size_t时,编译器会根据不同系统来替换具体的整型类型。因此,对象指的是实际的数据存储,而左值是用于标识或定位存储位置的标签。副作用也是一个C语言的术语,它是指对数据对象或文件的修改。num是可修改左值,5是右值。

2025-02-15 23:32:59 423

原创 C语言函数的实参与形参与缓冲区的概念

在C语言中,实际参数是传递给函数的特定值。形式参数是函数中用于储存值的变量。缓冲区刷新是指把缓冲区中的数据送到屏幕或文件的行为。

2025-02-15 23:15:53 191

原创 C语言中的常量与只读变量,#define与const的区别

代码在编译时就需要确定好数组的长度,所以只能用#define定义的宏常量,const的作用是限制变量为只读,它的值只有在运行时才能够确定,因此用const的变量来指定数组长度会报错。这条定义宏的语句,是不是很熟悉,这条预处理指令会在编译器编译前把源文件中使用到这个宏的地方都先展开。表明C处理器需要在编译器接手工作之前先处理这条指令。因为它们的值都不能够改变,都是它们的意义却是不同的。

2025-02-15 23:08:28 421

原创 C语言编译机制

o目标文件只包含编译源文件后的机器语言代码,不包含标准库函数的代码(库文件中有许多函数的目标代码),它不能直接运行,因为它缺失启动代码,启动代码充当程序与操作系统之间的接口。C的精神告诉你,它相信你(程序员)能够控制好,能够组织好,它不会在语言层面设置障碍去阻止你做任何事,它时刻保持语言的精练、简单,高效。编译器把源文件(扩展名为.c的文件)编译出中间代码(中间代码有很多种形式,如.s编译代码、.o目标代码),链接器再将其与其他代码连接在一起生成可执行文件。所以你负有责任去管理你的程序过程。

2025-02-15 17:37:22 290

原创 计算机中数据的表示

对于计算机中的二进制的解析完全取决于具体的机器指令,也就是说对于最高位是不是符号位,要不要取负权重等问题,要依赖于具体的机器指令,和二进数本身关系不大,如对于内存中的二进制数1111 1011,有的指令读取后,会将其视为有符号数,而有的指令读取后则会将其视为无符号数。+0, -0在系统中的表示法是一样的,而原码和反码都做不到。原码没有办法表示+0和-0,它只能表示+0,反码就更加不行了,最反后就是另一个值了。根据前求负数的补码的过程,我们可知结果的最高位总是1,这就是我们常说的符号位。

2025-02-08 10:20:44 1101

原创 汇编指令和机器码的区别

(本例子是在apple m1架构平台上进行的,编译出来的汇编代码和机器码与在x86架构下编译出来的会有所不同。不同架构的平台的对应的汇编代码与机器码也是不相同的)(本例子是在apple m1架构平台上进行的,编译出来的汇编代码和机器码与在x86架构下编译出来的会有所不同。不同架构的平台的对应的汇编代码与机器码也是不相同的)如汇编的ret指令对应的机器指令在我运行的平台上就是d65f03c0.编译出对应的汇编源文件*.s。将可执行文件反编译出来。

2025-02-08 09:00:51 347

原创 X86中的常用寄存器

RSI, RDI, R8, R9还可以在调用函数时传递参数。

2025-02-07 23:20:53 698

原创 电路基本原理

当其中一个输入为高电平,另一个输入为低电平时,上面输出1,下面的输出就是0,结果就是二进制的01.当输入都为高电平,即1时,上面的输出就是0,下面的输出就是1,结果就是二进制的10.输入都是高电平,才会输出高电平,否则没有输出。只要其中一个输入是高电平,就会输出高电平。输入高电平,则输出低电平。输入低电平,则输出高电平。输出电平与输入电平相反。

2025-02-07 23:14:18 506

原创 CPU的基本结构

部件之间的通信是由各种各样的总线来完成。以内存为例,地址总线传输要访问的内存地址,数据总线传输读写的数据。在实际中,有的总线地址和数据是分离的,有的是同一根分时复用。北桥芯片也集成了内存控制器,用来控制与内存的通信。目前,最新的主板上,就没有北桥芯片了,因为北桥的功能已经被集成到CPU中去了。FSB总线:前端总线(Front Side Bus)是CPU和北桥传递的所有数据用的,FSB总线的频率直接影响到CPU访问内存的速度。PCI总线:这是一种高性能局部总线,CPU和外设之间的高速通道。

2025-02-07 22:58:19 464

原创 Vim跳转文件及文件行结束符EOL

在Windows上,行尾就不只使用 LF 这一个字符了,在 LF 前面会多一个 CR,编码值为 13(U+000D)。文本文件里存放的是用行结束符(EOL,即 End of Line)隔开的文本行,二进制文件里则没有这样的明确分隔符。使用 Vim 编辑的文本文件,最后一个字符通常是 LF(除非使用 Mac 行尾风格,则结尾是 CR)。在 Unix 或类Unix上,这个 EOL 在存盘时使用的字符是 LF,编码值是 10(U+000A)。可以在分割的窗口打开跳转的文件,不过在我的实验不是次次都成功。

2025-02-06 14:14:53 638

原创 Vim 多窗口编辑及文件对比

在光标所在的窗口,输入分割窗口命令就会对那个窗口进行分割。设置窗口高度,默认为纵向占满,利于专心编辑某个文件。只保留当前窗口,关闭其他所有窗口。只保留当前窗口,关闭其他所有窗口。默认使用水平分割的方式。把当前窗口横向一分为二。把当前窗口纵向一分为二。

2025-02-05 19:01:26 731

原创 Vim的基础命令

将光标所在行开始的【数字】行,直接删除掉,直接输入新的内容进行内容替换,其余没有删除掉的不受影响,如果没有带【数字】,就是一行。将光标所在处开始的【数字】个字符,直接删除,直接输入内容进行替换,其余没有删除掉的不受影响,如果没有带【数字】,就是一个字符。删除光标所在行开始的【数字】行,不带数字就是一行,并开始输入新内容。删除光标所在行开始的【数字】行,不带数字就是一行,并开始输入新内容。光标所在行开始【数字】行字符,不加数字,就是当前行。光标所在行开始【数字】行字符,不加数字,就是当前行。

2025-02-04 21:17:21 1200

原创 C 标准库提供的进程控制

上面程序调用函数 atexit 为程序注册了一个回调函数,注册回调函数成功后,atexit函数会返回0。这个函数会在程序显式调用 exit 函数时,或从 main 函数内正常退出时被触发。在对应的回调函数 exitHandler 中,调用用 getenv 函数,获取并打印了当前宿主机上环境变量 PATH 的值。

2025-02-03 10:56:05 299

原创 C语言中的信号量

硬件中断直接由硬件触发,如磁盘完成了某次由用户程序指定的 IO 操作后,就会通过硬件中断的方式来通知 CPU 这一消息,并让 CPU 进行后续的处理。此时,如果应用程序并未设置自定义的信号处理程序,则操作系统将会执行默认信号处理程序中的逻辑,一般是直接终止当前程序的运行。在信号处理的过程中, CPU 从用户程序到信号处理程序的执行流程转移。当上述程序访问了非法内存,操作系统便会将信号 SIGSEGV 发送给当前进程,并之前通过 signal 函数注册的信号处理信息,调用用户自定义或默认的信号处理函数。

2025-02-03 09:54:30 441

原创 C语言中的线程本地变量

因此线程在对 counter 变量进行累加时,便不会受到其他线程的影响。线程本地变量还有一个用途:用来存储线程独有的一些信息,如错误信息。这处线程本地变量可不是简单的函数中的本地变量。线程除了可以共享存在于进程内的全局变量外,还可以有属于自己的线程本地变量。线程本地变量的值只能够在某个具体线程的生存期内可用。除了以关键字来定义线程本地变量的方式之外,标准库还提供了一系列的函数来实现同样的目的。这样,当线程退出时,便可以确保相应的线程本地资源(比如堆内存)能够以正确的方式被清理。

2025-02-02 23:11:58 502

原创 在C语言中使用条件变量实现线程同步

在多线程应用中,当某个线程的执行依赖于另一个线程对数据的处理时,这个线程可能没有被阻塞,只是不断地检查某个条件是否成立了(这个条件就是另一个线程对数据处理的结果的指示器),这是一种“忙等待”的方式实现线程间的同步。这样一来,某个线程可以在完成了某件事情后,通知并唤醒等待线程,让其继续工作,完成接下来的任务。在上述程序中,在 main 线程中,调用了与条件变量相关的函数 cnd_wait。在我们的例子中,只有 main 函数对应的一个线程,所以此时,互斥量将被重新上锁,main 线程将继续执行接下来的指令。

2025-02-02 22:13:02 580

原创 实现C语言的原子操作

我们一般都是在多线程环境中,才会需要原子操作的支持。因为当多个线程中对共享资源进行原子操作时,编译器和 CPU 将能够保证这些操作的正确执行。当该线程将整个原子操作全部执行完毕后,其他线程才可以继续执行同样的操作。与使用互斥量相比,原子操作可以更加清晰和方便地抽象并行代码,而不需要频繁进行加锁与释放锁的操作。从性能角度来看,原子操作的执行通常直接依赖于 CPU 提供的相应的原子机器指令。而使用互斥量则需要让线程阻塞,还要频繁进行上下文切换,比较之下,原子操作的性能一般会更好。

2025-02-02 20:50:52 715

原创 在C语言多线程环境中使用互斥量

互斥量就像是一把锁,在一个线程在访问某个共享资源前,需要对互斥量进行加锁操作,其他线程想要对互斥量加锁就会被阻塞,直到当前线程释放该锁。当锁被释放后,被阻塞的线程都开始继续执行,并再次重复前面的步骤,开始争夺可以对互斥量进行加锁的操作。如果有十个银行账号通过不同的十条线程同时向同一个账号转账时,如果没有很好的机制保证十个账号依次存入,那么这些转账可能出问题。我们可以通过互斥量来解决。互斥量这种方式,可以保证每次只有一个线程在操作共享资源。C标准库提供了这个互斥量,只需要引入threads.头文件。

2025-02-02 13:20:32 241

原创 本地部署DeepSeek

做完上述的东西,就完成了deepseek在本地的部署了。下载DeepSeek模型。下载完成后直接安装。

2025-02-01 11:17:07 498

原创 C++如何遍历数组vector

在C++中,vector是一个可变数组。那么怎么遍历它呢?我们以for循环为例(while循环,大家自己脑补)。

2025-01-01 21:40:38 652

uber-apk-signer

uber-apk-signer

2025-01-04

jadx-1.5.1.zip

jadx-1.5.1.zip

2025-01-04

Jadx-Dex to java decompiler

Jadx-Dex to java decompiler

2025-01-04

apktool.jar

apktool.jar

2025-01-04

APKLab-1.7.0.zip

APKLab-1.7.0.zip

2025-01-04

git常用命令.pdf

这是一份提供常用的git命令的pdf文件。可以通过查阅这份文档,快速使用git。个人觉得非常好用,遂推荐给大家。

2019-11-14

java-json.jar.zip

这个jar包可以实现xml与json字符串互相转化的功能。通过常我们反序列化时都习惯用json,但有些接口仍然使用xml,那么可以借助这个工具来实现xml转换json了。

2020-06-27

sqlitestudio-3.2.1.tar.xz

sqlite studio这一款数据库工具可以非常方便查看sqlite数据库,非常直观。在linux系统上下载下来解压后就可以使用了,无需要安装。

2020-04-17

Android-ttf.zip

Android字体,.ttf字体文件,可以用于Android中。本资源包含29种字体,任君选择。可以在Android应用中使用。这样可以丰富android应用的显示。

2020-07-02

最完整的git教程.zip

git最全的教程、最官方的教程、最完整的教程,你可以学习到最完整的git教程,你可以系统地学习git教程。

2019-11-13

mongodb-org-server_4.2.5_amd64.deb

这是mongodb server,版本是4.2.5,它是一个文档数据库。是NoSQL类型的数据库。在官方网站下载,可能会比较慢。在此分享给你们。

2020-03-28

jdk1.6-bin.zip

jdk-6u45-linux-x64.bin用于在linux上安装的,drozer需要jdk1.6。还有一些平台就是需要jdk1.6的。真是很奇怪。分享给大家。

2019-10-23

空空如也

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

TA关注的人

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