日常收藏与小记

1、Linux环境下段错误的产生原因及调试方法小结

Linux环境下段错误的产生原因及调试方法小结
博客园的一篇文章,对段错误原因和调试方法讲的还不错

2、Ubuntu重装桌面以及vbox虚拟机进入命令行

2.1 重装桌面
sudo apt-get install --reinstall ubuntu-desktop
sudo reboot
2.2 vbox虚拟机进入命令行

vbox如果按ctrl+alt,就会切换到主机下,使用右边的ctrl(也叫HOST键)可以替代这个组合,即按 ‘右ctrl+f1’ 即可。

3、栈、堆和常量区在代码中的区别

直接上代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define getmem 3    //1,stack; 2,heap; 3,const

#if getmem == 1	//stack
char *GetString(void){
	char array[6] = "hello";

	return array;
}

#elif getmem == 2	//heap
char *GetString(void){
	char *array;
	char buf[6] = "hello";
	
    array = malloc(sizeof(buf));
    strcpy(array, buf);
    
	return array;
}

#elif getmem == 3	//const
char *GetString(void){
	char *array = "hello";

	return array;
}
#endif

void main()
{
	char *pstr = NULL;
	
	pstr = GetString();
	printf("%s\n", pstr);
}

运行会发现
栈在出了函数之后就不可用了,程序运行会出错
堆和常量,在出了函数后仍可被使用

4、strlen使用注意事项

strlen在没有发现 \0 前会一直查找下去,然后返回 \0 之前的字符长度。
所以如果用strlen查询不确定的字符串长度,可能导致意外的无限循环。

5、tcp套接字api调用

tcp套接字api调用

6、字符集和字符编码

字符集(Character set)
字符的集合,每个字符集包含的字符个数不同,常见字符集:

ASCII字符集
GB2312字符集
BIG5字符集
GB18030字符集
Unicode字符集等

字符编码
比如UTF-8,就是Unicode字符集的编码方式

二者区别
字符集是书写系统字母与符号的集合。
字符编码则是将字符映射为一特定的字节或字节序列,是一种规则。

字符集和字符编码对应关系

字符集字符编码
ASCIIASCII
GB2312GB2312
GBKGBK
GB18030GB18030
UnicodeUTF-8、UTF-16、UTF-32

7、cp命令保留文件属性复制库链接文件

比如拷贝带有soft-link的so文件时, 加上-d参数就可以保留链接文件的属性了,而不会去复制了链接的原始库文件,命令如下:

cp -d  libXXX.so*  $DEST_DIR

8、\r\n和CR/LF的意思

\r是回车,英文是Carriage Return,简称CR作用:使光标到行首
\n是换行,英文是New Line或者是Line Feed,简称LF,作用:换到新行

9、编译时库的链接优先级

系统路径中如果有跟编译选项-L路径中的同名库,哪个更优先呢?优先级如下:

1.编译目标代码时指定的动态库搜索路径;
2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;
3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;
4.默认的动态库搜索路径/lib;
5.默认的动态库搜索路径/usr/lib.

同时可以指定程序运行时,从哪个目录搜索动态库,具体是用 -rpath 选项,如:

-Wl,-rpath=/mnt/app/

10、curl命令下载文件/http下载测试

1、利用curl下载http文件

curl -o mygettext.html http://www.gnu.org/software/gettext/manual/gettext.html

//9.9M
curl -OL http://d2.365rili.com/pc/update/365rili.exe

//62M
curl -OL http://xmp.down.sandai.net/xmp/XMPSetup6.1.7.810xmpdl.exe

//108M
curl -OL http://forspeed.rbread01.cn/down/VirtualBox-5.2.16-123759-Win.exe

//450M
curl -OL http://forspeed.rbread01.cn/down/newdown/4/26/VMwareworkstation.rar


