- 博客(124)
- 收藏
- 关注
原创 whois为什么有时会返回两个不同的域名状态
前阵子发现一直想注册但被别人注册了的一个域名快要过期了,就想着写个脚本跑在电脑上,每分钟检查一次域名状态,一旦域名被正式删除,就发封邮件通知我,这样就不用频繁手动检查域名状态了。
2025-04-28 21:14:33
557
原创 python数据分析一例:使用SQL和pandas对数据进行聚合和diff
虽说单独使用pandas也足够实现这个需求,但是考虑到类似的流水数据很多都是存在DB里的,检索数据时聚合一下也就顺手的事,因此聚合数据就交给SQL来做了。对一系列数据聚合后进行diff,是一种常见的数据分析需求。例如,我们可能会需要将每个月的财务支出流水数据进行分类汇总,再对不同月的汇总数据进行比较,看看哪些分类支出变多了,哪些变少了。此次我将使用SQL和pandas来实现上面所述需求,具体来说,使用SQL实现数据聚合功能,使用pandas对聚合后的数据进行diff。
2024-12-11 20:48:34
295
原创 Linux:bash在被调用时会读取哪些启动文件?
bash在被调用时会读取哪些启动文件?要回答这个问题,首先要弄清楚两个概念:login shell和interactive shell。
2024-07-28 21:40:32
503
原创 Qt:愚蠢的qmake
博主参与了一个使用qmake构建的项目,包含几百个源文件,最近遇到一个恼人的问题:有时仅仅修改了一个.cpp文件,构建项目时就有可能触发全编译。但是编译时又会命中ccache的缓存,这说明源代码实际上内容并没有发生变化。
2024-07-21 23:25:54
943
1
原创 Linux:使用vim编辑文件为什么会影响目录的mtime
touch一个存在的文件,文件的mtime发生了更新,文件所在目录的mtime不会更新;而使用vim编辑这个文件后再保存,文件和文件所在目录的mtime都会被更新。为什么会这样呢?本文将解释一下这种现象的成因。
2024-07-18 23:35:28
670
原创 C++:std::function的libc++实现
`std::function`是个有点神奇的模板,无论是普通函数、函数对象、lambda表达式还是`std::bind`的返回值(以上统称为可调用对象),无论可调用对象的实际类型是什么,无论是有状态的还是无状态的,只要它们有相同参数类型和返回值类型,就可以使用同一类型的`std::function`进行存储和调用。这种特性被称作类型擦除
2024-06-30 22:36:48
1225
原创 Linux:在使用UEFI固件的计算机上内核是如何被启动的
启动计算机通常不是一件难事:按下电源键,稍等片刻,你就能看到一个登录界面,再输入正确的密码,就可以开启一天的网上冲浪之旅了。但偶尔这件事没那么顺利,有时候迎接你的不是熟悉的登录界面,而是一个令人生畏的命令提示符界面,一闪一闪的提示符告诉你:“你碰到麻烦了”。于是你对着错误提示查找解决方法,按照网页上的步骤,你对着提示符输入并执行了几条你完全不理解的命令,计算机又能正常启动了,但同时你发现你那存有大学舍友糗照的硬盘分区被清空了。
2023-08-05 16:12:08
2447
原创 bash:如何直接diff两条命令的输出
如果我们想要diff两条命令的输出,一种容易想到的做法是将两条命令的输出分别重定向到两个文件中,然后diff两个文件的内容:$ readelf -WS ./a.out > a.txt$ readelf -WS ./a.out.full > b.txt$ diff a.txt b.txt而bash的Process Substitution机制可以帮助我们简化类似上面这类工作,把三条命令合并成一条:$ diff <(readelf -WS ./a.out) <(reade
2022-05-12 21:56:41
968
原创 Go:实现接口时指针接收器和值接收器的区别
在为类型定义方法时,如果没有避免拷贝或在方法中修改对象的需求,那选择指针接收器和值接收器区别不大。大多数情况下,我们可以通过指针直接调值接收器方法,也可以通过值直接调指针接收器方法,go会为我们自动做值和指针之间的转换:type A struct { d int}func (a A) print() { fmt.Println(a.d)}type B struct { d int}func (b *B) print() { fmt.Println(b.d)
2021-06-12 21:48:56
2894
原创 Go:fmt.Print系列函数为什么默认情况下不打印结构体中指针字段指向的值?
在Go中,一个结构体如果含有一个指针字段,在默认情况下,使用fmt.Print系列函数打印这个结构体时,并不会打印这个指针指向的值。因此,对于下面的代码:type Foo struct { A int}type Bar struct { F *Foo}func main() { b := Bar{&Foo{1}} fmt.Printf("%+v\n", b)}其输出为:{F:0xc0000140a0}map也是类似的,如果map的value类型为
2021-05-22 19:01:15
1760
原创 Prometheus踩坑记录
为什么使用rate函数计算指标增长率时,Grafana绘制结果显示“No data”?使用Grafana绘制以下PromQL查询结果时,Grafana显示“No data”:rate(prometheus_tsdb_head_samples_appended_total[1m])但是查询prometheus_tsdb_head_samples_appended_total本身是能看得到数据的,这是为什么?使用Prometheus的Table视图查看数据:查询1:prometheus_tsdb_
2021-03-28 15:00:10
3721
原创 PAC和Proxy的关系
PAC和Proxy的关系问:PAC是什么?答:是Proxy Auto Config的缩写,实际上是一个JavaScript脚本。问:PAC脚本里面有什么?答:这个脚本包含了一个FindProxyForURL(url, host)函数。问:FindProxyForURL函数有什么功能?答:根据传入的url,可能会返回DIRECT或PROXY proxy.example.com:8080或类似的其他字符串,调用者可以根据这个返回的字符串选择使用一个Proxy或者不使用Proxy。问:PAC脚本保存
2021-03-14 19:20:41
2209
1
原创 蹭个热点:用bash统计csdn博客阅读量是否符合本福特定律
拜大洋彼岸国家大选所赐,本福特定律这两天在微博和知乎上突然火了起来,因为有人根据本福特定律推断大选投票结果有人为操纵的痕迹。那么什么是本福特定律呢?本福特定律的内容大致是这样的:对于一组样本足够大,且难以人为操控的自然十进制数据,如世界上所有国家的人口、面积、GDP等,其首位为n的数据占数据总量的比例为:P(n)=log10(n+1n)P(n)=\log_{10}\left(\frac{n+1}{n}\right)P(n)=log10(nn+1)计算下来,以1打头的数据占数据总量的30.10%
2020-11-09 22:07:23
405
2
原创 使用OpenGL实现ASCII Art滤镜
效果图:仓库地址:https://github.com/im-red/asciiart_gl之前使用Qt实现过一个CPU版本的ASCII Art滤镜,流程大致如下:根据字体选择确定单元方格大小。将每个可用字符绘制到单元方格大小的空白图片上,计算每个可用字符的平均灰度值。根据第二步计算出来的每个可用字符的平均灰度值,生成一个0~255灰度值到字符的映射表。按单元方格大小对输入图片进行划分,灰度化后求每个方格的平均灰度值。查询灰度值到字符的映射表,对输入图片的每个方格使用字符进行填充。CP
2020-10-25 16:47:27
365
原创 Qt:监控一个QObject对象发射的所有信号
如果我们想要监控一个QObject对象发射的所有信号,同时又不追求手段的通用性的话,可以给目标对象的每个信号写一个槽函数,然后手动connect。这听起来就麻烦,有没有不那么麻烦的通用方法呢,自然是有的。如果能对Qt的信号槽原理进行一点深入的探索,我们就能以很简单的方法达到我们的目的。以下代码均基于Qt5.12.7。信号槽的连接保存在sender的metaObject中,其数据结构为QObjectPrivate::Connection:struct Connection{ QObject *
2020-10-08 18:08:12
2852
原创 为什么std::priority_queue有一个构造函数接受Compare类型对象作为参数?
在我之前写的一篇博客《使用decltype取函数类型遇到的“invalidly declared function type”问题》中,最近收到一条评论:X: 想问问,既然模板里面已经传入了comp指针了,为什么构造函数里还要再传一次呢?我先把情境描述的更清楚一些,std::priority_queue是优先队列的标准库实现,其声明如下:template< class T, class Container = std::vector<T&g
2020-09-08 21:51:35
1154
3
原创 localhost还是127.0.0.1,这是一个问题(并不是)
(本文内容仅针对Linux环境,内核版本4.15,thrift版本0.11.0,glibc版本2.27)localhost比127.0.0.1快?有江湖传言称,“使用localhost访问本机服务比使用127.0.0.1要快”,这有没有道理呢?自然是没有道理的,除了个别的特例(如https://www.php.net/mysql_connect)因为会对localhost做特殊处理(使用UNIX domain socket替代TCP socket)所以可能快一点(存疑,未验证)外,其他情况使用loca
2020-07-29 22:59:27
2032
原创 Linux:利用内核日志记录系统启动时产生的进程树
前言之前项目中遇到过一个bug,bug产生的原因是某个程序在两个不同的启动脚本中被同时启动了两次,系统中出现了两个实例。这个程序在代码内部没有保证单实例,靠shell脚本的pidof(1)命令保证单实例,然而因为两个启动脚本的启动时间太过接近,pidof(1)没能起作用,导致程序被启动了两次。出了这个bug后就想着需要梳理一下系统在启动时都运行了哪些脚本,这个系统“传承”了估计有七八年,启动脚...
2020-04-12 16:07:39
913
原创 四种迷宫生成算法的实现和可视化
(上图是使用随机化Prim算法生成一个200x200的迷宫的过程)Github项目地址:maze前言本文中的迷宫指的是最常见的那种迷宫:迷宫整体轮廓是二维矩形,迷宫里的格子是正方形的,格子上下左右各相邻另外一个格子(边和角除外),迷宫内部没有环路,也没有无法到达的格子,起点在一个角(本文中为左上角),终点在另一个角(本文中为右下角),从起点到终点有且仅有一条路径:每个格子都可以抽象成图...
2020-04-05 17:29:24
18077
2
原创 使用bash和graphviz分析并可视化C/C++源文件依赖关系
流程流程并不复杂:使用find命令搜索指定目录所有C/C++源文件扫描所有源文件,使用cpp(The C Preprocessor)过滤掉注释后,使用sed提取#include,生成依赖条目将所有依赖条目拼成.dot文件,然后使用graphviz中的dot工具将.dot文件转为.png图片代码代码的Github仓库为dep,为了方便~~(以及凑字数)~~放在这里一份:#!/bin...
2020-03-29 17:34:28
1784
原创 clang:FunctionDecl::isOutOfLine()和FunctionDecl::isInlined()能同时返回true吗?
最近读clang源码时发现这么一段代码:FunctionDecl *FD = ............if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { ...... if (MD->isOutOfLine() && ......) { ...... if (FD...
2020-03-16 00:32:46
529
原创 Qt:为什么QGraphicsView设置Antialiasing/SmoothPixmapTransform没生效?
QGraphicsView::setRenderHint有两个常用的选项:QPainter::Antialiasing和QPainter::SmoothPixmapTransform,前者是用来打开反走样功能,后者用来在对图片进行缩放时启用线性插值算法而不是最邻近算法。然而这两个选项都有一些坑,想达到预期的效果的话得做一些额外的功课。QPainter::Antialiasing和QOpenGLW...
2020-03-08 00:37:00
2932
原创 bash的几种特别的I/O重定向语法
下面这几种重定向语法都很简单,容易记住:ls > stdout.tx # 用标准输出覆盖stdout.txtls not-exist-file 2> stderr.txt # 用标准错误覆盖stderr.txtls exist-file not-exist-file > stdout.txt 2> stderr.txt # 用标准输出覆...
2020-02-22 14:41:23
424
原创 当std::bind遇到非静态类成员函数
之前看项目代码在实现表驱动方法时,经常会遇到这样的代码:// enum { ID0, ID1, ID2 };// std::map<int, std::function<void()>> Foo::m;// void Foo::func0(){}// void Foo::func1(){}// void Foo::func2(){}void Foo::init...
2020-02-11 21:32:53
1927
原创 QString和QByteArray
QString有一个未标记为explicit的构造函数QString(const QByteArray &ba),导致许多形参为QString的函数可以接受类型为QByteArray的实参,时间久了会会以为这两个类可以随意混用,但实际并不是这样,这两个类适用的场景还是有区别的。QString相较QByteArray更高级更抽象,QByteArray则更底层更具体。QString基本单位是...
2020-02-10 23:45:34
2328
原创 Linux C/C++调试之五:程序运行耗时的组成
分析程序出现的启动缓慢、响应缓慢和操作卡顿等性能问题时,第一步不该是打开代码编辑器浏览我们的代码,而是首先确定问题是否发生在我们的代码中,简单点的方法就是打开top做一个大致的判断,看一看各CPU的us、sy、id耗时的占比都是多少。进一步来讲,我们需要确定时间都花到什么地方了,是我们的代码中?内核中?还是进程睡大觉的地方?现在假设我们的程序运行在一个CPU资源丰富的环境中,因此就不考虑进程争夺C...
2020-01-11 23:00:24
1777
原创 条件变量为什么要和互斥量一起使用?
一个简单的使用条件变量的场景:主线程从stdin读取一个字符串,然后由echo线程打印这个字符串,正确的代码是这样的:#include <iostream>#include <condition_variable>#include <mutex>#include <thread>#include <string>#includ...
2020-01-02 21:56:01
1162
原创 Linux C/C++调试之四:callgrind的局限
在上篇文章中我介绍了callgrind的大致用法,可以看出来,callgrind是一个非侵入式的,使用起来也很傻瓜的调优工具。初用时感觉这个工具非常趁手,是个程序都想用callgrind去分析一下。但深入使用后发现,callgrind不是银弹,它还是有一些缺陷的。这些缺陷的根源在于:callgrind使用指令数来衡量性能,而程序员用耗时来衡量性能,指令数与耗时仅仅是一个正相关的关系,而非成比例的关...
2019-09-01 23:49:51
2018
1
原创 Linux C/C++调试之三:性能分析工具callgrind的使用
callgrind是valgrind工具套件中用于分析程序性能的一个工具,它能够得到粒度为函数、代码行和指令级别的性能数据,具体来说,我们可以得到某个函数、某行代码、某条指令处累计执行了多少条指令。我们看一个实例:// foo.cppint accumulate(int begin, int end){ int result = 0; for (int i = begin;...
2019-09-01 21:13:55
4107
原创 使用googletest测试可能断言或导致进程退出的函数
做单元测试,一般是验证函数输出数据与预期是否相符。但是也有例外,我们可能需要验证函数在接收到非法参数时是否会断言或抛异常,例如下面这个例子:int foo(int *p){ assert(p != nullptr); return *p;}当传给foo的实参为nullptr时,运行的预期结果就是断言后进程异常退出。这在单元测试中如何验证呢?如何不让这些验证异常值的用例干扰...
2019-08-26 23:41:56
2691
原创 gettimeofday和clock_gettime是不是系统调用?
在《Linux多线程服务端编程》一书5.1节中提到过,在x86-64的Linux上,gettimeofday不是系统调用,不会陷入内核。其实这种说法有点小问题,因为gettimeofday确实是个系统调用,但是linux的vdso(virtual dynamic shared object)机制帮我们做到了在调用这些系统调用时不陷入内核,从而提高了性能。vdso机制说白了就是在用户空间帮我们实现...
2019-08-25 16:13:07
6387
1
原创 Qt使用OpenGL进行多线程离屏渲染
基于Qt Widgets的Qt程序,控件的刷新默认情况下都是在UI线程中依次进行的,换言之,各个控件的QWidget::paintEvent方法会在UI线程中串行地被调用。如果某个控件的paintEvent非常耗时(等待数据时间+CPU处理时间+GPU渲染时间),会导致刷新帧率下降,界面的响应速度变慢。假如这个paintEvent耗时的控件没有使用OpenGL渲染,完全使用CPU渲染。这种情况处...
2019-07-28 11:58:14
16805
29
原创 linux下监控shell脚本或可执行程序启动过的子进程
使用history命令可以查看在shell中直接执行过的命令,但是无法查看间接执行过的命令,或者说启动过的子进程。举个例子,shell脚本或者make命令都会启动一些子进程,这些子进程并不会显示在history命令的输出中,那么如何监控他们启动过哪些子进程呢?首先需要明确的是,shell脚本靠得也是sh可执行程序加载执行,./foo.sh的效果一般等同于sh ./foo.sh,因此监控shell...
2019-07-21 11:34:42
1464
原创 利用libtooling提取C++中enum值与名的映射
之前的一篇文章中,有思考过如何将enum的值与名进行映射,其中一种方法是利用工具进行预处理生成。最近由于项目中有类似的需求,所以学习了libclang,写了一个小工具实现映射。整体流程非常简单:匹配enum声明的AST节点。获取enum声明AST节点的类型(即枚举类名前面附上作用域)获取enum声明所在文件名(用于过滤系统头文件中的枚举)获取enum声明所在文件行号(可用于区分同一命名...
2019-06-04 23:57:16
1696
1
原创 ptrace系统调用的实现
最近遇到这样一个问题,机器跑着跑着画面冻结了,打开top看到Xorg的cpu占用率100%。想用gdb挂上去看一下,结果gdb一直卡着挂不上去。后来又换用perf分析,结果发现进程99%的时间花在了一个ioctl调用。这个ioctl操作的是nvidia显卡,进程实际上是卡在了nvidia的驱动中。我对gdb挂不上去这件事感到很好奇,之前除了因为进程已经被另一个gdb调试而导致gdb挂不上去之外,...
2019-05-12 15:32:28
2896
原创 Qt在Linux下如何查找可用字体
最近遇到一个问题:一个Qt程序在Windows上正常运行,在Linux下编译运行后汉字就全变成方块了,成了名副其实的“方块字”。我一开始考虑是字符编码问题,调用QChar::unicode检查中文字符的编码,发现没有问题。如果不是编码问题,那就需要考虑是字体问题了。然后就安装了文泉驿字体,然后将控件字体设置为文泉驿,发现还是没有用。调用QFontDatabase::families检查所有可...
2019-04-09 20:58:13
4352
原创 C++11中静态局部变量初始化的线程安全性
前言大家都知道,在C++11标准中,要求局部静态变量初始化具有线程安全性,所以我们可以很容易实现一个线程安全的单例类:class Foo{public: static Foo *getInstance() { static Foo s_instance; return &s_instance; }private: F...
2019-04-07 15:03:31
14463
3
原创 Myer差分算法(Myer's diff algorithm)
Myer差分算法是一个时间复杂度为O(ND)的diff算法,就以diff两个字符串为例,其中N为两个字符串长度之和,D为两个字符串的差异部分的总长度。这个算法首先发表在An O(ND) Difference Algorithm and Its Variations。Myer差分算法直接解决的问题是最长公共子序列(LCS)的等价问题——最小编辑脚本(SES)问题。当然了,这是论文中的表述,在我看来...
2019-04-03 21:51:41
5028
原创 编辑距离算法和Levenshtein距离算法
前言最近在研究diff工具的实现,已经写了一个简单的demo,不过目前这个demo只是把Levenshtein距离算法的结果用Qt可视化了出来而已,还没有实用价值,界面如下:各种diff工具的核心基本都是编辑距离算法,网上许多文章把编辑距离算法等同于Levenshtein距离算法,但实际上Levenshtein距离算法只是各种编辑距离算法其中之一。各种编辑距离算法会使用不同的编辑操作种类,例...
2019-03-25 20:53:47
1996
原创 C++:shared_ptr的隐式转换
最近遇到这样一个编译问题,代码是这样的:#include <memory>#include <iostream>class Base{public: virtual ~Base() {}};class Derived : public Base{public: ~Derived() {}};void processSpBase(s...
2019-03-22 00:04:03
5143
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人