常用的知识或技巧笔记

core文件路径:
/proc/sys/kernel/core_pattern
更改Core文件的地址:echo “/corefile/core-%e-%p-%t” > core_pattern
gdb命令:info singal info sybmol up:将栈帧向上回溯一层
调试器的bt的地址来自进程上的栈,根据栈里保存的函数返回地址来显示的。
https://pan.baidu.com/s/1kF1NDrGpu9wTUUDGAliCIA

TCP笔记:

	如果我们确实想在某个TCP链接上发送一个FIN, 那么可以改用shutdown函数,代替close, 我们还得清楚, 如果父进程对每个由Accept返回的已连接套接字都不调用close, 那么并发服务器中将会发送什么,
	首先, 父进程最终将耗尽可用描述符, 因为任何进程在任何时刻刻拥有的打开着的描述符通常都是有限的, 不过更重要的是,没有一个客户连接会被终止, 子进程关闭已连接套接字时, 它的引用计数将由2减为1,
	且保持1,因为父进程永不关闭任何已连接套接字,这将妨碍TCP连接终止序列的发生, 导致连接一直打开着。

TIME_WAIT状态:是主动断开连接方的状态。
TCP的TIME_WAIT状态是网络编程人员不容易理解的概念, 存在这一状态是为了实现完整地终止全双工的连接(即处理最终的ACK丢失的情形),并允许老的重复分解从网络中消失。
TCP的流量控制:
TCP总是告诉对方它能够接受多少字节的数据,这称为通告窗口,任何时刻,这个窗口指出接收缓冲区的可用空间,从而确保发送方
发送的数据不会溢出接收缓冲区,窗口时刻动态地变化:当接收到发送发的数据时,窗口大小减小,而当接收方应用进程从缓冲区中读取
数据时,窗口大小增大,窗口的大小减小到0是有可能的:TCP的接收缓冲区满,它必须等待应用进程从这个缓冲区读取数据后才能再接收
从发送方来的数据。
TCP窗口大小:是指无需等待确认应答而可以继续发送数据的最大值(指数据大小)

拷贝构造函数:
CExample(const CExample& C), 是否开辟新资源来区分是深拷贝还是浅拷贝
模式:
实际上 Prototype 模式和 Builder 模式、AbstractFactory 模式都是通过一个类(对象实例)来专门负责对象的创建工作(工厂对象),
它们之间的区别是:Builder 模式重在复杂对象的一步步创建(并不直接返回对象),AbstractFactory 模式重在产生多个相互依赖类的对象,
而 Prototype 模式重在从自身复制自己创建新类。

几个常用的寄存器

sp/esp/rsp(16bit/32bit/64bit)栈寄存器—指向栈顶

bp/ebp/rbp 栈基址寄存器—指向栈底

ip/eip/rip 程序指令寄存器—指向下一条待执行指令

指令寄存器 EIP
EIP —— 标志当前进程将要执行指令位置,在64位模式下扩展为 RIP 64位指令寄存器。

通用寄存器

32位通用寄存器有八个,eax, ebx, ecx, edx, esi, edi, ebp, esp,

他们主要用作逻辑运算、地址计算和内存指针,具体功能如下:

eax 累加和结果寄存器
ebx 数据指针寄存器
ecx 循环计数器
edx i/o指针
esi 源地址寄存器
edi 目的地址寄存器
esp 堆栈指针
ebp 栈指针寄存器

在 64-bit 模式下,有16个通用寄存器,但是这16个寄存器是兼容32位模式的,
32位方式下寄存器名分别为 eax, ebx, ecx, edx, edi, esi, ebp, esp, r8d – r15d.
在64位模式下,他们被扩展为 rax, rbx, rcx, rdx, rdi, rsi, rbp, rsp, r8 – r15.
其中 r8 – r15 这八个寄存器是64-bit模式下新加入的寄存器。