2、curl命令详解,可以参考[http://www.linuxdiyf.com/linux/2800.html](http://www.linuxdiyf.com/linux/2800.html)

11、Linux释放内存

释放 echo 3 > /proc/sys/vm/drop_caches
  0:0是系统默认值,默认情况下表示不释放内存,由操作系统自动管理
  1:释放页缓存
  2:释放dentries和inodes
  3:释放所有缓存

如果现在想让操作系统重新分配内存,那么设置drop_caches的值为0即可

12、关于指针的初始化

如果定义指针的时候,指针指向一个有空间的数据,这时不需要分配空间;
如果要给指针赋值,则需要分配内存空间。

13、xml中node和element的区别

一张图解释
node和element的区别

14、几种拨号方式的区别(Gobinet/QMI-WWAN/ppp拨号)

拨号还有NDIS、ECM,暂时没做介绍。
参考:https://blog.csdn.net/u010164190/article/details/79096184

1.Gobinet拨号
GOBI 高通Gobi无线宽带芯片技术,只需一个模块即可支持多种移动宽带网络和众多移动运营商.
高通公司称全新的芯片将基于Gobi 4G LTE无线基带、MDM9615和MDM9215。这种技术可以在FDD和TDD网络下进行LTE连接,同时支持HSPA+和EV-DO网络、2G/3G网络。这意味着用户可以在本地使用高速4G LTE网络,在其他地方使用3G网络。Gobi平台在MDM芯片组的基础上还提供了软件增强层,这样可以使用不同技术下的无线连接更简单。

2.QMI-WWAN协议拨号
QMI: Qualcom Message Interface
MSM: Mobile station mode
AP: Application Procesor

高通平台目前都是非对称多核心,最主要的是AP和Modem。
两个处理器怎么进行通信呢,我们把AP和Modem当作两个主机,问题就变得了很简单,TCP/IP协议不是一种非常成功的进程间跨主机通信方式。高通没有采用这种方式,但是借鉴了TCP/IP的框架设计。
Qualcomm MSM Interface,作用用于AP和BP侧的交互,通俗说法就是让设备终端TE(可以是手机,PDA,计算机)
对高通BP侧的AMSS系统进行操作,如调用函数,读取数据,设置其中的NV项等。
参考:http://blog.csdn.net/u012439416/article/category/7004974

3.ppp协议拨号:点对点协议
PPP(点到点协议)在拨号过程中用于MS和PC间数据交互、协商。在拨号流程的初期首先开启的就是PC和MS直接的PPP过程,在拨号成功后,还需要依靠PPP协议对IP包进行封装传输数据。
官网源码:https://ppp.samba.org

15、双网卡如何实现同时访问多个网络

环境:双网卡,其中一个连外网和公司内网,另一个连接设备网络;
方法:
第一步:手动配置连接设备的网卡ip和子网掩码,不要配置网关,否则存在两个网关,会造成无法正常连接网络,比如我的环境就连不了公司内网;
第二步:添加静态路由,管理员模式进入windows命令行,输入如下命令:

route delete 0.0.0.0 //删除默认路由

//172.**.**.1为连接公司网络的网卡网关,表示所有网络走172.16.80.1
route add 0.0.0.0 mask 0.0.0.0 172.**.**.1 -p

//表示172.31开头的数据走172.**.**.25网关(即另外一块网卡的网关)
route add 172.31.0.0 mask 255.255.0.0 172.**.**.25 -p

查看路由信息

route print

删除静态路由

route delete 172.31.0.0 mask 255.255.0.0 172.**.**.25 -p
格式就是`route add 目标网段 mask 掩码 下一跳地址` -p

所有需要发往目标网段的IP数据包,全部由下一跳地址这个网关转发。
-p表示重启仍旧有效

目标网段必须是非直连网段,即172.16.80.*中的*要是0
下一跳地址必须是直连网段,所以目标网段和下一跳一定不是同段地址。

16、获取以太网MAC地址

代码如下:

static BOOLEAN GetEthernetMacAddress(char *ver)
{
    FILE    *mac;
    char    str[32] = {0};
 
    strcpy(ver,"00:00:00:00:00:00");
    mac = popen("cat /sys/class/net/eth0/address","r");
 
    if(mac != NULL){
        if(fgets(str,sizeof(str),mac) != NULL){
            strcpy(ver,str);
        }
        pclose(mac);
        return true;
    }
    return false;
}

17、adb工具下载

ref:https://blog.csdn.net/liuxinfa/article/details/82878816
以下是adb工具包最新Google官方版下载地址:

ADB和Fastboot for Windows

https://dl.google.com/android/repository/platform-tools-latest-windows.zip

ADB和Fastboot for Mac

https://dl.google.com/android/repository/platform-tools-latest-darwin.zip

ADB和Fastboot for Linux

https://dl.google.com/android/repository/platform-tools-latest-linux.zip

由于这些是直接的 Google 链接,用户可以确保下载不仅是官方的,而且将始终能够获得最新版本的 ADB 和 Fastboot 。

18、内存和cpu检测方法

pmap -x pid
top

19、编译选项说明

gcc的各种编译选项说明:

-g
加上-g选项以后,gcc在编译是会做以下额外的操作:

创建符号表,符号表包含了程序中使用的变量名称的列表。
关闭所有的优化机制,以便程序执行过程中严格按照原来的C代码进行。
-funwind-tables
如果用了backtrace接口,那么要加这个才会有比较多的信息
-Wl选项告诉编译器将后面的参数传递给链接器。
-soname则指定了动态库的soname(简单共享名,Short for shared object name)
-Wl 表示后面的参数也就是-soname
-ldl
如果你的程序中使用dlopen、dlsym、dlclose、dlerror 显示加载动态库,需要设置链接选项 -ldl
// 以下未验证
使用静态链接
对于运行时找不到动态库的问题,除了通过-Wl,-rpath指定路径外,还可以通过静态链接库的方式来解决。实际生产环境中通常只在一台机器上编译二进制程序,再将二进制程序分发到线上运行环境。程序需要的库可能实际线上环境中根本没有,也需要将库静态链接。

静态链接库有下面几种方式。

只保留静态库
如安装luajit后,在/usr/local/lib下既有静态库,也有动态库。链接时优先链接动态库。如果将动态库删除,只保留静态库,这时链接器就会链接静态库.

通过-Wl,-Bstatic对指定的库使用静态链接
gcc会对-Wl,-Bstatic 后面的库使用静态链接。对-Wl,-Bdynamic后面跟的库使用动态链接。 如果需要对指定的库使用静态链接,其他的库使用默认的动态链接,可以这样用

gcc test  -Wl,-Bstatic -lluajit-5.1 -Wl,-Bdynamic -lxxx -lxxx
这样gcc会链接libluajit-5.1.a,而对其他库使用动态链接。

20、printf无符号类型为负数

unsigned int dwValue;

printf(“%d”, dwValue);

在dwValue的值大于0x7FFFFFFF时,输出的结果会变成负数。

正确的程序应该为:

printf(“%u”, dwValue);

无符号整数相减的话永远不可能产生一个负数 所以不能有以下代码

unsigned int a = 6;
unsigned int b = 7;
unsigned int c = a-b;
if(c< 0)
printf("%d",c);

该代码中a-b不可能是一个负数,所以该判断条件永远进不去,另外,如果写成a-b>0的话,该循环能进去 打印输出的却是-1(编译环境为vs2008). 正确应该是用printf(“%u”,c),输出的结果是0xffffffff.

21、Linux查看网络端口号情况

netstat -paut

使用以上命令即可

22、如何避免socket端口被system建立的子进程继承了资源导致的占用问题

在父进程建立socket的时候,增加选项SOCK_CLOEXEC即可,这样fd就不会被system建立的子进程继承,如:

fd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);

