Makefile如何使用

工程化编译项目时,Java用Maven\Gradle,前端用npm,C/C++用Make
使用Make命令编译C/C++时,是通过Make工具实现。推荐使用w64devkit
w64devkit支持Linux命令

  • 根据更改的源文件,自动确定需要更新哪些文件。它还自动确定更新文件的正确顺序,以防一个非源文件依赖于另一个非来源文件。
    因此,如果您更改一些源文件,然后运行Make,则不需要重新编译所有程序。它只更新那些直接或间接依赖于您更改的源文件的非源文件。
    如何确定依赖的呢,来源与我们在Makefile中指定的dependencies
  • Make不限于任何特定的语言。所有能在命令行运行的编程语言都能处理(Java\Golang\Python…)。另外基于文件的改变然后更新另外的文件也可以。

Makefile中的一条规则告诉Make如何执行一系列命令,以便从源文件构建目标文件。它还指定了目标文件的依赖项列表。此列表应包括用作规则中命令输入的所有文件(无论是源文件还是其他目标文件)。

1
2
3
target:   dependencies ...
commands
...
1
2
3
4
hello: hello.o
g++ -o hello hello.o
hello.o: hello.cpp
g++ -c hello.cpp

更新机制

运行Make时,可以指定要更新的特定目标;否则,Make会更新makefile中列出的第一个目标。当然,必须首先更新生成这些目标所需的任何其他目标文件作为输入。
Make使用makefile来确定哪些目标文件应该更新,然后确定哪些文件实际上需要更新。如果目标文件比其所有依赖项都新,那么它已经是最新的,不需要重新生成。其他目标文件确实需要更新,但顺序正确:每个目标文件都必须重新生成,然后才能用于重新生成其他目标。

Makefile文件命名

Make自动查找makefile文件,顺序为GNUmakefile>makefile>Makefile
GUNmakefile:不建议使用,只能支持GUN make
makefile:所有版本都能识别
Makefile:推荐,最常用

运行make时没有找到上述文件会报错,但可以手动指定文件名

1
2
make -f <filename>
make --file=<filename>

香港卡全攻略

为什么要办香港卡?

保险?参与港美股?参与加密货币?OpenAI付费?公司股票不转回?对于我来说,听着牛逼想要但又不是必须的理由。最后决定办理是因为觉得港股券商入金有奖励,家人可以顺便去玩一圈。

选择哪个银行?

有那么多银行,我们可以办哪些,哪些又比较好呢?
从发币行角度考虑

  • 香港上海汇丰银行
  • 渣打银行(香港)
  • 中国银行(香港)
    三家银行都是在全球开展业务。从网上的信息来看汇丰和中国银行很好办,渣打不太好办。
    另外虚拟银行众安银行、天星银行、蚂蚁银行等,没有考虑和办理就不列了。
香港上海汇丰银行 中国银行
总部 伦敦 中国
办理难度 容易 容易
转汇费用 据说同名内地香港互转不要手续费 同名内地香港互转不要手续费

听说汇丰和中国银行从内地卡转入香港卡不要手续费。我办了汇丰之后就飘了不想再办就出去玩了。回来内地后去汇丰银行办理内地卡,没想到她直接告诉我只接待Premier客户,有存款要求不然有管理费。

怎么办理?

两种方式

  • 直接到营业网点线下排队办理

    如果人多去晚了可能无法办理,或者预约的人数多也可能被拒绝

  • 网上预约,再到网点办理

    网上预约后无需再早去现场排队拿号,直接告诉接待人员,然后就给你安排了

Read More

C++编译器有哪些

没想到C++环境搭建都这么麻烦,编译器有很多种。

没有研究是觉得有些复杂。

在编译时会将我们include,#define等合并成一个文件。那如何看到这个编译的中间文件呢?
在Visual Studio中设置
Preprocess to a File

代码

1
2
3
4
5
6
#include <iostream>

int main() {
std::cout << "Hello World!" << std::endl;
std::cin.get();
}

Ctrl + F7编译后,可以从Debug目录下看到FileName.i文件中已经包含了include的 iostream代码

注意:Visual Studio和Visual Studio Code是不同的工具

下一个看看C++如何建立link,为什么C++中不像java一样需要导入包,就可以link,然后引用呢?如果有两个同名的函数,那link的时候会报错吗?

netlink

什么是Netlink通信机制

Netlink是linux提供的用于内核和用户态进程之间的通信方式。

但是注意虽然Netlink主要用于用户空间和内核空间的通信,但是也能用于用户空间的两个进程通信。只是进程间通信有其他很多方式,一般不用Netlink。除非需要用到Netlink的广播特性时。

那么Netlink有什么优势呢?

一般来说用户空间和内核空间的通信方式有三种:/proc、ioctl、Netlink。而前两种都是单向的,但是Netlink可以实现双工通信。

Netlink协议基于BSD socket和AF_NETLINK地址簇(address family),使用32位的端口号寻址(以前称作PID),每个Netlink协议(或称作总线,man手册中则称之为netlink family),通常与一个或一组内核服务/组件相关联,如NETLINK_ROUTE用于获取和设置路由与链路信息、NETLINK_KOBJECT_UEVENT用于内核向用户空间的udev进程发送通知等。

netlink具有以下特点:

  • 支持全双工、异步通信(当然同步也支持)
  • 用户空间可使用标准的BSD socket接口(但netlink并没有屏蔽掉协议包的构造与解析过程,推荐使用libnl等第三方库)
  • 在内核空间使用专用的内核API接口
  • 支持多播(因此支持“总线”式通信,可实现消息订阅)
  • 在内核端可用于进程上下文与中断上下文

