
学习笔记
choumin
这个作者很懒,什么都没留下…
展开
-
GHashTable基本用法和注意事项
GHashTable 基本用法和注意事项。原创 2024-12-29 10:10:29 · 199 阅读 · 0 评论 -
C语言中32位浮点数的格式
C语言中32位浮点数的格式原创 2024-07-06 11:13:36 · 861 阅读 · 0 评论 -
gap意识
学习和工作过程中的 gap 意识...原创 2024-05-12 00:17:09 · 289 阅读 · 0 评论 -
C++中重载定位new表达式
C++中重载定位 new 表达式 ...原创 2024-03-23 10:50:47 · 400 阅读 · 0 评论 -
linux内核中从核初始化过程
linux 内核的入口函数是每个体系结构自己定义的,假设当前架构的内核入口函数是:kernel_entry(),则下面梳理了从核的初始化过程(内核版本:4.19):在从核线程中:smpboot_thread_fn() 会循环(while(1))调用 cpuhp_thread_fun(),后者在每次被调用时都会更新当前 cpu 的 state (在 cpuhp_cpu_state 结构体中),当 state 大于 target 后,结束循环。其中 target 的值由主核设置为:CPUHP_ONLINE。原创 2022-07-12 17:25:11 · 683 阅读 · 0 评论 -
使用fifo文件实现进程间通信
fifo 文件是一种先进先出的特殊文件,即命名管道。从man7 上可以看到 fifo 的相关信息,摘抄如下:A FIFO special file (a named pipe) is similar to a pipe, except that it is accessed as part of the filesystem. It can be opened by multiple processes for reading or w...原创 2021-08-08 09:18:16 · 1134 阅读 · 0 评论 -
软件工程的基本原理
著名软件工程专家 Boehm 于 1983 年提出软件工程的 7 条基本原理。Boehm 认为,这 7 条原理是确保软件产品质量和开发效率的最小集合,它们是相互独立、缺一不可的最小集合,同时又是相当完备的集合。 (1)用分阶段的生命周期计划严格管理 这条原理说明,应该把软件生命周期分成若干阶段,并相应制订出切实可行的计划,然后严格按照计划对软件的开发和维护进行管理。 (2)坚持进行阶段评审 软件的质量保证工作不能依赖编码...原创 2021-07-31 11:37:52 · 6644 阅读 · 0 评论 -
需求获取之联合需求计划
为了提高需求获取的效率,越来越多的企业倾向于使用小组工作会议来代替大量独立的访谈。联合需求计划(JRP)是一个通过高度组织的群体会议来分析企业内的问题并获取需求的过程,它是由企业主管部门经理、会议主持人、用户、协调人员、IT人员、秘书等共同组成的专题讨论组来分析、讨论问题并定义系统需求。 联合需求计划是一种相对来说成本较高的需求获取方法,但也是一种有效的方法。联合需求计划将会起到群策群力的效果,对于一些问题最有歧义的时候或对需求最不清晰的领域都是十分有用的一种方法。这种方式...原创 2021-04-10 14:38:16 · 1274 阅读 · 0 评论 -
软件开发之极限编程
极限编程是 Kent Beck 与 Ward Cunningham 在 20 世纪 90 年代初期提出来的,相对于传统的软件工程方法,它具有以下特点: (1)一种轻量级的软件开发方法,以实践为基础的软件工程过程和思想。 (2)它使用快速的反馈,大量而迅速的交流,通过及时和大量的测试来最大限度地保证和满足用户的需求。 (3)强调用户满意,开发人员可以快速反应需求的变化。 (4)认为代码质量的重要程度超出其他所有的内容。...原创 2021-04-10 14:37:50 · 431 阅读 · 0 评论 -
软件开发之构件组装模型
构件组装模型利用模块化思想将整个系统模块化,并在一定构件模型的支持下复用构件库中的一个或多个软件构件,通过组装高效率、高质量地构造软件系统。构件组装模型本质上是演化的,开发过程是迭代的。 在该模型中,软件体系结构设计尤为关键,它不仅规划迭代开发的构件数量和次序,而且指导通过组装的方式构造应用软件。 构件组装模型使得软件开发不再一切从头开始,开发的过程就是构件组装的过程,维护的过程就是构件升级、替换和扩充的过程。...原创 2021-04-10 14:37:20 · 1296 阅读 · 0 评论 -
软件开发之螺旋模型
螺旋模型由 Boehm 于 1988 年提出来的,它是针对大型软件开发项目的特点而提出来的。实践证明,项目规模越大,问题越复杂,资源、成本、进度等不确定的因素就越大,项目承担风险也就越大。因此,风险是软件开发不可忽视的潜在不利因素,它可能在不同程度上损害软件开发过程和软件产品的质量,必须在风险造成危害之前,及时对风险进行识别、分析,并采取风险管理策略,减少甚至消除风险带来的损害。 螺旋模型不像瀑布模型将软件开发过程用一系列活动和活动之间回退来表示,而是将过程用螺旋线表示,螺...原创 2021-04-10 14:35:50 · 2919 阅读 · 0 评论 -
软件开发之喷泉模型
喷泉模型也称为迭代模型。喷泉模型认为软件开发过程的各个阶段是相互重叠和多次反复的,功能模块不是一次完成,而是像喷泉,水喷上去又可以落下来,既可以落在中间,又可以落到底部。各个开发阶段没有特定的次序要求,完全可以并行进行,可以在某个开发阶段中随时补充其他任何开发阶段中遗漏的需求。 喷泉模型是以面向对象驱动的模型,主要用于描述面向对象的软件开发过程。软件的某个需求部分通常重复开发多次,实现需求的相关对象在每次迭代中加入渐进的软件产品。由于对象概念的引入,对象及对象关系在分析、设...原创 2021-04-10 14:35:19 · 3020 阅读 · 0 评论 -
软件开发之增量模型
增量模型由 Mills 等于 1980 年提出,可以让客户得到一些机会以延迟对详细需求的决策,即客户的需求可以逐步提出来;另外,每一次增量需求的划分与增量实现的集成是以不影响系统体系结构为前提的。 在增量模型中,客户大概或模糊地提出系统须提供的服务或功能,即给出系统的需求框架,以及这些服务或功能的重要作用,从而可以确定系统需求实现的优先级。待开发增量的选择是依照优先级确定的,核心需求的优先级较高,一般在最初的增量中解决。 一旦一个增量开发完成,客户就可以使...原创 2021-04-10 14:33:39 · 1172 阅读 · 0 评论 -
软件开发之演化模型
演化模型主要针对需求不是很明确的软件项目,希望通过第一个原型来逐步探索和理解用户需求。按照不同的原型应用策略,演化模型可以分为两类:探索式演化模型和抛弃式演化模型。 探索式演化模型,其目标是与用户一起工作,共同探索系统需求,直到最后交付系统。这类开发从需求较清楚的部分开始,根据用户的建议逐渐向系统中添加功能。因此,最终的系统是在探索需求的原型上一步一步添加功能完成的。 抛弃式演化原型,通过实现一个或多个系统原型理解和明确用户需求,然后给出系统一个较好的需求...原创 2020-11-10 16:54:46 · 1459 阅读 · 0 评论 -
软件开发之瀑布模型
该模型由 Winston Royce 于 1970 年在其论文中提出。瀑布模型规定软件生命周期提出的一些基本工程活动,并且规定它们自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落。 它包括需求分析、设计、编码、测试、运行和维护。软件生命周期的阶段划分不仅降低软件开发的复杂程度,而且提高软件开发过程的透明程度。推迟软件实现,强调在软件实现前必须进行分析和设计工作。以项目的阶段评审和文档控制为手段有效地对整个开发过程进行指导,保证阶段之间正确衔接,能够及时发现并纠正开发过程...原创 2020-11-10 16:53:55 · 1140 阅读 · 0 评论 -
软件配置项目
随着软件开发工作的开展,会得到许多工作产品或阶段产品,还会用到许多工具软件。所有这些独立的信息项都要得到妥善的管理,决不能出现混乱,以便于在提出某些特定的要求时,将它们进行约定的组合来满足使用的目的。这些信息项目是配置管理的对象,称为软件配置项。 软件配置项目可以分为以下几类: (1)环境类,指软件开发环境或软件维护环境,例如编译器、操作系统、编辑器、数据库管理系统、开发工具、项目管理工具、文档编制工具等。 (2)定义类,是需求分析与定义...原创 2020-11-08 22:59:00 · 438 阅读 · 0 评论 -
面向对象的设计原则学习
1、开放/封闭原则该原则规定,类或对象及其方法对于扩展来说,应该是开放的,但是对于修改来说,应该是封闭的。2、控制反转原则该原则规定,高层次的模块不应该依赖于低层次的模块,它们应该都依赖于抽象。该原则建议任何两个模块都不应以紧密方式相互依赖。事实上,基本模块和从属模块应当在它们之间提供一个抽象层来耦合。3、接口隔离原则该原则规定,客户端不应该依赖于它们不需要使用的接口。4、单一职责原则该原则规定,类的职责单一,引起类变化的原因单一。一个类可以因为所需行为的变化而进行修改,但是如果原创 2020-11-07 10:31:48 · 116 阅读 · 0 评论 -
mips中的原子读改写实现
mips 中的 ll 指令 和 sc 指令可以用来实现原子的读改写操作。由 ll 指令和 sc 指令构成的指令序列并不保证所有操作的原子性,但是只有当这些指令序列的执行确实没有受到干扰时,原子操作才能成功完成。指令 ll d, o(b) 用普通的基址加偏移的寻址方式载入一个 32 位数,该指令执行后有如下影响:首先处理器记住该加载指令已执行(在 CPU 内部的某个不可见的硬件关联状态位进行设置);其次处理器将该加载指令的地址存储在寄存器 LLAddr 中。ll 指令原子执行完后,后面的 sc t, o(原创 2021-04-16 11:46:07 · 629 阅读 · 1 评论 -
mips中分支指令的偏移量计算
在 mips 中,分支指令的低 16 位是相对于当前 PC 的有符号字偏移,用于表示字的距离,偏移量为 0 时,就跳转到分支指令的延迟槽处,因此要想跳转到自身所在的位置,就需要将偏移量设为 -1。下面来看一个示例,首先有如下汇编源码:$ cat ./main.smove $v0, $a0sltiu $t2, $a2, 40andi $t0, $a0, 0xfbnez $t2, .Lbranch1ldl $t1, 3($a1)原创 2021-04-02 21:10:08 · 3187 阅读 · 0 评论 -
使用objdump查看内核中某个函数的汇编代码
方法:先通过 System.map 找到函数的起始地址,然后通过 objdump 得到反汇编后的内容以下示例用来查看内核中 sys_getpid() 函数的汇编代码,其中,stop-address 的值是拍脑袋想出来的。$ grep sys_getpid ./System.mapffffffff8026d920 T sys_getpid$ objdump -d --start-address=0xffffffff8026d920 --stop-address=0xffffffff8026e92原创 2021-04-02 15:44:13 · 2661 阅读 · 0 评论 -
dump虚拟机中的一段内存
方法:使用 virsh qemu-monitor-command 命名,它的基本用法是:$ virsh qemu-monitor-command --help NAME qemu-monitor-command - QEMU 监控程序命令 SYNOPSIS qemu-monitor-command <domain> [--hmp] [--pretty] {[--cmd] <string>}... DESCRIPTION QEMU 监控程序原创 2021-04-02 14:58:53 · 1168 阅读 · 0 评论 -
KMP算法
网上已经有大量关于KMP的博客了,我也写不出新意来,这里就不写KMP的原理,需要的可以去看看其他博客,这里主要聚焦一个问题:如何在知道KMP的原理后,快速写出代码?对于KMP算法,我觉得应该牢记以下几条内容,以便能够快速写出代码:失配时,文本串不回溯,模式串回溯 模式串回溯时依赖 next 数组 next 数组的计算只依赖模式串 假设模式串为P,已知 next[i] = k 的情况下,求 next[i + 1] 的方法:若 P[i] == P[k],则 next[i + 1] = k + 1,原创 2021-03-27 23:19:02 · 155 阅读 · 0 评论 -
汇编器指令学习
汇编器指令在编译时起作用,用来控制汇编器的操作,不属于 CPU 指令集,因此称为伪指令。下面例举汇编器指令可以做的一部分事情:1)为汇编器值指明程序的开始和结束位置2)为数据提供存储位置3)为变量赋值4)定义不同段的开始和结束位置,在程序中定义宏等等。下面介绍几个 x86 汇编器支持的指令.align integer, pad指明下一个生成的数据以模 integer 为对齐,其中 integer 必须要是 2 的幂,pad 用来指明填充的内容,对于 text section,是 0x90(原创 2021-03-24 10:04:51 · 476 阅读 · 0 评论 -
git rebase后commit id的变化
经测试发现,在执行完 git rebase 之后,1)会生成的新的 commit id2)新commit 与旧commit 的父节点不相同3)旧 commit 的父节点保持不变查看某个 commit 的父节点的方法:$ git log --pretty=%P -n 1 commit-id...原创 2021-03-13 08:23:43 · 3584 阅读 · 0 评论 -
使用glibc xdr对结构体进行编解码
glibc 中的 rpc/xdr.h 提供了很多 xdr_xxx()接口,可以用一种跨平台的方式对任意数据进行编码和表示。下面介绍如何对结构体数据进行跨平台的编码和解码,主要涉及以下几个步骤:1)使用 rpc 语言定义结构体(类似于 thrift 中的 IDL 文件),使用 rpcgen 生成对应的 .h 和 .c 文件2)使用 xdrstdio_create() 初始化 XDR 对象,并调用上述文件自动生成的接口对结构体数据进行编码,得到编码后的内存 buffer3)使用 xdrmem_cr.原创 2021-03-06 23:25:41 · 1454 阅读 · 0 评论 -
fmemopen和open_memstream
glibc 中的 fmemopen() 和 open_memstream() 函数可以实现在一段内存上进行 IO 操作,它们的返回值都是 FILE * 类型,利用这个文件指针,可以调用 fwrite()、fread() 等流操作函数,操作结果可以反映到这段内存中。fmemopen() 使用示例:#include <stdio.h>#include <stdlib.h>#include <string.h>char *write_to_buf(char *原创 2021-03-06 22:11:40 · 2518 阅读 · 0 评论 -
使用远程virt-manager安装虚拟机的步骤
使用远程 virt-manager 安装虚拟机大概有下面几步:1)使用 ssh -X 连上远程服务器;2)使用 virt-manager 启动图形界面;3)通过 virt-manager 创建虚拟机,并指定 iso 镜像 和 新建 qcow 文件,然后启动虚拟机;4)进入虚拟机后,找到系统安装程序并运行,按照提示依次执行安装步骤;5)安装成功后重启系统,再次进入,此时虚拟机就可以正常使用了。...原创 2021-03-02 09:30:07 · 2867 阅读 · 2 评论 -
GNU C中的复合语句
在 GNU C 中,复合语句可以像一个表达式一样使用,例如下面的代码:int a = ({ int z; int y = foo (); if (y > 0) z = y; else z = - y; z;});再比如,内核中定义的各种get_xxx()宏:#define get_current_user() \({ \ struct user_struct *__u; \ const str原创 2021-02-26 09:05:40 · 255 阅读 · 0 评论 -
使用unshare创建新的pid namespace
在 linux 上,可使用 unshare 命令或 unshare()系统调用来创建一个新的 namespace,其中也包括 pid namespace(内核版本至少需要是3.8),需要注意的一个小点是,默认情况下,unshare 创建的 pid namespace 是作用在被调程序的子进程上,如下所示:$ sudo unshare -p ./getpidpid: 27666使用 --fork 表示创建一个子进程,并在子进程中运行命令。可以看到 pid namespace 在子进程上生效了,第原创 2021-02-25 10:36:48 · 1142 阅读 · 0 评论 -
动态链接的可执行程序的加载过程
1)内核在装载完 ELF 可执行文件以后就返回到用户空间,将控制权交给程序的入口。对于不同链接形式的 ELF 可执行文件,这个程序的入口是有区别的。对于静态链接的可执行文件来说,程序的入口就是 ELF 文件头里面的 e_entry 指定的入口;对于动态链接的可执行文件来说,如果这时候把控制权交给 e_entry 指定的入口地址,那么肯定是不行的,因为可执行文件所依赖的共享库还没有被装载,也没有进行动态链接。所以对于动态链接的可执行文件,内核会分析它的动态链接器地址(在“.interp”段),将动态链接器映射原创 2021-02-22 14:49:27 · 489 阅读 · 1 评论 -
类型定义typedef
C 语言提供了 typedef 关键字,用来建立新的数据类型名,例如,声明typedef unsigned int Length;将 Length 定义为与 int 具有同等意义的名字,它和类型 int 完全相同,可以用于类型声明、类型转换等。注意:typedef 中声明的类型在变量名的位置出现,在语法上类似于存储类型 extern、static 等。 typedef 声明并没有创建一个新类型,它只是为某个已存在的类型增加了一个新的名称。 通过这种方式声明的变量与通过普通声明方式声明的原创 2021-02-19 22:50:37 · 365 阅读 · 0 评论 -
linux下查看pid namespace的方法
1)方法一使用 lsns 查看下面展示了当前系统中只有一个 pid namespace,其 inode 号是 4026531836,该 pid namespace 中的最小 pid 是 1,即 init 进程$ lsnsNS TYPE NPROCS PID USER COMMAND4026531836 pid 77 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 224026531837 user原创 2021-02-18 15:09:34 · 3854 阅读 · 1 评论 -
数字图像的灰度拉伸
成像系统只能获取一定亮度范围内的值。由于成像系统的量化级数有限,常出现对比度不足的弊病,图像看起来比较模糊、暗淡。通过灰度拉伸可加大图像的对比度,使图像变得更加清晰。灰度拉伸分为线性拉伸和非线性拉伸两种方法。1、线性拉伸对像素值进行线性比例变化,主要有以下几种方法:全域线性拉伸 2%线性拉伸 分段线性拉伸 灰度窗口切片(可将某一区间内的灰度级和其他部分分开)2、非线性拉伸使用非线性函数对图像进行拉伸变化,常用的非线性函数有指数函数、对数函数、平方根、高斯函数等。其中,指数变换对于图像中亮原创 2021-02-14 10:48:45 · 5619 阅读 · 0 评论 -
辐射到达遥感探测器的各种路径
太阳辐射在真空传播时几乎不受任何影响。然而,当它与地球大气交互作用时,会发生选择性散射和吸收,这两种能量损失总称为大气衰减。理想状况下,相机或探测器记录的辐射是瞬时视场内以一定立体角离开目标地面的辐射量的函数。然而,其他辐射能会通过各种不同路径进入瞬时视场,从而给遥感处理带来混淆噪声。因此,需要梳理辐射到达遥感探测器的各个路径,如下所示:路径 1 包含的是太阳光谱辐照度,它照射到瞬时视场内的地面之前几乎没有衰减。这里我们感兴趣的是某些特定太阳天顶角的太阳光谱辐照度,而且到达地面的辐照度是该角度大气透原创 2021-02-13 19:16:36 · 558 阅读 · 0 评论 -
非选择性散射
当微粒的直径比入射波长大10倍以上的时候,就会发生非选择性散射。这种散射类型是非选择性的,即不仅蓝光、绿光或红光被散射,所有的光都被散射。因此,组成云雾的水滴和冰晶对所有可见光波长均等散射,使云呈现白色。几乎同比例的蓝、绿和红光的非选择性散射,总是呈现为一般观察者看到的白色光。这就是在雾中打开机动车的远光灯会使情况变得更糟的原因,因为这种情况会非选择性地散射更多的光进入我们的视野。...原创 2021-02-13 11:16:39 · 2083 阅读 · 0 评论 -
米氏散射
米氏散射发生在距离地面4.5km以下的低层大气中,这里有许多直径与入射辐射波长相当的球形微粒。微粒的实际尺寸可能是入射辐射波长的0.1 ~ 10倍。对于可见光来说,主要的散射介质是粉尘和直径为几十分之一微米到几微米的其他微粒。米氏散射比瑞利散射更强,且散射波长也更长一些。大气中的烟雾和粉尘越多,就会散射越多的紫光和蓝光,这时仅只有波长更长的黄光、橙光和红光到达人眼。因此,污染能够对美丽的日出和日落做出贡献。...原创 2021-02-13 11:09:28 · 5276 阅读 · 0 评论 -
瑞利散射
当物质(一般指大气中的氧分子和氮分子)的有效直径比入射辐射的波长小很多倍(通常小于0.1)的时候,就会发生瑞利散射(通常也称分子散射)。所有的散射都是通过原子或分子辐射的吸收和再次发射完成的。由于无法预测某个特定的原子或分子发射光子的具体方向,因此称之为散射。散射总量与辐射波长的4次方成反比。例如,紫外光(0.3μm)的散射大概是红光(0.6μm)的 16 倍,即 (0.6 / 0.3)^4 = 16;蓝光(0.4μm)的散射大约是红光(0.6μm)的 5 倍,即 (0.6 / 0.4)^4 = 5原创 2021-02-13 10:50:17 · 6754 阅读 · 0 评论 -
C语言中的#line宏
在 C 语言中, __FILE_ 表示当前正在被编译的源文件名字的字符串字面值,__LINE__ 表示当前源文件行数的十进制常量,而 #line 可以改变上述两个宏的内容,即为其指定新的值。主要有以下两种形式:#linelinenum#linelinenumfilename上述调用将会使编译器认为:下一行源代码的行号是从 linenum 开始,并且,当前的输入文件有 filename 给出。以下为示例代码:#include <stdio.h>int main...原创 2021-02-10 18:01:22 · 4826 阅读 · 0 评论 -
在linux中使用setns()设置pid namespace
以下代码展示了 setns() 的用法,#define _GNU_SOURCE#include <fcntl.h>#include <sched.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/wait.h>#in原创 2021-02-10 08:47:36 · 3573 阅读 · 0 评论 -
linux下cscope的配置
1、cscope 安装比较简单,略过。2、cscope 数据库文件生成在利用 cscope 来搜索代码之前,需要先为项目源码生成一个 cscope 数据库,生成的方法主要有以下两种:1)对项目源码的根目录执行:cscope -R 命令,该命令会递归的去解析所有子目录,并在当前目录下生成一个cscope.out的文件。$ cscope -R2)上述命令会解析所有以 .c、.h、.y、.l 结尾的源文件,这里面有两个小问题,第一,我们无法排除某些文件,第二,除了以上述几种后缀结尾...原创 2021-02-07 23:43:31 · 939 阅读 · 0 评论