如果遇到端口占用,但是进程里又已经关闭了,就要考虑被子进程继承的问题了。
在进程中创建进程,有三种方式:exec、system、clone。

23、Linux: 查看二进制文件

查看二进制文件,用od或hexdump命令。

$ od -tx1 -tc -Ax binFile
000000  61  62  63  64  65  31  32  33  34  35  61  62  63  64  65  31
         a   b   c   d   e   1   2   3   4   5   a   b   c   d   e   1
000010  32  33  34  35  61  62  63  64  65  31  32  33  34  35  61  62
         2   3   4   5   a   b   c   d   e   1   2   3   4   5   a   b
000020  63  64  65  31  32  33  34  35  0a
         c   d   e   1   2   3   4   5  \n
000029

-tx1选项表示将文件中的字节以十六进制的形式列出来,每组一个字节(类似hexdump的-c选项)

-tc选项表示将文件中的ASCII码以字符形式列出来(和hexdump类似,输出结果最左边的一列是文件中的地址,默认以八进制显示)

-Ax选项要求以十六进制显示文件中的地址

24、Linux内核编译几种clean方法

# make help
Cleaning targets:
  clean           - Remove most generated files but keep the config and
                    enough build support to build external modules
  mrproper        - Remove all generated files + config + various backup files
  distclean       - mrproper + remove editor backup and patch files