寄存器简介
先明确一点,本文关注的是通用寄存器(后简称寄存器)。既然是通用的,使用并没有限制;后面介绍寄存器使用规则或者惯例,只是GCC(G++)遵守的规则。因为我们想对GCC编译的C(C++)程序进行分析,所以了解这些规则就很有帮助。
在体系结构教科书中,寄存器通常被说成寄存器文件,其实就是CPU上的一块存储区域,不过更喜欢使用标识符来表示,而不是地址而已。
X86-64中,所有寄存器都是64位,相对32位的x86来说,标识符发生了变化,比如:从原来的%ebp变成了%rbp。为了向后兼容性,%ebp依然可以使用,不过指向了%rbp的低32位。
X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。
刚刚说到,寄存器集成在CPU上,存取速度比存储器快好几个数量级,寄存器多了,GCC就可以更多的使用寄存器,替换之前的存储器堆栈使用,从而大大提升性能。
让寄存器为己所用,就得了解它们的用途,这些用途都涉及函数调用,X86-64有16个64位寄存器,分别是:%rax,%rbx,%rcx,%rdx,%esi,%edi,%rbp,%rsp,%r8,%r9,%r10,%r11,%r12,%r13,%r14,%r15。其中:

%rax 作为函数返回值使用。
%rsp 栈指针寄存器,指向栈顶
%rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。
%rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防他被修改
%r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值

性能:
Windows:
性能监视器:
开始=>输入"perfmon.msc" 或者 开始=>控制面板=>管理工具=>性能监视
资源监视器:
Windows任务管理器=>性能 标签=>资源监视器

kafka:
消费的tipic名称要和生产的一致
groupid随意
同一个Topic支持不同group id消费

boost::shared_ptr:
Boost文档说,在调用shared_from_this()之前,必须存在一个正常途径创建的shared_ptr
boost::shared_ptr spy(new Y)
boost::shared_ptr p = spy->GetSelf(); //OK
shared_from_this();
在enable_shared_from_this的成员函数 shared_from_this里,
内部存储的 weak_ptr 被转换为 shared_ptr, 从而增加了相应的引用计数,以确保相应的对象不会被删除

Windebug:
Specify the full name of the DLL to load: .reload /f D:\test\A.dll
set .exepath as described before eg: .exepath d:\test
set the image path and symbol path :.sympath d:\test

	 .dump /mf d:/test.dmp 

读写锁在临界区最小时,开销最大。

数据锁:
struct bucket {
HPR_Mutex mut;
NodeInfo* list;
}
许多数据结构都可以分割,数据结构的每个部分带有一把自己的锁,这样虽然每个部分一次只能执行一个临界区,但是数据结构的各个部分形成的临界区就可以并行执行了
, 在锁竞争必须降低时,和同步开销不是主要局限时,可以使用数据锁。 数据锁通过将一块过大的临界区分散到各个小的临界区来减少锁竞争。
避免死锁主要有三种方法:等级锁(给锁分等级(编号), 如果线程已经获取来编号相同或者更高的锁,就不允许再获取这把锁),条件锁(获取锁之前, try_lock一下),一次一把锁的设计.
软件包管理->软件安装->自定义安装->安装->确定
消除boost编译警告:
#ifndef _lint
#include “boost/shared_ptr.hpp”
#include “boost/make_shared.hpp”
#define Plugin_SharedPtr boost::shared_ptr
#endif

查看库是32还是64:
objdump -a *.a
objdump -a *.so
strings <可执行文件名>
getconf LONG_BIT 查看系统位数
删除表内容:
truncate table [表名] 选中iac_imsdb->查询->新建查询->输入command->执行即可

Linux查看正在运行的网卡:
ifconfig enp2s0f0 |sed -n “1p” | awk -F" " ‘{print $2}’|grep RUNNING

mallopt(M_TRIM_THRESHOLD,0):
Modifying M_TRIM_THRESHOLD is a trade-off between increasing
the number of system calls (when the parameter is set low) and
wasting unused memory at the top of the heap (when the
parameter is set high).

