学习的笔记

1. linux中perror和printf的区别

  • perror是用来打印系统错误信息的,参数只能是字符串
  • printf是用来打印用户指定的信息的,参数比较多样化,可以通过strerror(errno)实现perror的功能
  • ps: errno是个整型,系统错误码,strerror是将其转为字符串的函数
  • perror直接输出到屏幕,不进缓冲区
  • prinft会先进入缓冲区,加’\n’可以保证立即输出
  •   int lfd = socket(AF_INET, 4, 0);
      if (lfd == -1)
      {
          perror("socket error");
          printf("socket error: %s\n", strerror(errno));
          exit(1);
      }
    
  • 参考文章:【1】 【2】

2.linux中查找函数或变量头文件

  • 使用man文档,例如:man socket, man errno, man strerror

3. 宏定义中使用#和##

  • 两个#是将宏定义参数与其他字符拼接
__SOCKADDR_COMMON (sin_);
#define	__SOCKADDR_COMMON(sa_prefix) \
sa_family_t sa_prefix##family
typedef unsigned short int sa_family_t;
// 这里的sa_family_t是数据类型,无符号短整型
// 这里的##是将宏定义参数sa_prefix与family拼接起来作为变量名了
  • 一个#是将宏定义参数转换为字符串
#define STR(s)     #s 
printf(STR(baobaoyeye));      // 输出: baobaoyeye

4. linux中sockaddr_in和sockaddr

  • sockaddr_in将ip和端口分开了
  • 分配的内存大小相同16字节,网络类型是无符号短整型2字节,ip和端口一共14个字节,sockaddr是char数组14字节,sockaddr_in是端口无符号短整型2字节,ip是无符号整型4字节,zero凑数8字节。
  • sockaddr的那14个字节,ipv4中也只用到了前6个字节,多出来的8个是ipv6使用的吗,但是ipv6是16个字节,这也不够呀
  • 定义时使用sockaddr_in,传入函数时通过强制类型转换为sockaddr
  • 参考文章 【1】

5. htons和htonl

  • host to net short 将两个字节的短整型转换为网络需要的大端模式
  • host to net long 四个字节

6. 大端模式和小端模式

  • 计算机一般是小端模式,在网络编程中使用的是大端模式
  • 小端模式,低字节存储在低地址,高字节存储在高地址
  • 大端模式,低字节存储在高地址,高字节存储在低地址
  • 小端模式,在进行强制类型转换时不需要调整字节的内容,把int转short,就只需要把int的前两个字节给short就行
  • 小端模式,cpu进行数值运算时,依次从低位到高位取数据运算,直到最高位刷新符号位,运算更高效
  • 大端模式,符号位在数据的内存的第一个字节中(低地址),便于快速判断数据的正负和大小
    参考文章:【1】

7. linux中的void exit(int __status)

  • 用于退出当前进程
  • 那个status可以用来标志进程是正常退出还是异常退出,比如1是异常,0是正常

8. select和poll的区别

  • select支持最大1024个文件描述符(更改需要重新编译内核),poll没有上限。linux一个进程默认的最大文件描述符数量也是1024,可以修改
  • select是通过位图fd_set来传入待检测文件描述符和传出准备就绪的文件描述符,传入和传出都是同一个位,所以需要拷贝来保留原始待检测文件描述符,poll是通过结构体数组,传入和传出是结构体内两个参数,不需要在传入前进行一次拷贝。
  • 他们的检测逻辑是基本一样的,通过对线性表进行遍历的方式,内核遍历把需要检测的进行检测,我们在select/poll函数调用后,遍历判断哪些文件描述符是就绪的。都需要传入一个最大文件描述符,作为遍历终点。
  • 参考文章:【1】【2】

9. select和epoll的区别

  • select是跨平台的,windows,linux,mac都可以用,epoll是linux独有的
  • select/poll内核检测文件描述符就绪状态时,需要进行遍历,而epoll在添加文件描述符时,注册了回调函数,当文件描述符就绪时,会通过回调函数将其添加到就绪链表中
  • select/poll调用后不会告诉你具体哪些文件描述符就绪,需要自己遍历判断,而epoll会返回就绪的文件描述符
  • select/poll都是将待检测文件描述符的数据结构在用户态创建,调用函数时拷贝进内核中再使用;epoll的待检测文件描述符的数据结构是直接创建在内核态中的,调用函数时不需要拷贝了。准确来说,epoll是在添加文件描述符时就拷贝了。这里设计的是区分了频繁调用和偶尔调用,添加文件描述符就是偶尔调用,拷贝次数更少。
  • 关于传出就绪文件描述符时,epoll应该也是进行拷贝了,毕竟那个接收就绪文件描述符的数组,是在用户这边分配的内存,不是指针。(那个mmap机制好像是早期的版本中用到的)
  • 参考文章:【2】