25、sprintf使用记录

该函数会在末位自动添加结束符’\0’,返回不统计结束符的长度。

26、const修饰符说明

const修饰的变量,虽然是只读的,但是在某些环境下还是可以通过指针地址修改对应的值,这边举两个例子说明不同的情况:

例子1:局部的const变量,取堆栈的数据

void main()
{
	const char a=0;
	char *b=&a;
	
	printf("a:%d, b:%d\n", a, *b);
	//a=1;	//compile err
	*b=2;
	printf("a:%d, b:%d\n", a, *b);
}

运行结果:

a:0, b:0
a:2, b:2

例子2:全局的初始化的const变量,存在数据区

const char a=0;
int main(int argc,char **argv)  
{

char *b=&a;

printf("a:%d, b:%d\n", a, *b);
//a=1;	//compile err
*b=2;
printf("a:%d, b:%d\n", a, *b);
    
    return 0;  
}

运行结果:

直接段错误。

例子3:全局的未初始化const变量,存在bss

const char a;
int main(int argc,char **argv)  
{

char *b=&a;

printf("a:%d, b:%d\n", a, *b);
//a=1;	//compile err
*b=2;
printf("a:%d, b:%d\n", a, *b);
    
    return 0;  
}

运行结果:

a:0, b:0
a:2, b:2

27、内存布局:栈,堆,BSS段(静态区),代码段,数据段

参考资料地址:
https://www.cnblogs.com/Spider-spiders/p/8884729.html
https://www.cnblogs.com/zhaozhong1989/articles/2728241.html

我们程序运行的时候都是放在内存里的,存储区域大概分为5块

1、栈区(stack)
由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap)
一般由程序员分配释放, 若程序员不释放(就会造成内存泄漏的问题),程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

3、全局区(静态区)(static)
全局变量和静态变量的存储是放在一块的。
初始化的全局变量和静态变量在一块区域(data)
未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(BSS,Block Started by Symbol)。
程序结束后由系统释放(在整个程序的执行过程中都是有效的)

4、文字常量区
常量字符串就是放在这里的, 程序结束后由系统释放;

5、程序代码区(code)
存放程序执行代码的一块内存区域、里面是二进制的代码、内存区域通常属于只读,
某些架构也允许代码段为可写,其实就是存放代码框架、或者说函数体、代码体的地方。

代码在加载到内存前,程序内部已经有三个信息:代码区(TEXT)、初始化数据区(DATA)和未初始化数据区(BSS)
在这里插入图片描述
思维导图
内存布局
代码示例:

