- 博客(124)
- 收藏
- 关注
原创 git常用操作大全
1. git diff不接参数,顺序展示多个文件的差异内容(和暂存区内容对比);接参数filename,展示指定文件的差异内容(和暂存区内容对比);接参数–cached,暂存区和本地仓库进行对比。2. git checkout -b [branch_name]创建一个新的本地分支3. git branch -vv查看本地分支的跟踪情况4. git branch -a查看所有分支(包括远程分支)5. git branch -D [branch_name]删除本地分支
2024-08-12 21:46:30
456
原创 如何撤销/回滚远程修改
通过git revert commit_id,撤销指定commit,然后push到远程分支,即可撤销指定commit的修改,并新增一个revert的提交记录。到远程分支,这样对应的历史提交就被删除了。否则就需要解决冲突之后再提交,但是此情况会产生一个新的commit。,不出现冲突的情况下就可以直接。
2024-07-27 13:56:14
267
原创 C++多线程编程之互斥锁
为什么会出现这种情况呢,简单分析下原因,每次加1时,数据都会从内存加载到寄存器,如果taskC某次从内存读到寄存器的值是100,此时失去cpu,taskD也从内存读到100,然后做加1,再写回内存,此时sum的实际值是101,如果此时taskC再次获得cpu,他会计算sum=100+1,sum的值还是101,这就有问题了。这属于数据同步的问题,为了解决这种问题,于是就有了互斥锁。主要有lock、try_lock和unlock三种接口,其中lock失败会阻塞线程,成功则获得锁的所有权。
2024-07-22 18:52:08
322
原创 lock_guard和unique_lock的区别与使用
std::unique_lock具有lock_guard的功能,但同时unique_lock可以使用mutex的接口lock和unlock来主动加锁和释放锁,而lock_guard是不支持的。std::lock_guard 是 C++11 引入的一个模板类,位于 <mutex> 头文件中,用于实现 RAII(Resource Acquisition Is Initialization)模式的锁管理,确保锁的自动获取与释放,即使在异常情况下也能正确释放锁,防止死锁。
2024-07-22 18:51:45
309
原创 设计模式总结
设计模式的目标是管理变化,提高代码复用。在使用模式的时候,应该非常明确需求的变化点与稳定点,否则设计模式不一定适用。另外,设计模式给予我们的只是一个参考,我们更应该关注和掌握的是设计原则,有了对设计原则的深刻理解,在设计代码的过程中,我们也能设计出适合我们自己业务场景的设计模式,这才是学习设计模式最终应该达到的层次。
2024-07-19 19:43:22
1185
原创 C++多线程std::thread使用详解
join代表主线程会阻塞到该线程结束后才会退出,通常情况下配合joinable(是否为可连接状态)使用,因为只有可连接状态的线程才可以调用join。detach模式下需要考虑引用或者指针参数的生命周期问题,在主线程退出之后,它们的资源会被释放,此时子线程有可能访问到无效内存,导致程序崩溃。此时,作为const引用,thread在传递参数的时候,也可以进行值传递,但是考虑性能的情况下,推荐按引用传递。需要注意的是,因为是指针,所以被传递对象的生命周期必须大于线程的生命周期。
2024-07-19 18:37:06
394
原创 C++内存对齐
通常情况下,cpu取数据是按照内存单元取的,而内存单元的地址是对齐的。这就意味着,内存对齐的情况下,cpu取某个地址上的数据(它存储在某个内存单元),只需要取一次即可。这里有一个原则,就是尽量将对齐字节数大的成员声明在前面,从而减少内存对齐时,带来额外的内存开销。c的偏移地址是9,但c要按照2字节对齐,所以要填充一个字节,也就是x所占的位置,因此,c的偏移地址变成了10,可以对齐。对于类或者结构体的对齐,首先考虑内部各变量自身的对齐,其次再考虑类作为一个整体,也需要按照最大的数据成员去对齐。
2024-07-17 23:04:06
472
原创 装饰模式原理与C++实现
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。装饰模式属于结构型模式,它是作为现有的类的一个包装。通过使用组合而非继承的方式,实现了运行时动态扩展对象功能的能力,并且根据需要可以扩展多个功能,避免继承带来的灵活性差和多子类衍生的问题。装饰类在接口上表现为is-a Component的继承关系,继承了Component的所有接口。但是在实现上,又表现为has-a的组合关系,即装饰类又使用了另一个Componet类。
2024-07-17 22:57:05
791
原创 模板方法原理与C++实现
定义一个操作中的算法骨架(稳定的),而将一些步骤的实现延迟到子类中(变化的)。模板方法使得子类可以复用一个算法的结构,而只改变(重写)这个算法的特定步骤。模板方法是一种非常实用且常见的设计模式,它使用简单的机制(虚函数)为应用程序框架提供了灵活的扩展点。模板方法中被模板方法调用的虚函数可以有具体实现,也可以没有任何实现(纯虚函数),但一般访问权限为protected,因为作为算法的一部分,它没有对外单独开放的必要。
2024-07-15 18:27:04
324
原创 策略模式原理与C++实现
定义一些列算法,把他们一个个封装起来,并且使他们可以相互替换(变化)。该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展、子类化)。Strategy及其子类为组件提供了一系列可重用的算法,使得类型在运行时方便的根据需要在各算法之间切换。策略模式消除了条件判断语句,含有许多条件判断的语句往往可以使用策略模式来解耦合。如果Strategy对象没有数据成员,那么各个上下文之间可以共享同一个Strategy对象,从而节省对象开销。
2024-07-15 18:26:17
488
原创 C++性能优化篇:map与unordered_map的正确使用
在一次代码修改中,我尝试了下使用unordered_map替换map来存储中间结果,发现程序耗时降低了67%,于是仔细分析了下两者的区别。两者都是C++标准库中提供的关联容器,用于存储键值对。,明显降低了复杂度。所以,在不考虑有序性和范围查找的时候,应该使用。简单分析下上述函数的时间复杂度,第一个for循环的时间复杂度为。,在处理大量数据的时候,其效率会更高。,第二个for循环的时间复杂度为。
2024-06-28 08:58:41
364
原创 C++性能优化篇:使用memcpy替代for循环
在做内存数据拷贝的时候,应减少循环,尤其是嵌套循环,多使用memcpy,这样既容易理解,又可以提高程序性能,何乐而不为呢?还有一种提升内存拷贝性能的方式,就是使用并行拷贝的方式。在编写程序的时候,可以考虑使用多个线程,每个线程拷贝其中一段内存。
2024-06-28 08:58:06
657
原创 C++性能优化篇:深拷贝、浅拷贝与移动构造
在做性能优化的时候,遇到数据量较大的场景,减少不必要的数据拷贝,是可以极大得提高程序性能的。移动语义可以帮助我们实现在浅拷贝的同时,又能避免资源重复释放的问题。但是使用移动语义也要注意,被移动的对象在移动完成之后,不能再被使用,否则可能出现未知错误。
2024-06-26 17:04:37
500
原创 Makefile并行执行
最近在编译项目代码的时候,发现全量编译一次代码需要十分钟,加了多核编译参数之后,还会出现各种错误,导致编译失败。于是我就想改造下makefile文件,使其能够多核编译,经过改造之后,效果显著,8核编译的情况下,只要1分半,编译速度提高了7倍(为之惊奇)。因为依赖关系是c依赖d,那么必须等d执行完,而b又依赖c,就得等c执行完。多核编译的情况下,会并行编译多个cpp文件,从而提高编译效率,并且增量编译也只会编译有修改的cpp文件。,完全没有问题,他会依照d、c、b、a的顺序去执行各个规则。
2024-06-15 00:31:31
536
原创 git revert的使用
就可以将指定commit id的修改撤销,然后提交此次撤销操作即可。需要注意的是,如果C2处修改的地方在C3或者其他提交节点也有过修改,那么revert就会出现冲突,就需要手动解决冲突后再提交。由于某种原因我们需要撤销掉之前某一次的修改,但是这个修改已经提交,并且后面又经历了好几轮的提交。
2024-04-26 17:37:56
220
原创 在no branch上commit后,再切换到其他分支,找不到no branch分支的修改怎么办?
在no branch上commit后,再切换到其他分支,找不到no branch分支的修改怎么办?
2024-04-26 09:29:40
447
原创 git简单实践
此处就是过滤app、compile.sh、一些中间缓存文件、目标文件等,此时再使用。查看的时候会发现有些文件就是临时文件,不需要提交,你可以创建一个。注意不要添加了不需要提交的文件,
2024-04-17 10:35:07
322
原创 string_view使用详解
std::string_view是C++17引入的一个轻量级、非拥有字符串引用类,它主要用于高效地传递和操作字符串数据,而无需复制字符串本身。
2024-04-15 11:07:27
410
原创 C++17新特性总结
C++17 是继 C++14 之后的一个重要版本,引入了许多新特性和改进,旨在提高编程效率、简化代码以及增强标准库的功能。
2024-04-11 18:01:44
2171
原创 C++14新特性总结
C++14是对C++11标准的一个较小但重要的补充和改进,它在保持向后兼容性的同时,引入了一系列旨在提高代码简洁性和效率的新特性和增强功能。
2024-04-11 16:28:18
1608
原创 std::forward完美转发
C++完美转发是一种利用万能引用和std::forward函数模板来精确传递参数值类别,特别是右值引用和移动语义的能力,从而提升代码效率和资源管理的技术。
2024-04-11 14:43:12
453
原创 右值引用和移动语义
右值引用和移动语义是C++11中用于优化资源管理和提高程序性能的重要工具。它们使得程序能够在保证语义正确的情况下,以较低的成本转移大型对象的所有权,而非进行深度复制,从而显著减少了不必要的内存分配和数据复制,特别是在处理大量数据或昂贵资源时效果尤为明显。
2024-04-11 14:36:09
283
原创 C++11新特性总结
C++11是对C++编程语言的一次重大更新,它引入了大量新特性和改进,旨在提高代码的效率、可读性、安全性以及程序员的生产力。
2024-04-11 14:18:38
447
原创 C++计算程序运行时间
有时候我们需要简单计算下程序的运行时间,但又不想借助工具,而是简单的几行代码来粗略计算下时间,话不多说我们直接开始吧。如果我们多处地方都要计算执行时间,那就要重复去写好几遍这段代码,不太方便。duration的第二个模板参数不写时,即为秒级别时间。
2024-04-10 10:29:46
843
原创 C++中的string类操作详解
针对C++中的string,本文主要讲解如何对其进行插入、删除、查找、比较、截断、分割以及与数字之间的相互转换等。
2024-04-08 17:44:23
1622
1
原创 STL关联容器之map使用详解
插入数据时,应尽可能的避免额外的构造和析构开销,因此建议选用emplace,而不是insert。但是注意的是,key存在时,insert效率反而更高。删除数据时,目标迭代器就会失效,注意不能再对目标迭代器做任何操作。查找目标key时,为避免二次查找,应使用find方法以提高代码效率。
2024-04-01 19:41:42
1067
1
原创 记录一次数组越界导致的线程死锁问题
pthread_cancel并不一定保证线程被释放,它只是给目标线程发送了一个信号,而只有当目标线程到达一个取消点(系统调用)时,目标线程才会退出。如果需要等待线程退出,应该调用pthread_join来保证这一点。上述代码中,如果在cancel之后调用该函数,程序会出现段错误,因为在使用线程相关的信息时,拿到的是一个空值。在对字符数组进行赋值时,c语言提供的一些函数并不安全,很多时候越界却不自知。
2024-03-28 18:09:15
747
原创 vim设置文本或代码缩进
softtabstop的值不为0时,当按下tab键后,会插入对应数量的空格符,而当其值为0时,则插入的是制表符。为避免在不同环境下打开文本时制表符宽度不一致,可以设置softtabstop。
2024-03-21 15:03:32
207
原创 shell三剑客之sed
作为文本处理的三剑客之一,sed的使用也是非常频繁的,通常适用于对文本中匹配的行或字符串进行替换、删除、添加等处理。i:可选参数,表示对文本直接操作,会修改文本内容,不加该参数则不修改。g:表示替换所有匹配的串,不加则只替换一次。filename:要操作的文件名。str1:表示要替换的目标串。str2:表示替换后的新串。
2024-03-04 18:01:47
204
原创 C++缺陷与思考
很明显,我对C++的思考仅限于C++语言本身,至于其他语言我很少涉及,因此,不能够通过与其他语言的对比中,发现C++更多的不足。因为不知道别人有多好,所以我总以为C++给予我的就是它最好的,但事实上它也有很多缺陷。当然,一切相遇都是最好的安排,既然选择了C++,那它就是最好的,不忘初心(学好C++),方得始终。
2024-02-29 17:58:38
461
1
原创 shell三剑客之grep
作为文本处理的三剑客之一,sed的使用也是非常频繁的,通常适用于对文本中匹配的行或字符串进行替换、删除、添加等处理。i:可选参数,表示对文本直接操作,会修改文本内容,不加该参数则不修改。g:表示替换所有匹配的串,不加则只替换一次。filename:要操作的文件名。str1:表示要替换的目标串。str2:表示替换后的新串。
2024-02-27 18:08:56
199
1
原创 Linux下如何生成coredump文件
在linux下执行程序,当出现coredump时,却发现没有生成core文件,或者生成了core文件却不知道在哪里,下面就讲述如何产出core文件,以及指定core文件的产出格式与路径。上述情况下仅限于个人使用时,修改core文件的产出。但linux作为服务器使用时,则需要更加完整的core文件名,包括时间戳,进程名等等。在当前路径下产出core文件,文件名为core,如果配置了pid后缀,文件名则为core.pid。使得core文件的大小不受限制,能够产出完整的core文件。此命令只会对当前终端有效。
2024-02-27 18:06:55
581
原创 coredumctl的使用与gdb调试
可以看出程序最终是在调用函数func时崩溃的(对空指针进行解引用)。–since=today:表示只显示今天的coredump信息列表。可以看到PID=437990进程崩溃时的相关信息。EXE:出现段错误时,运行的程序名。通过上述命令即可生成core文件。PID:出现段错误的进程id,
2024-02-27 18:05:05
333
原创 gdb调试进阶之disassemble
在gdb调试的过程中,除了会使用基本命令外,我们还可以学会使用一些进阶命令,比如dissassemble,它是一个反汇编命令,即将目标代码反汇编成汇编代码。有时候我们使用的可执行程序并不带有调试信息,也就无法看到实际代码的执行结果,但是我们可以通过汇编代码来查看程序在执行过程中出现的异常崩溃等问题。通过打印rax寄存器rax中的值也可以看出其保存的地址值是0,也就是空指针,那么对0进行寻址,必然会失败。实际上,生产环境中程序崩溃的定位会复杂很多,此处结合disass的使用只提供了一点点的思路。
2024-02-27 18:03:27
1076
原创 gdb调试进阶之x命令
examine/x命令是用于显示内存中的值。其命令格式:x/[n/f/u] [addr]s:如果内存指向的值是字符串,那么格式就是s。u:以多少个字节作为一个内存单元,默认为4。i:如果内存指向的值是指令,那么格式就是i。n:正整数,表示可显示的内存长度。u:十六进制无符号格式显示。addr:要显示的目标内存。x:十六进制格式显示。
2024-02-27 11:51:11
882
原创 C++中如何获取虚表和虚函数的地址
funcB_addr2:将vtable_addr + sizeof(intptr_t),先强转为指向虚函数地址的指针,再解引用,即得到第二个虚函数的地址,对于32位系统sizeof(intptr_t)的值为4,64位系统则等于8。funcB_addr就类似p1,funcB_addr2类似于p1_2,virtual_func_ptr类似于p,vtable_addr类似于addr,虚函数地址即为元素,每个元素占sizeof(intptr_t)个字节。本文主要讨论如何获取。
2023-11-08 17:32:25
513
基于gmock实现的cppmockfree的使用方法总结
2023-08-30
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人