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

如何启动Phoenix Query Server

问题

启动Phenix Query Server 6.0.0报错

1
2
3
2023-08-03 15:20:01.672088 launching /var/jdk/bin/java -cp /etc/hbase/conf:/etc/hadoop/conf::/var/phoenix-queryserver-6.0.0/bin/../phoenix-queryserver-6.0.0.jar: -Dproc_phoenixserver -Dlog4j.configuration=file:/var/phoenix-queryserver-6.0.0/bin/log4j.properties -Dpsql.root.logger=INFO,DRFA -Dpsql.log.dir=/tmp/phoenix -Dpsql.log.file=phoenix-root-queryserver.log org.apache.phoenix.queryserver.server.QueryServer

错误: 找不到或无法加载主类 org.apache.phoenix.queryserver.server.QueryServer

HBase 2.4.15

Phoenix 5.1.3

前因

升级HBase 2.4.15后,之前的Phoenix 4.13.1就不能用了。从Phoenix官网看到Phoenix和HBase的版本对应。

Current release 4.16.1 can run on Apache HBase 1.3, 1.4, 1.5 and 1.6.
Current release 5.1.3 can run on Apache HBase 2.1, 2.2, 2.3, 2.4 and 2.5.

然后Phoenix 5.1.3中没有带query server,需要单独下载query server并启动,如图

Query Server Installation

Read More