没有Linux和C的基础是真看不懂这是啥玩意儿…

什么是Redis keyspace notification

Redis消息架构两种中的一种keyspace notification、 Pub/Sub

实时监控Rdis 键值改变。

Keyspace通知允许client订阅Pub/Sub channels,以便接收影响Redis数据的事件。

功能概览

键空间通知使得客户端可以通过订阅频道或模式, 来接收那些以某种方式改动了 Redis 数据集的事件。

以下是一些键空间通知发送的事件的例子:

  • 所有修改键的命令。
  • 所有接收到 LPUSH 命令的键。
  • 0 号数据库中所有已过期的键。

事件通过 Redis 的订阅与发布功能(pub/sub)来进行分发, 因此所有支持订阅与发布功能的客户端都可以在无须做任何修改的情况下, 直接使用键空间通知功能。

因为 Redis 目前的订阅与发布功能采取的是发送即忘(fire and forget)策略, 所以如果你的程序需要可靠事件通知(reliable notification of events), 那么目前的键空间通知可能并不适合你: 当订阅事件的客户端断线时, 它会丢失所有在断线期间分发给它的事件。

未来将会支持更可靠的事件分发, 这种支持可能会通过让订阅与发布功能本身变得更可靠来实现, 也可能会在 Lua 脚本中对消息(message)的订阅与发布进行监听, 从而实现类似将事件推入到列表这样的操作。

Read More

C/C++参数中的_In_和_Out_代表什么

最近看方法参数中的疑惑

1
2
3
sai_status_t sai_api_query(_In_ sai_api_t sai_api_id, _Out_ void** api_method_table)
{
}

_In_和_Out_是用于标记参数的传递方式的注解。它们并不是C\C++语言的关键字,而是一种约定俗成的注释方式,用于提示函数的调用者和阅读者关于参数的特性。

_In_表示该参数是输入参数,即函数内部会读取参数的值,但不会修改它。通过这个标记,我们可以清楚地知道该参数在函数内部只被用于读取数据。

_Out_表示该参数是输出参数,即函数内部会修改参数的值,并将修改后的结果返回给调用者。通过这个标记,我们可以清楚地知道该参数在函数内部会被修改,我们在调用函数时需要确认传入的参数具备存储修改后结果的能力。

Read More

内存没满但是频繁fullgc,是不是ReservedCodeCacheSize的锅

业务中的现象表现

运行一段时间后,频繁fullgc,2s10几次fullgc,无法对外提供服务

环境

gc日志

内存还有非常多的情况下就开始了fullgc

dump分析

只看到class loader的一直重新加载?内存指向java.security.Permission,没有其他大对象?没有搞懂重新改好了也是这样,需要再搞懂

jvm参数
1
2
3
4
5
-Xms128m -Xmx256m -XX:ReservedCodeCacheSize=50m -XX:MetaspaceSize=96m -XX:MaxMetaspaceSize=96m -Xss256k -XX:MaxDirectMemorySize=16m
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSClassUnloadingEnabled
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:GCLogFileSize=10M -XX:NumberOfGCLogFiles=3 -Xloggc:/var/logs/gc1.log
-XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:NativeMemoryTracking=summary
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/logs/dump1-$(date +%Y%m%d%H%M%S).hprof"
修改

怀疑是-XX:ReservedCodeCacheSize=50m导致Meta不生效,导致重新加载fullgc?

修改为jvm参数,后好使了

1
2
3
4
-Xms128m -Xmx256m -XX:PermSize=128m -XX:-UseGCOverheadLimit -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80
-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:GCLogFileSize=10M -XX:NumberOfGCLogFiles=3 -Xloggc:/var/logs/gc1.log
-XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:NativeMemoryTracking=summary
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/logs/dump1-$(date +%Y%m%d%H%M%S).hprof"

需要再研究,怎么来指向这个问题。

另外火焰图必不可少

怎样使用DataX将HBase数据导入到MySQL

有需求使用DataX将HBase表中数据迁移到MySQL中,有的表在Phoenix中定义,使用hbase20xsqlreader读取。有的没有在Phoenix中定义,数据是动态插入,列是不固定的。

  • hbase20xsqlreader,读取Phoenix
  • hbase11xreader,读取HBase

不管读取HBase还是Phoenix都要求填写column,但是可以写sql占位,传进来。

我这里由于业务原因就没有使用占位符的方式传递。

现在的业务需求是我HBase横表迁移到MySQL纵表中。

动态列中的列名有在MySQL表中记录,所以实现流程就是

  1. shell 脚本调用mysql读取出要在HBase中读取的列
  2. 循环生成hbase11xreader读取-写入txt的DataX json
  3. 调用DataX执行上面的json文件导出txt
  4. 循环txt为每行加入MySQL要插入的列key
  5. 生成读取txt,写入MySQL

Read More

符合国际标准的城市编码

问题

fork的项目running_page有一个Issue提到国家和地区识别不正确,看了数据样例较为复杂,有的是有国家省市区,有的只有部分,还有国外的。running_page中代码以逗号分隔取国家,然后根据统计用区划代码和城乡划分代码对比取出城市。

问题是,数据是全球的用户是全球的,那全球各个国家和区域的标准应该是什么?中国有省市区,那其他国家有吗?有统一标准吗?

国际标准 ISO 3166

全球化那就必然要找国际标准了,看这里ISO 3166, Codes for the representation of names of countries and their subdivisions

里面又包含了

如何使用

我们拿到gps后做需要逆地址解析拿到ISO 3166标准的代码,有哪些方式可以呢,google map?

我调研了2个方式

Read More