内存笔记:

	库的文本段可能与其它使用相同库的进程共享, 它们各自有一份数据段的私有副本.
	栈为线程栈.
	sar -B 检查pgscan 寻找连续的页扫描(超过10秒), 它是内存压力的预兆
	vmstat:检查si, so 列, 如果一直非0, 那么系统正存在内存压力. 指交换匿名换页, 每秒运行vmstat检查free列的可用内存. 单位KB, swpd:交换出的内存量, free:空闲的可用内存, buff:用于缓冲缓存的内存, cache:用于页缓存的内存.
	dmesg 过滤Out of message ,是否有OOM终结者 
	slabtop:内核块分配统计信息
	DTrace:分配跟踪

.rpm解压:
解包:rpm2cpio FileName.rpm | cpio -div

Close_WAIT:

产生原因:通过图上,我们来分析,什么情况下,连接处于CLOSE_WAIT状态呢?

在被动关闭连接情况下,在已经接收到FIN,但是还没有发送自己的FIN的时刻,连接处于CLOSE_WAIT状态。
通常来讲,CLOSE_WAIT状态的持续时间应该很短,正如SYN_RCVD状态。但是在一些特殊情况下,就会出现连接长时间处于CLOSE_WAIT状态的情况。
出现大量close_wait的现象,主要原因是某种情况下对方关闭了socket链接,但是我方忙与读或者写,没有关闭连接。代码需要判断socket,一旦读到0,断开连接,read返回负,检查一下errno,如果不是AGAIN,就断开连接。

wc -l /proc/net/tcp 命令检查tcp 连接数

显示出传输和发送的网络吞吐量:
sar -n DEV 1 |awk ‘NR == 3 || $3 == “eth0”’\

查看库的命令:
nm -D/U *.so
ldd -r *.so
objdump -D *.so

查看动态库导出函数列表
1.使用objdump命令。
例如:objdump -tT xxx.so
2.使用nm命令(个人觉得使用nm方式查看更方便。)
例如 nm -D xxx.so
linux 指令:
ps -aux | grep $(pidof iixs) | grep “hik.iixs.iixxs” | awk ‘NR1{print “”$3"%"}’
top -n 1 -p $(pidof ixxs)|grep ixxs | awk 'NR
1{print $9}’
递归锁: 单线程递归, 多线程互斥!

boost智能指针
shared_ptr 中存有一个weak_ptr,而weak_ptr对象有两个指针:px 指向对象实体,而 pn.pi_ 则指向的是指针的计数对象
读写锁:
互斥原则:
读-读能共存,
读-写不能共存,
写-写不能共存。
查看网卡信息: ethtool eno1 , ifconfig
查看网络io: netstat -i -c(持续输出) netstat -s (总结输出)
此“兆”不同于彼“兆”
sar -n DEV 1 | awk ‘NR == 3 || $3 == “eno1”’
在正式解析千兆网卡之前,先谈谈很多人容易搞混淆的概念。不少用户都曾经有这样的疑惑,自己是百兆网卡,但是在局域网内最多也就不到10MB/s的传输速度;办个“4M宽带”,下载速度也只有400KB/s…… 其实,这是大家搞错了MB和Mb的概念。一般我们所说的千兆和百兆,它的单位都是Mbps,而传输速度我们一般则用MB/s来作为单位。实际上和硬盘的容量概念一样,B是指Byte,而b则是指bit,1B=8b。那么替换到网络中也是一样,普通的百兆网卡理论传输速度为100Mbps,实际上只有12.5MB/s,而千兆网卡的理论传输速度则为125MB/s。明白了这点,相信就没人真的以为千兆网卡传输能达到1GB/s的速度了。事实上,就目前的应用环境而言,在大多数情况下,百兆网卡已经足够了,而各位的宽带带宽只要按照运营商给出的数字再除以8,也基本上就是自己宽带能下载的极限速度了。

IO:

iostat -d -x -k 1
iostat -dxkzt -p sda 1 指定磁盘
pidstat -d -p 49766 1 指定进程IO
pidstat -d 1 //显示所有进程占用磁盘io情况
kB_rd/s:每秒从磁盘读取的KB
kB_wr/s:每秒写入磁盘KB
kB_ccwr/s:任务取消的写入磁盘的KB。当任务截断脏的pagecache的时候会发生。
COMMAND:task的命令名