//main.cpp
int a = 0;   // 全局初始化区 
char *p1;  //全局未初始化区 
main() 
{ 
    int b;               //栈 
    char s[] = "abc";    //abc是在栈里面,而下面123456/0却在在常量区内,要注意这两种情况的区别
    char *p2;            // 栈 
    char *p3 = "123456"; //123456/0在常量区,p3在栈上。
    static int c =0; 全局(静态)初始化区 
    p1 = (char *)malloc(10); 
    p2 = (char *)malloc(20);   //分配得来得10和20字节的区域就在堆区。 
    strcpy(p1, "123456");      //123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方
}

28、HTTP测试服务器

发送到以下地址,会自动返回发送的数据,比如:curl http://httpbin.org/get
http://httpbin.org/post
http://httpbin.org/get

29、利用find和cp进行查找文件的复制

find 查找的目录 -name 目标文件通配符 | xargs -i cp {} 复制的目标地址,比如:

find . -name *.tar | xargs -i cp {} /cpfolder

30、Linux内存记录小脚本

#!/bin/sh

FILE="/mnt/sdisk/meminfo.txt"
FLAG=0

echo "Start test meminfo" >> $FILE
while [ true ]
do
# 8h
if [ $FLAG = '28800' ]; then
        echo "End test meminfo" >> $FILE
        exit 1
fi
/bin/sleep 1
echo $(date) >>$FILE
cat /proc/meminfo | grep -E "Mem|Buffer|Cached" >> $FILE

FLAG=$((${FLAG}+1))
echo "$FLAG sec"
done

31、Linux脚本获取当前文件夹名字

foldername=`pwd |awk -F '/' '{print $NF}'`
#如果是根目录,则命名为root,否则就是文件夹名字
#比如脚本位置为/mnt/test/get_folder_name.sh,执行结果就是test
echo ${foldername:-"root"}

32、logcat指定关键字输出

adb logcat | grep -E "keyword1|keyword2"

33、Linux抓包

//数据拨号网卡的log保存到log.pcp
tcpdump  -i rmnet_data0 tcp port 80 -n -w  log.pcp

34、Linux 系统 文件锁 fcntl函数详解

https://www.cnblogs.com/mingfeng002/p/6962915.html
这篇讲的很详细

35、以太网速度设置

ethtool -s eth0 speed 100 duplex full autoneg off
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Protobuf是一种高效的序列化协议,可以用于数据交换和数据存储。它的主要优势是大小小,速度快,可扩展性强。下面是使用Protobuf的一些小记: 1. 定义消息格式 首先,需要定义消息格式,以便Protobuf可以将数据序列化和反序列化。消息格式定义在.proto文件中,使用protobuf语言编写。例如,下面是一个简单的消息格式定义: ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 这个消息格式定义了一个名为Person的消息,包含两个字段:name和age。 2. 生成代码 一旦消息格式定义好,就可以使用Protobuf编译器生成代码。编译器将根据消息格式定义生成相应的代码,包括消息类、序列化和反序列化方法等。可以使用以下命令生成代码: ``` protoc --java_out=. message.proto ``` 这将生成一个名为message.pb.java的Java类,该类包含Person消息的定义以及相关方法。 3. 序列化和反序列化 一旦生成了代码,就可以使用Protobuf序列化和反序列化数据。例如,下面是一个示例代码,将一个Person对象序列化为字节数组,并将其反序列化为另一个Person对象: ``` Person person = Person.newBuilder() .setName("Alice") .setAge(25) .build(); byte[] bytes = person.toByteArray(); Person deserializedPerson = Person.parseFrom(bytes); ``` 这个示例代码创建了一个Person对象,将其序列化为字节数组,然后将其反序列化为另一个Person对象。在这个过程中,Protobuf使用生成的代码执行序列化和反序列化操作。 以上是使用Protobuf的一些基本步骤和注意事项,希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值