10. 类的成员变量应该使用引用、指针、还是类对象

  • 使用指针时:
    • 此类占用的内存会更小,如果指针指向的空间是多个类对象所共有的,可以节省空间
    • 该成员变量可以使用多态
    • 该成员变量可能不需要使用,这时候可以不初始化这个指针,节省空间
    • 缺点:需要进行内存管理,实现析构函数、拷贝构造函数和赋值运算符
  • 使用类对象时:
    • 不需要自己写代码进行内存管理
    • 各个成员变量内存连续,更快的访问速度
    • 需要引入头文件,降低编译速度
  • 使用引用类型
    • 不能使用默认构造函数,必须在初始化列表中初始化引用类型的成员变量,引用类型不能被重新赋值
  • 参考文章:【1】【2】

11. linux安装mysql

  • sudo apt-get install mysql-server
  • sudo service mysql start
  • 登录 sudo mysql -uroot -p
  • 进入数据库 use mysql;
  • 开启远程连接 update user set host=‘%’ where user=‘root’;
  • flush privileges;
  • 修改数据库密码 ALTER USER ‘root’@‘%’ identified with mysql_native_password BY ‘123456’;
  • flush privileges;
  • quit;
  • 参考文章:【1】

12. sql语句

  • select给字段起别名,在每个字段后空格或者as,再加别名,别名最好加引号
  • select empno "name1", sal "name2", sal*12 "name3" from emp;
  • select中使用distinct时,是根据查询的所有字段组合判断是否重复,
  • select distinct ename,deptno from emp;
  • select中使用where进行条件过滤,等于号是=,不等于是!=或<>
  • select ename,deptno,sal from emp where deptno=1;
  • select中使用where进行条件过滤,用and,or 连接不同条件,and优先级高,not仅针对最近的条件起作用
  • select中使用where进行条件过滤,用in进行枚举范围过滤
  • select * from emp where empno in (3,4,5);
  • select中使用where进行条件过滤,用between xxx and xxx进行连续范围过滤
  • select * from emp between 3 and 5;
  • select中使用where进行条件过滤,用like配合 _ 和 % 进行模糊查询,_ 代表一个任意字符,% 代表多个任意字符
  • select * from emp where ename like "%a%;
  • select中使用order by进行排序,可以多个字段,desc代表倒序,asc代表正序
  • select * from emp order by deptno desc,sal asc;
  • update多个字段,用逗号隔开
  • update emp set sal=9000,deptno=1 where empno=3;
  • update时采用子查询
  • update emp set sal=sal+1000 where deptno=(select deptno from dept where dname='development');
  • delete数据
  • delete from emp where empno=5;
  • delete 整个表
  • delete from emp;
  • truncate table emp; 这个速度快,把数据库给表的空间回收
  • null什么都不是,不能和其他比较,null与其他的相加还是null
  • 如果not in 后面的枚举中又null,将所有都不符合
  • 查看表的字段和类型等
  • desc emp;
  • primary key是主键,唯一的,insert和update时不能重复
  • inner join:查询位于两个表中的两个字段,用重复字段进行连接
  • select ename,loc from emp,dept where emp.deptno=dept.deptno;
  • select ename,loc from emp inner join dept on emp.deptno=dept.deptno;
  • 自连接:查询在同一个部门工作的两个员工
  • select e1.ename,e1.deptno from emp e1 join emp e2 on e1.deptno=e2.deptno and e1.empno!=e2.empno;
  • 左外连接和右外连接,另一边是null
  • 取两次查询的交集
  • select distinct deptno from emp intersect select deptno from dept;
  • 取两次集合的并集,加all不去除重复值
  • select distinct deptno from emp union (all) select deptno from dept;
  • 分组函数?感觉是统计函数 max,min,avg,sum,count,这里不会统计null
  • select max(sal) from emp;
  • group by进行分组,比如求最大值,可以按照部门求每个部门的
  • select deptno,avg(sal) from emp group by deptno;
  • having用于group by后进行条件过滤,where不能用了,因为group by的执行在where后
  • select deptno,avg(sal) from emp group by deptno having avg(sal) >10000;
  • 子查询可以作为一个字段进行select
  • all关键词,比如例子中的,大于所有人的工资,从跟一个数比,变成跟一个集合比
  • select ename,sal from emp where sal>all(select sal from emp where deptno=2);
  • any关键词,比如例子中,大于任意一个人工资,就是比工资最低的高就行
  • select ename,sal from emp where sal>any(select sal from emp where deptno=2);
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值