网络性能:

	查看TCP参数命令: sysctl -a |grep tcp
	查看两个队列: 半连接队列:tcp_max_syn_backlog = 4096, 已连接队列 net.core.somaxconn = 1024  sysctl -a |grep net.core.somaxconn
	lsof 按照进程ID列出包括套接字细节在内的打开的文件
	ss:套接字统计信息
	iftop:按主机总结网络接口吞吐量
	traceroute:查看到目的地的路由, 开源需要安装
	ip : 网络接口统计信息
	nicstat : 网络接口吞吐量和使用率
	sar : 统计历史信息
	netstat -I=eno2 1
	nestat -s
	ifconfig eno2:检测网卡错误, 丢弃, 超限统计信息.

查看服务的在系统中的最近异常及状态:
systemctl status hik.iac.ias.1

设计模式:

	八大原则:依赖倒置原则, 开放封闭原则(对扩展开放对修改封闭), 单一职责原则, 里式替换原则, 接口隔离原则, 对象组合优于类继承,  封装变化点, 面向接口编程(IInterface)
	重构法则: 静态->动态 ,  早绑定->晚绑定, 继承->组合, 编译时依赖->运行时依赖,  紧耦合->松耦合(抽象出来, 或者增加适配, 代理, 中间层)

nm objdump :

		objdump -tT 
		查看库依赖项:objdump -x xxx.so | grep "NEEDED"
		nm -D 
		查看库中接口: nm -D libxxx.so| awk '{if($2=="T"){print $3}}'

使用gcore工具产生core文件而不杀死进程:

	$ gcore pid   (进程号)
	gdb的generate-core-file命令 
	(gdb) generate-core-file
	Saved corefile core.19388
	(gdb) detach

gdb 调试工具dump出可疑内存:
gdb attach #先连接到进程中
gdb dump memory /path/dump.bin 0x0011 0x0021 # dump 出内存段的信息,具体要 dump 的内存段地址,可以借助之前pmap 排查的结果,以及 cat /proc//maps 中指示的地址段得出
strings /path/dump.bin | less # 查看内存内容, 相信你能从中发现一些不一样的东西

用户自定义信号值:
kill -10 12345 or kill -SIGUSR1 12345
会给test发送SIGUSR1 信号。
kill -12 12345 or kill -SIGUSR2 12345
会给test发送SIGUSR2 信号。

查看CPU:

pidstat -u -p 12617 1
pidstat -u -t(显示各线程的cpu统计)-p 12617 1
mpstat -P ALL 1

PING指定包大小,和包数

:
ping -c 4 -s 1500 10.10.68.131

抽象:

抽象是从感性认识出发,通过分析和比较,抽出共同点,撤开差异性的内容和联系,通过综合得出简单的、基本的规定的过程。分析、比较和综合是抽象的基础,没有分析、比较和综合就找不到事物的异同,也不能区分事物的本质属性和非本质属性。在抽象过程中,分析、比较和综合相互作用、相互渗透,抽象的具体过程也千差万别,但都包括如下基本过程:分离、提纯、简略.
抽象指的是从纷繁复杂的事物中提炼本质的过程,是一个具体到概念的过程, 例如苹果、香蕉、生梨、葡萄、桃子等,它们共同的特性就是水果。得出水果概念的过程,就是一个抽象的过程。
我们在开发的过程中要保持一种敏锐的感觉,发现可能的变化并且封装起来,只提供一个精心定义的接口让外界调用。这样你在接口后面所做的任何变化,外边就不受影响了

总结了一下网上关于__cxa_pure_virtual出现的可能:

1:线程切换的时候, 一个清空了虚函数表,另外一个线程却正要用 
2:构造函数调用虚函数也会出这个问题 
3:垂悬指针也会出现这个现象,父类指针指向子类实例,子类被释放后,用父类指针调用

你可能感兴趣的:(工作中常用的笔记)