# collection **Repository Path**: chizuruwq/collection ## Basic Information - **Project Name**: collection - **Description**: C,CPP日常练习 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-05-04 - **Last Updated**: 2024-08-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # PROBLEMS # Day20 配置环境: - vim - git - python3.9 - bt # Day21 1. 自己整理ls -l各列的含义,然后贴到答题框中 2. 假如目录结构是 ├── dir1 │ └── dir2 请问dir2目录的硬链接数是几? 现在继续在dir2目录下再新建一个dir3目录: ├── dir1 │ └── dir2 │ └── dir3 此时dir2目录的硬链接数又是几呢? 描述一下这个过程中dir2目录硬链接数变化的过程和原因。 3. 对于某个目录下的文件来说,此文件的文件名、文件权限、时间戳、所有者信息等以及最终文件的数据都分别存储在物理文件系统中的什么位置呢? 自己总结一下上述数据信息存储的位置。 4. 目录的读写执行权限决定了什么?普通文件的读写执行权限决定了什么? 5. 一个文件没有写的权限,那么它可不可以被删除呢?取决于什么? # Day22 1. 使用gdb调试core文件,并检查出错时的堆栈信息 2. 说明一下使用动态库和静态库的区别。然后分别生成动态库和静态库。 可以直接参考文档笔记中的实现 主要是自己练习一下生成库文件的指令 3.1 一个目录中有三个.c文件:main.c add.c subtract.c(内容无所谓),最终将它们生成一个可执行程序main。请编写这个Makefile文件。 3.2 一个目录中有三个.c文件:test.c test2.c test3.c(内容无所谓),它们都有自己的main函数,都要最终生成独立的可执行程序:test、test2、test3。请编写这个Makefile文件。 > 注意:要求实现clean清理和rebuild重建功能 > 注:可以尽量写的更通用一些。 4. 请按照章节《HelloWorld》配置Linux开发环境,配置好公共头文件、Makefile以及.c文件模板,最后实现一个标准C语言的文件流文件复制,将代码提交上来. 5. 以下小题目,请利用学过的目录相关操作函数实现: - 打印列出目录中的所有文件和子目录,要求列出dirent结构体的所有信息不用递归,只看一级目录) - 自己生成一个目录,使用一下telldir和seekdir # Day23 1. 请实现: - 无排序功能的ls -al指令 - 实现简化版tree指令 2. 自己实现一下open形式的文件复制,然后自己测试比较一下它和fopen文件复制的性能 3. 题目描述 请使用 read() 和 write() 系统调用在 C 语言中实现结构体的序列化和反序列化。给定一个结构体类型Person,包含姓名(最长30个字符)、年龄和性别。你需要实现以下功能: - 序列化(写入):将结构体 Person 对象写入到一个文件中。 - 反序列化(读取):从文件中读取数据并恢复到结构体 Person 的对象中。 结构体类型定义如下: ```c typedef struct { char name[31]; // 姓名,包含一个结束字符 int age; // 年龄 char gender; // 性别('M' = 男,'F' = 女) } ``` # Day24 1. 利用mmap文件映射实现逐段的文件复制功能。 2. 利用mmap文件映射和read/write实现:将文件中的全部大写字母转换成对应的小写字母 3. 利用dup实现重定向功能: - 重定向标准输出到文件 - 标准输入重定向到文件, 从文件读数据 - 实现在标准输出重定向到文件, 复原,再重定向到文件的反复横跳 - 重定向标准错误到文件server.log中, 实现类似打印日志的功能 # Day25 1. 实现即时聊天,如果对方连续10s没有发送任何消息则断开连接。(注意,即使本方在10s内从标准输入当中输入数据也不行)。 2. 编写程序A和B。A负责将文件的名字、长度和内容通过管道发送B,B需要新建一个目录,并将该文件存储起来。 # Day26 1. 说明一下什么是进程,什么是虚拟内存,什么是虚拟CPU? 2. 使用思维导图整理进程相关的命令, 以及每个命令比较重要部分的显示结果 3. 书写一个程序同时监听管道的读端和写端。 - 如果可写,则写入4096个字节 - 如果可读,则读取1024个字节 - 描述一下运行的现象 4. 编写C程序A和B,A和B通过管道进行通信: - 程序A先后执行3次printf("Helloworld\n"); - 第一次显示在A的标准输出当中; - 第二次显示在B的标准输出当中; - 第三次显示在A的标准输出当中。 # Day27 1. 画出下列代码当中每个进程的虚拟内存的示意图,并判断下列代码当中会输出多少个减号? ```c int main(){ printf("-"); fork(); printf("-"); fork(); printf("\n"); } ``` 2. 说明什么是孤儿进程,什么是僵尸进程,他们对操作系统有什么影响?书写代码创建孤儿进程和僵尸进程。 3. 进程的结束方式有哪些?return、_exit和exit有什么区别? 4. 实现一个守护进程。 5. 书写两个可执行程序: - 可执行程序一: - 父进程负责创建子进程并且最后回收其资源; - 子进程加载可执行程序二。 - 可执行程序二: - 列出当前目录所有文件的文件名。 # Day28 1. 编写C程序验证ps命令显示的是有效用户ID,还是真实用户ID。作业中应该包括代码、操作每个步骤和命令以及最终结果的截图 2. 验证匿名管道的性质: - 是否发生读阻塞? - 是否发生写阻塞? - 读端先关闭,写端继续写会怎么样? - 写端先关闭,读端继续读会怎么样? 3. 新建共享内存,连接,然后往共享内存写入How are you,然后另外一个进程连接共享内存,读取数据并打印显示,最后删除共享内存。提交操作记录和相关代码。 4. fork创建一个子进程,两个进程访问同一段共享内存,共享内存里保存一个整形数,父子进程用for循环的方式。每次对这个整形数字加1,父子进程各循环1000万次。加完后打印一下共享内存里的数字,看看是多少? # Day29 1. 完成窗口聊天 - A进程和B进程负责通信,从标准输入读到的字符串通过管道发给对方 - A进程从标准输入读到的字符串发给B进程后,B打印到屏幕上。 - B进程从标准输入读到的字符串发给A进程,A打印到屏幕上。 退出方式: 任意一个进程在标准输入收到输入1,给所有进程(通信双方)发送10号信号,每个进程收到10号信号后,开始执行有序退出。 了另两 2. 通过sigprocmask阻塞2号信号,睡眠5秒后,解除阻塞,2号信号得到执行;在睡眠后,解除阻塞之前,通过sigpending检测是否有信号挂起。 3. 使用sigaction注册2号信号的处理函数 - 允许自动重启低速系统调用 - 在处理2号信号时阻塞3号信号,不会被3号信号打断; - 在2号信号的信号处理函数中,使用sigpending函数判断一下有没有3号信号处于未决状态; 4. 信号递送过程中,产生了另一个同类信号会怎么样?产生个、三个、多个同类信号会怎么样?写代码验证一下你的想法。说明mask和pending如何变化。 5. signal的作用是什么?会不会导致阻塞?handler函数会在什么情况下调用?使用同一个handler去注册不同的信号,效果怎么样? # Day30 1. 什么是线程?线程和进程有哪些区别? 2. `pthread_join`为什么需要一个`void **`参数?书写程序,创建3个子线程,然后等待所有的子线程终止,最后获取其退出状态。 3. 线程的清理函数什么时候会执行?什么情况下线程退出的时候不会执行清理函数? 4. 从源码角度说明为什么`pthread_cleanup_push`和`pthread_cleanup_pop`必须成对出现? # Day31 1. 使用多线程模拟卖票逻辑: - 一个线程卖票: 票未必每一次都能卖掉, 每一次买票的人在随机的状态下(假设:用产生一个随机数<0.5表示有人要买票)选择是否买票 - 另一个线程加票 - 在初始情况下有20张票的情况下:每次卖一张 - 当第一次票小于5张的时候追加一次票: 10张票 - 卖完为止 2. 测试一下主线程打开文件以后,子线程能否通过文件描述符访问同一个文件对象?如果某个线程执行close之后会怎么样? # Day32 1. 现在有两个线程t1和t2,t1 打印 A 和 C,t2 打印 B。书写代码,使用条件变量每次的显示顺序都是A->B->C。 代码书写完成后,回答问题:条件变量中加锁的目的是什么? 2. 主线程执行事件A A: printf("Before A!\n"); sleep(3) printf("After A\n"); 子线程执行事件B, B: printf("Before B!\n"); sleep(3) printf("After B\n"); 在AB事件之外不使用sleep,使用条件变量,确保B一定在A完成之后运行。 3. 两个生产者, 三个消费者 生产者:每隔3秒生产一个商品, 容器满则等待 消费者:在前5秒不消费, 5秒之后, 每隔一秒消费一个商品, 无商品则等待 初始条件:容器初始10个商品, 最大上限20个商品 # Day33 1. HTTP的中文全称是什么?从全称的每个字段来说明HTTP的特点。 2. URI由哪些部分组成? 3. HTTP请求报文和响应报文由哪些部分组成?HTTP常用方法有哪些?HTTP常用状态码有哪些? 4. 对称加密和非对称加密有什么区别?简要说明一下HTTPS的握手阶段流程。 5. HTTP协议中GET请求和POST请求的区别有哪些呢? 6. 使用浏览器或者抓包工具, 抓一个http的包, 截图标注一个http请求有哪些信息需要重点关注 # Day34 1. 什么是大端模式和小端模式,什么是主机字节序和网络字节序?编写代码,验证一下自己的机器是大端模式还是小端模式? 2. 根据域名,获取一下知名互联网厂商的IP地址信息,如阿里、京东、腾讯、百度。 3. 先简单说说socket、bind、listen、connect函数分别有什么基本作用呢? # Day35 1. 使用select编写聊天室程序: - 客户端和服务端使用tcp通信; - 服务端可以处理新客户端的连接和转发消息; - 客户端可以连入服务端并发送消息。 2.编写带有超时踢出的聊天室程序: - 客户端和服务端使用tcp通信; - 服务端可以处理新客户端的连接和转发消息; - 客户端可以连入服务端并发送消息。每个客户端只要有30s未活跃,则被踢出聊天室。 # Day37 把我们昨天的两个作业(群聊、超时)试着改成epoll实现 (如果需要使用删除, 可以参考我们文档epoll_ctl函数设置EPOLL_CTL_DEL删除监听文件描述符的操作) # Day38 1. 完善进程池 2. 选做: 假设父进程fork了一个子进程之后, 子进程打开一个文件, 把这个文件通过本地socket传给父进程, 让父进程能访问向这个文件写一个hello或者world之类的字符 # Day39 1. 实现`recvn(int netfd, void *buf, int length)` 该函数可以在不使用MSG_WAITALL的情况下,往buf指向的内存中接收任意长度(length)的数据。 2. 完善进程池 # Day41 1. 练习今天讲的所有Git命令 2. 模拟和使用开发一个项目, 制造冲突, 解决冲突 3. 创建分支, 试着在分支上写代码并且感受合并分支 # Day42 1. 创建一个名为""订单""的数据库, 修改它的编码格式, 再删除这个数据库 2. 设计一个分支结构,使用感受日常开发代码的合并逻辑 3. 假设本地已经有一个项目, 想在不移动这个项目的前提下, 通过git管理这个项目的代码文件, 它的操作步骤是什么. 4. "会退掉工作空间的修改", "把缓冲区内容回退到工作空间", "版本回退" # Day43 1.写出sql语句 - 增加 年龄 这一列 - 修改 身高 为浮点类型 - 插入10条数据 - 修改id = 10 的名字为'乔峰' - 修改 id 不为1和2 的性别为 '男' ```sql create table users( id int, name varchar(10), nickname varchar(10), gender char, height int, weight int, score float, birthday date, nation varchar(20) ); ``` 2. 有如下一张表 ```sql create table student( id int, name varchar(20), chinese float, english float, math float ); ``` - 请添加2列信息,出生日期,籍贯。 - 请修改语文成绩的数据类型为int型 - 请在里面插入10名学生数据 - 假设10名同学中有同姓的,如王,请找出姓王同学的信息 - 请找出各科不及格学生的信息 - 请找出有任何一科不及格学生的名称 - 请找出两科成绩在90分以上的学生名称 - 请找出没有一科挂科的学生名称 3. 新建一个学生表S,有包含如下信息, 并插入10条数据。 - 学号 id, - 学生姓名 name, - 性别 gender, - 年龄 age, - 专业 dept, - 所在系编号 …等 - 学号格式为 201801 201802 201803... - 性别只有 'male' & 'female' - 院系包含(信息系、数学系,计算机科学系等) 然后做如下查询: - 查询全体学生的学号与姓名。 - 查询全体学生的详细记录。 - 查询全体学生的姓名、出生年份和所属部门 使用列别名改变查询结果的列标题 - 查询所有年龄在20岁以下的学生姓名及其年龄。 - 查询年龄在20~23岁(包括20岁和23岁)之间的学生的姓名、系别和年龄。 - 查询年龄不在20~23岁之间的学生姓名、系别和年龄。 - 查询信息系、数学系和计算机系学生的姓名和性别。 - 查询既不是信息系、数学系,也不是计算机科学系的学生的姓名和性别。 - 查询学号为200518的学生的详细情况。 - 查询所有姓刘学生的姓名、学号和性别。 - 查询姓“李”且全名为两个汉字的学生的姓名。 - 查询名字中第2个字为“立"字的学生的姓名和学号。 - 查询所有不姓刘的学生姓名。 - 查询学号在201801~201809之间的学生姓名。 4. 创建一个城市表,字段有id、名字、所属国家名字、人口、所属省份, 并插入若干数据 - 查询所有城市名及人口信息 - 查询city表中,所有中国的城市信息 - 查询人口数小于100人城市信息 - 查询中国,人口数超过500的所有城市信息 - 查询中国或美国的城市信息 - 查询人口数为100-200(包括两头)城市信息 - 查询中国或美国,人口数大于500的城市 - 查询城市名为qing开头的城市信息 # Day44 1. 新建一个学生表stu,有包含如下信息, 并插入10条数据。 - 学号 id 整数类型, - 学生姓名 name, - 性别 gender, - 年龄 age, - 专业 dept, - 所在系编号 …等 - 学号格式为 201801 201802 201803... - 性别只有 'male' & 'female' - 院系包含(信息系、数学系,计算机科学系等) 实现: - 18.查询不同院系学生的人数。 - 19.查询不同院系学生的平均年龄,并以降序排序。 - 20.查询计算机系年龄在20岁以下的学生姓名。 - 22.查询全体学生情况,按系号升序,按年龄降序。 2. 创建一个城市表,字段有id、名字、所属国家名字、人口、所属省份, 并插入若干数据 - 统计city表的行数 - 统计各国城市的个数 - 统计每个国家的城市总人口数 - 统计中国每个省的城市个数及城市名列表 - 统计每个国家的城市个数,并且只显示超过5个城市的国家 - 统计每个国家的城市个数,并且只显示超过5个城市的国家并按照从大到小排序 - 统计每个国家的城市个数,并且只显示超过5个城市的国家并按照从大到小排序,并且只显示排名前三 3. 某大学研究生院 有若干研究生导师,包括职工编号、姓名、职称、研究方向,其中每个导师的职工编号是唯一的。 若干研究生,包括学号、姓名、性别、入学日期,其中每个研究生的学号是唯一的。 每个导师可以带若干研究生,但每个研究生只能有一个导师。 - 请设计一个数据库,要求可以正确体现导师和研究生之间的关系。 - 设计完毕之后,请插入一定量的数据,并验证你设计的数据库是否满足要求。 - 1.请查出每个导师所带研究生的姓名。 - 2.清查出特定姓名的导师所带研究生的姓名。 - 3.请查出每个导师所带研究生的数量。 - 4.请查出每个导师所带的男研究生的数量。 - 5.请找出选择哪个研究方向的导师最多。 - 6.请找统计不同职称的导师的个数。 在数据库中创建如下两张表: ```sql create table dept ( deptno varchar(10) primary key, dname varchar(10) ); create table emp ( empno varchar(10) primary key, ename varchar(10), job varchar(10), mgr varchar(10), sal float, deptno varchar(10) references dept(deptno) ); insert into dept values ('1','事业部'); insert into dept values ('2','销售部'); insert into dept values ('3','技术部'); insert into emp values ('01','jacky','clerk','tom','1000','1'); insert into emp values ('02','tom','clerk','','2000','1'); insert into emp values ('07','biddy','clerk','','2000','1'); insert into emp values ('03','jenny','sales','pretty','600','2'); insert into emp values ('04','pretty','sales','','800','2'); insert into emp values ('05','buddy','jishu','canndy','1000','3'); insert into emp values ('06','canndy','jishu','','1500','3'); select * from dept; select * from emp; ``` - 列出emp表中各部门的部门号,最高工资,最低工资 - 列出emp表中各部门job为'CLERK'的员工的最低工资,最高工资 - 对于emp中最低工资小于2000的部门,列出job为'CLERK'的员工的部门号,最低工资,最高工资 - 根据部门号由高而低,工资有低而高列出每个员工的姓名,部门号,工资 - 列出'buddy'所在部门中每个员工的姓名与部门号 - 列出每个员工的姓名,工作,部门号,部门名 - 列出emp中工作为'CLERK'的员工的姓名,工作,部门号,部门名 - 对于emp中有管理者的员工,列出姓名,管理者姓名(管理者外键为mgr) - 对于dept表中,列出所有部门名,部门号,同时列出各部门工作为'CLERK'的员工名与工作 - 对于工资高于本部门平均水平的员工,列出部门号,姓名,工资,按部门号排序 - 对于emp,列出各个部门中工资高于本部门平均工资的员工数和部门号,按部门号排序 # Day45 1. 通过C语言关于预处理SQL的API接口,对用户表t_user(id, name, password,email)实现以下查询操作, ```sql const char stmt_str = " select id, name, email from t_user where id > ? "; ``` 2. 通过C语言关于预处理SQL的API接口,对用户表t_user(id, name, password,email)实现以下更新操作, ```sql const char * stmt_str = "Update t_user set name=? where id = ?"; ``` # Day46 1. 什么是命名空间?其作用是什么?匿名命名空间有什么特点? 2. 什么是 常量指针 和 指向常量 的指针?什么是数组指针和指针数组?什么是函数指针和指针函数?请举例说明。 3. new/delete与malloc/free的区别是什么?(面试常考) 4. 以下代码输出的是___? ```c++ int foo(int x,int y){ if(x <= 0 ||y <= 0) return 1; return 3 * foo(x-1, y/2);//27 } cout << foo(3,5) << endl; ``` 5. 若执行下面的程序时,从键盘上输入5,则输出是() ```c++ int main(int argc, char** argv){ int x; cin >> x; if(x++ > 5){ cout << x << endl; }else{ cout << x-- << endl;// 6 } return 0; } ``` 6. 写出下面程序的结果: ```cpp int main(){ int a[5]={1,2,3,4,5}; int *ptr=(int *)(&a+1); printf("%d,%d",*(a+1),*(ptr-1));// 2,5 } ``` # Day47 1. 什么是函数重载?其实现原理是什么?如何进行C与C++的混合编程? 2. 什么是inline函数?inline与带参数的宏定义之间的区别是什么? 3. C++内存布局是怎样的?可以具体阐述一下么? 4. 定义Student类型,包含数据成员包括姓名、学号、年龄,并用该类型创建不同的对象 # Day48 1. 写出以下程序运行的结果。( ) ```c++ class Sample { public: Sample(); void Display(); private: int i; static int k; }; Sample::Sample(){ i=0; k++; } void Sample::Display(){ cout << "i=" << i << ",k=" << k << endl; } int Sample::k=0; int main( ){ Sample a, b; a.Display(); // 0, 2 b.Display(); // 0, 2 return 0; } ``` 2. 写出下面程序的运行结果() ```cpp class Sample{ int i; public: Sample(); Sample(int val); void Display(); ~Sample(); }; Sample::Sample(){ cout << "Constructor1" << endl; i=0; } Sample::Sample(int val){ cout << "Constructor2" << endl; i=val; } void Sample::Display(){ cout << "i=" << i << endl; } Sample::~Sample(){ cout << "Destructor" << endl; } int main(){ Sample a, b(10); a.Display(); b.Display(); return 0; } ``` > Constructor1 > Constructor2 > i=0 > i=10 3. 写出下面程序的结果: ```cpp int i = 1; class Test{ public: Test() :_fourth(_third),_second(i++),_first(i++),_third(i++){ _third = i; } void print(){ cout << "result : " << _first + _second + _third + _fourth << endl; } private: int _first;//1 int _second;//2 int _third;//4 int &_fourth;//4 }; int main(){ Test test; test.print(); return 0; } ``` > 11 4. 设已经有A,B,C,D 4个类的定义,程序中A,B,C,D析构函数调用顺序为? ```cpp class A{ public: A(){}; ~A(){ cout << "del A" << endl; } }; class B{ public: B(){}; ~B(){ cout << "del B" << endl; } }; class C{ public: C(){}; ~C(){ cout << "del C" << endl; } }; class D{ public: D(){}; ~D(){ cout << "del D" << endl; } }; C c; // 先创建的后销毁 int main(){ A *pa=new A(); B b; static D d; // 静态,但是局部 delete pa; return 0; } /** * ~ a * ~ b * ~ d * ~ c * */ ``` 5. 特殊的成员函数有哪几种?各自的特点是什么? 6. new表达式和delete表达式的底层实现是什么? 7. 实现将Point类型的单例对象创建在静态区的写法,并理解 8. 实现将Point类型的单例对象创建在堆区的写法,并完善 - 需要提供回收单例对象的方法 - 需要灵活使用单例对象,让单例对象的数据成员可以有不同的值 # Day49 1. 实现一个单例的Computer类,包含品牌和价格信息。 2. 创建存放Point对象的vector,尝试进行遍历 3. 创建存放“存放int数据的vector”的vector,尝试进行遍历,并体会vector对象和元素的存储位置 4. 当流失效时,如何重置流的状态,并重新再正常使用流呢? 5. 实现一个自定义的String类,保证main函数对正确执行。实现时,记得采用增量编写的方式,逐一测试。 ```cpp class String{ public: String(); String(const char *pstr); String(const String &rhs); String &operator=(const String &rhs); ~String(); void print(); size_t length() const; const char * c_str() const; private: char * _pstr; }; int main(){ String str1; str1.print(); String str2 = "Hello,world"; String str3("wangdao"); str2.print(); str3.print(); String str4 = str3; str4.print(); str4 = str2; str4.print(); return 0; } ``` # day50 1. 执行以下程序 ```cpp char *str; cin >> str; cout << str; ``` 若输入abcd 1234,则输出( ) 2. 执行以下程序 ```cpp char a[200] = {0}; cin.getline(a, 200, ' '); cout << a; ``` 若输入abcd 1234,则输出( ) 3. 编写一个类,实现简单的栈。栈中有以下操作,并自行写出测试用例,每个函数都需要测试到。 ```cpp class Stack { public: bool empty(); //判断栈是否为空 bool full(); //判断栈是否已满 void push(int); //元素入栈 void pop(); //元素出栈 int top(); //获取栈顶元素 //... }; ``` 4. 安装log4cpp,尝试将log4cpp官网的示例代码跑通 5. 统计一篇英文(TheHolyBible.txt)文章中出现的单词和词频。 输入:某篇文章的绝对路径 输出:词典文件dict.txt(词典中的内容为每一行都是一个“单词 词频”) 词典的存储格式如下。 a 66 abandon 77 public 88 代码设计: ```cpp struct Record{ string _word; int _frequency; }; class Dictionary{ public: //...... void read(const std::string &filename); void store(const std::string &filename); private: vector _dict; }; ``` 提示:因为我们需要统计圣经文件中单词以及该单词在文件中出现的次数,所以可以看去读圣经文件,然后将单词存到数据结构中,并记录单词的次数,如果单词第二次出现的时候,只需要修改单词的次数(也就是这里说的单词的频率),这样当统计完整个圣经文件后,数据都存在数据结构vector了。接着遍历vector数据结构就可以将单词以及单词次数(也就是频率)存储到另外一个文件。(当然如果不存到另外一个文件,就只能打印到终端了) 注意:在读圣经文件的时候,有可能字符串是不合法的,比如:abc123 abc?这样的字符串,处理方式两种:直接不统计这样的字符串或者将非法字母去掉即可。 # Day51 1. 使用log4cpp格式化输出的信息,同时要求输出到终端、文件和回卷文件中。 提示:通过实践来感受log4cpp的使用,这是学习任何第三方库的第一步要做的事儿,先从模仿开始,再慢慢逐步理解。学会使用第三方库,是工作中的基本能力,一定要掌握方法论。 2. 什么是友元?友元的存在形式有?友元有何特点? 3. 运算符重载的原则是什么?有哪些规则?不能重载的运算符有哪几个? 4. 编写Base类使下列代码输出为1 ```cpp int i=2; int j=7; Base x(i); Base y(j); cout << (x+y == j - i) << endl; ``` 提示:本题考查的其实就是运算符重载的知识点。 5. 利用运算符重载,使Point对象能够进行+、+=、前置++、后置++操作(对坐标进行计算) 6. 用所学过的类和对象的知识,封装log4cpp,让其使用起来更方便,要求:可以像printf一样,同时输出的日志信息中最好能有文件的名字,函数的名字及其所在的行号(这个在C/C++里面有对应的宏,可以查一下) 代码模板: ```cpp class Mylogger{ public: void warn(const char *msg); void error(const char *msg); void debug(const char *msg); void info(const char *msg); private: Mylogger(); ~Mylogger(); private: //...... }; void test0(){ //第一步,完成单例模式的写法 Mylogger *log = Mylogger::getInstance(); log->info("The log is info message"); log->error("The log is error message"); log->fatal("The log is fatal message"); log->crit("The log is crit message"); } void test1() { printf("hello,world\n"); //第二步,像使用printf一样 //只要求能输出纯字符串信息即可,不需要做到格式化输出 LogInfo("The log is info message"); LogError("The log is error message"); LogWarn("The log is warn message"); LogDebug("The log is debug message"); } ``` # Day52 1. C++中函数对象、成员函数指针该如何使用呢?请用代码给出示例。 2. 自定义一个String类保存字符串内容,实现以下String类的各个函数,并给出相应的测试用例 ```cpp class String{ public: String(); String(const char *); String(const String &); ~String(); String &operator=(const String &); String &operator=(const char *); String &operator+=(const String &); String &operator+=(const char *); char &operator[](std::size_t index); const char &operator[](std::size_t index) const; std::size_t size() const; const char* c_str() const; friend bool operator==(const String &, const String &); friend bool operator!=(const String &, const String &); friend bool operator<(const String &, const String &); friend bool operator>(const String &, const String &); friend bool operator<=(const String &, const String &); friend bool operator>=(const String &, const String &); friend std::ostream &operator<<(std::ostream &os, const String &s); friend std::istream &operator>>(std::istream &is, String &s); private: char * _pstr; }; String operator+(const String &, const String &); String operator+(const String &, const char *); String operator+(const char *, const String &); ``` # Day53 1. 实现pimpl设计模式,并体会其思想 2. 在类之外定义一个全局类AutoRelease,实现单例模式的自动释放 3. 使用嵌套类和静态对象的方式,实现单例模式的自动释放 4. 使用atexit函数结合静态destroy函数,实现单例模式的自动释放 # Day54 1. 使用pthread_once函数结合destroy函数,实现单例模式的自动释放 2. 实现一个采用COW技术的自定义字符串类型CowString,并让其下标访问运算符能区分出读操作和写操作。 3. 实现以下函数,简单模拟SSO思想的string并验证实现效果 ```cpp class String { public: String(const char * pstr); ~String(); char & operator[](size_t idx); friend ostream & operator<<(ostream & os,const String & rhs); private: union Buffer{ char * _pointer = nullptr; char _local[16]; }; size_t _size; size_t _capacity; Buffer _buffer; }; void test0(){ String str1("hello"); String str2("hello,world!!!!!"); //... } ``` # Day55 1. 词频统计的作业再用map容器去实现一次,体验一下使用vector/map时程序执行的速度 提示:++dict[word]; 2. 文本查询 该程序将读取用户指定的任意文本文件【当前目录下的china_daily.txt】,然后允许用户从该文件中查找单词。查询的结果是该单词出现的次数,并列出每次出现所在的行。如果某单词在同一行中多次出现,程序将只显示该行一次。行号按升序显示。 要求: a. 它必须允许用户指明要处理的文件名字。 b. 程序将存储该文件的内容,以便输出每个单词所在的原始行。 ```cpp vector lines; // lines[i]表示第i行的内容 ``` c. 它必须将每一行分解为各个单词,并记录每个单词所在的所有行。在输出行号时,应保证以升序输出,并且不重复。 ```cpp map > wordNumbers; // k表示string,v表示k所在行号的集合 map dict; // k表示string,v表示出现频率 ``` d. 对特定单词的查询将返回出现该单词的所有行的行号。 e. 输出某单词所在的行文本时,程序必须能根据给定的行号从输入文件中获取相应的行。 示例: 使用提供的文件内容,然后查找单词 "element"。输出的前几行为: > element occurs 125 times. > (line 62) element with a given key. > (line 64) second element with the same key. > (line 153) element |==| operator. > (line 250) the element type. > (line 398) corresponding element. 程序接口[可选]: ```cpp class TextQuery{ public: //...... void readFile(const string filename); void query(const string & word);// private: //...... vector _lines;//O(1) map > _wordNumbers;//the the map _dict;// }; //程序测试用例 int main(int argc, char *argv[]){ string queryWord("hello"); TextQuery tq; tq.readFile("test.dat"); tq.query(queryWord); return 0; } ``` 3. 使用tinyXml2库解析RSS文件,并生成一个网页库pagelib.txt tinyXml2 -- https://github.com/leethomason/tinyxml2 rss -- http://www.runoob.com/rss/rss-tutorial.html 对于html的标签需要使用正则表达式进行过滤,正则表达式需要用到标准库中的std::regex 参考接口: ```cpp struct RssItem { string title; string link; string description; string content; }; class RssReader{ public: RssReader(); void parseRss();//解析 void dump(const string & filename);//输出 private: vector _rss; }; ``` 要求:最后生成一个 pagelib.txt, 其格式如下: ```html 1 ... ... ... ... ... ... ``` 提示:RSS文件解析作业思路: xml --> rss --> tinyxml2 --> std::regex # Day56 1. 三种继承方式对于基类成员的访问权限是怎样的? 2. 多基派生会产生的问题有哪些?怎样解决? 3. 指出并改正下面程序中的错误。 ```cpp #include using std::cout; using std::endl; class Point{ public: Point(int a=0, int b=0){ x = a; y = b; } void move(int xoffset,int yoffset){ x += xoffset; y += yoffset; } int getx(){ return x; } int gety(){ return y; } private: int x,y; }; class Rectangle:protected Point{ public: Rectangle(int x, int y, int l, int w): Point(x,y){ length = l; width = w; } int getLength(){ return length; } int getWidth(){ return width; } private: int length; int width; }; int main(){ Rectangle r(0, 0, 8,4); /* 类外不可调用protected继承的成员, 要修改继承权限为public */ r.move(23,56); cout << r.getx() << "," << r.gety() << "," << r.getLength() << "," << r.getWidth() << endl; return 0; } ``` 4. 指出并改正下面程序中的错误。 ```cpp #include using std::cout; using std::endl; class A{ public: int x; A(int a = 0){ x = a; } void display(){ cout<< "A.x = " << x << endl; } }; class B{ public: int x; B(int a = 0){ x=a; } void display(){ cout<<"B.x = " << x << endl; } }; class C:public A,public B{ public: C(int a, int b, int c): A(a), B(b){ y=c; } int gety(){ return y; } private: int y; }; int main(){ C myc(1,2,3); /* 没有加作用域 */ myc.A::x = 10; myc.A::display(); return 0; } ``` 5. 看程序写结果 ```cpp #include using std::cout; using std::endl; class Base{ public: Base(int n){ cout <<"Constructing base class" << endl; _ix=n; } ~Base(){ cout <<"Destructing base class" << endl; } void showX(){ cout << _ix << ","; } int getX(){ return _ix; } private: int _ix; }; class Derived:public Base{ public: Derived(int n, int m, int p): Base(m), _base(p){ cout << "Constructing derived class" < using namespace std; class A { public: A() { cout << "A's cons." << endl; } virtual ~A() { cout << "A's des." << endl; } virtual void f() { cout << "A's f()." << endl; } void g() { f(); } }; class B : public A { public: B() { f(); cout << "B's cons." << endl; } ~B() { cout << "B's des." << endl; } }; class C : public B { public: C() { cout << "C's cons." << endl; } ~C() { cout << "C's des." << endl; } void f() { cout << "C's f()." << endl; } }; int main(void) { A *pa = new C(); pa->g(); delete pa; /** * A's cons. * A's f(). * B's cons. * C's cons. * C's f(). * "C's des. * B's des. * A's f(). */ return 0; } ``` 3. 写出下列程序的输出结果。 ```cpp #include using namespace std; class A { public: virtual void func(int val = 1) { cout << "A->" << val << endl; } virtual void test() { func(); } private: long _a; }; class B : public A { public: /** * 覆盖了父类的内容;函数名、返回值、默认值没有覆盖 * @param val */ virtual void func(int val = 10) { cout << "B->" << val << endl; } private: long _b; }; class C : public B { virtual void func(int val = 10) { cout << "C->" << val << endl; } }; int main(void) { B b; A *p1 = (A *) &b; B *p2 = &b; p1->func(); p2->func(); /** * B->1 * B->10 * */ return 0; } ``` 4. 根据给定的程序,写出执行结果 ```cpp #include using std::endl; using std::cout; class A { public: A(int i, int j) { a = i; b = j; } void move(int i, int j) { a += i; b += j; } void disp() { cout << "(" << a << "," << b << ")" << endl; } private: int a, b; }; class B : public A { public: B(int i, int j, int k, int l) : A(i, j), x(k), y(l) { } void disp() { cout << x << "," << y << endl; } void fun() { move(3, 5); } private: int x, y; }; int main() { A m(1, 2); m.disp();// (1,2) B d(3, 4, 5, 6); d.fun();// i = 6, j = 9 d.A::disp();// (6, 9) d.disp();// 5, 6 /** * (1,2) * (6,9) * 5,6 */ return 0; } ``` 5. 根据给定的程序,写出执行结果 ```cpp #include using std::endl; using std::cout; class A { public: void FuncA() { printf("FuncA called\n"); } virtual void FuncB() { printf("FuncB called\n"); } }; class B : public A { public: void FuncA() { A::FuncA(); printf("FuncAB called\n"); } virtual void FuncB() { printf("FuncBB called\n"); } }; int main(void) { B b; A *pa; pa = &b; A *pa2 = new A; pa->FuncA(); pa->FuncB(); pa2->FuncA(); pa2->FuncB(); delete pa2; /** * FuncA called * FuncBB called * FuncA called * FuncB called * */ return 0; } ``` 6. 根据给定的程序,写出执行结果 ```cpp #include using std::endl; using std::cout; class Base { public: Base(int j) : i(j) { } virtual ~Base() { } void func1() { i *= 10; func2(); } int getValue() { return i; } protected: virtual void func2() { i++; } protected: int i; }; class Child : public Base { public: Child(int j) : Base(j) { } /* 重写了父类方法 */ void func1() { i *= 100; func2(); } protected: /* 覆盖了父类方法 */ void func2() { i += 2; } }; int main() { Base *pb = new Child(1); /* 访问的是父类的fun1 */ pb->func1(); cout << pb->getValue() << endl; delete pb; /** * 12 */ return 0; } ``` 7. 带虚函数的单继承结构下,虚函数地址的存放规则是怎样?请用代码验证 8. 编写程序:给定以下抽象类Figure,通过该图形类扩展生成3个不同的图形Rectangle、Circle、Triangle,体会使用纯虚函数的好处。 ```cpp class Figure { public: virtual string getName() const = 0; virtual double getArea() const = 0; }; void display(Figure & fig) { cout << fig.getName() << "的面积是:" << fig.getArea() << endl ; } void test() { Rectangle r(10, 20); Circle c(15); Triangle t(3, 4, 5); display(r); display(c); display(t); } ``` # Day58 1. 根据给定的程序执行结果,将下列程序补充完整。 ```cpp #include using std::endl; using std::cout; class Base { public: Base(int i) { b = i; } Base() : b(0) {} virtual void Print() { cout << "Base 's Print() called." << endl; } protected: int b; }; class Derived1: public Base { public: void Print() { cout << "Derive1's Print() called." << endl; } }; class Derived2 : public Base { public: void Print() { cout << "Derive2's Print() called. " << endl; } }; //Base * obj void fun(Base* obj) { obj->Print(); } int main(void) { Derived1 d1; Derived2 d2; fun(&d1); fun(&d2); return 0; } /* Derive1's Print() called. Derive2's Print() called. */ ``` 2. 根据给定的程序,写出执行结果 ```c++ #include using std::endl; using std::cout; class Base1 { public: virtual void fun() { cout << "--Base1--\n"; } }; class Base2 { public: void fun() { cout << "--Base2--\n"; } }; class Derived : public Base1, public Base2 { public: void fun() { cout << "--Derived--\n"; } }; int main() { Base1 obj1, *ptr1; Base2 obj2, *ptr2; Derived obj3; /** * --Base1-- * --Base2-- * --Derived-- * --Base2-- */ ptr1 = &obj1; ptr1->fun(); ptr2 = &obj2; ptr2->fun(); ptr1 = &obj3; ptr1->fun(); ptr2 = &obj3; ptr2->fun();// return 0; } ``` 3. 虚函数的多继承结构下,虚函数地址的存放规则是怎样?利用VS验证规则 4. 请分析如下结构下的各种访问情况 ```c++ #include using std::endl; using std::cout; class A { public: virtual void a() { cout << "A::a()" << endl; } void b() { cout << "A::b()" << endl; } virtual void c() { cout << "A::c()" << endl; } void e() { cout << "A::e()" << endl; } }; class B { public: virtual void a() { cout << "B::a()" << endl; } void c() { cout << "B::c()" << endl; } void d() { cout << "B::d()" << endl; } virtual void f() { cout << "B::f()" << endl; } }; class C : public A, public B { public: virtual void a() { cout << "C::a()" << endl; } virtual void b() { cout << "C::b()" << endl; } void c() { cout << "C::c()" << endl; } void d() { cout << "C::d()" << endl; } }; void test0() { /** * C::a() * C::b() * C::c() * C::d() * A::e() * B::f() */ // 未通过指针调用,均未访问虚表 C c; c.a(); c.b(); c.c(); c.d(); c.e(); c.f(); cout << endl; /** * C::a() * A::b() * C::c() * A::e() * */ A* pa = &c; pa->a();/* 覆盖 */ pa->b(); pa->c();/* 覆盖 */ // pa->d(); 子类自定义的方法父类不可访问 pa->e(); // pa->f(); B类的方法A的指针不可访问 cout << endl; /* * C::a() * B::c() * B::d() * B::f() */ B* pb = &c; pb->a();/* 访问虚表但是goto C::a()*/ // pb->b(); 子类自定义的方法父类不可访问 pb->c();/* 不是虚函数 */ pb->d();/* 不是虚函数 */ // pb->e(); pb->f();/* 访问虚表,但是子类未覆盖此方法,所以调B::f()*/ cout << endl; /** * C::a() * C::b() * C::c() * C::d() * A::e() * B::f() */ C * pc = &c; pc->a();/* 访问虚表,但是没触发多态 */ pc->b();/* 访问虚表,但是没触发多态 */ pc->c();/* 覆盖A的c() */ pc->d();/* 隐藏 */ pc->e();/* 仅仅继承 */ pc->f();/* 访问虚表,但是没触发多态 */ } int main(void) { test0(); return 0; } ``` # Day59 1. 练习函数模板和类模板的基础用法,多写才能熟悉 2. 使用函数模板实现两个整数类型数据相加、两个double型数据相加、两个存放int型元素的set融合 3. 使用类模板定义出可以存放各种类型元素的栈 4. 利用可变模板参数实现一个函数模板,用来计算多个整型、浮点型数据的加法,返回类型为double # Day60 1. 使用类模板模拟RAII的思想,使其管理堆上的Computer资源 2. C++提供了哪几种智能指针,其各自的特点是什么?请通过代码进行练习、验证 3. 理解shared_ptr的循环引用问题(面试容易问到),掌握解决的方法,通过代码验证 4. unique_ptr和shared_ptr需要注意哪些误用的情况,应该如何解决(避免),请通过代码进行说明。 # Day61 1. 实现C++ primer 15.9中的文本查询扩展的作业,可以查某个单词在某行出现、某个单词在某行没有出现、某两个单词在某行出现、某两个单词至少有一个出现、三个单词的查询等等。(即实现查询单词的与、或、非操作) # Day62 1. STL包括哪些组件?各自具有哪些特点? 2. STL中的容器包括哪些?各自具有哪些特点? 3. 序列式容器包括哪些?他们之间有哪些异同? 4. 下面程序有什么错误? ```cpp list lst; list::iterator iter1 = lst.begin(), iter2 = lst.end(); while(iter1 < iter2){ //.... } ``` 5. 创建和初始化vector的方法,每种都给出一个实例?当然也可以把deque与list写出来 6. 如果c1与c2是两个容器,下面的比较操作有什么限制? ```cpp if(c1 < c2) ``` 7. 使用模板实现一个快速排序算法 ```cpp template> class MyQsort{ public: MyQsort(T *arr, size_t size, Compare com); void quick(int left, int right, Compare &com); int partition(int left, int right, Compare &com); void print(); private: vector _vec; }; ``` # Day63 1. 关联式容器有哪些?各自具有哪些特点?(熟悉基本操作) 2. 使用map重写词频统计作业。(之前使用的vector,可以比较他们的速率) 3. 使用模板实现一个堆排序算法 使用模板的框架如下: ```cpp template > class HeapSort{ public: HeapSort(T *arr, size_t size); void heapAdjust(size_t ,size_t); void sort(); void print(); ​ private: vector _vec; Compare _cmp; }; ``` # Day64 1. 无序关联式容器有哪些?各自具有哪些特点? 2. 使用unordered_map重写词频统计作业。再比较一下使用map和vector时所花费的时间,体会这几种容器的区别 3. 使用unordered_map/map实现单词转换程序。给定一个string,将它转换为另一个string。程序的输入是两个文件,第一个文件保存的是一些规则,用来转换第二个文件中的文本。每条规则由两部分组成:一个可能出现在输入文件中的单词和一个用来替换它的短语。表达的含义是,每当第一个单词出现在输入中时,我们就将它替换为对应的短语,第二个输入文件包含要转换的文本。(C++ primer 11.3.6) 提示: 规则文件:map.txt文件,其实就是第一个单词,被后面的一串所替换。 待转换文本:file.txt文件,该文件中的单词如果出现在map.txt文件的第一个单词的话,就用map.txt的后面一串替代。 结果:最后结果其实就是,将file.txt文件中的并且出现在map.txt中第一个单词转换为map.txt后面的一串。例如:where r u的输出结果就是where are you. r替换为are,u替换为you ``` //file.txt where r u y dont u send me a pic k thk l8r //map.txt brb be right back k okay? y why r are u you pic picture thk thanks! l8r later ``` # Day65 1. Leetcode 146 LURCache的实现 2. 无序关联式容器有哪些?各自具有哪些特点? 3. Leetcode 127题 # Day66 1. 算法库中有哪些类型的操作?什么是函数对象? 2. 容器、迭代器、算法之间的关系是怎样的?他们是如何结合在一起的? 3. 什么是迭代器失效问题?该问题是如何产生的?怎样避免产生迭代器失效问题 4. 什么是回调函数,注册回调函数,执行回调函数?(掌握std::bind用法,非常重要) std::bind的实现原理阅读材料 5. Leetcode 20题 # Day67 1. 了解std::allocator的用法之后,实现自定义的Vector类 接口形式: ```cpp template class Vector { public: Vector(); ~Vector(); void push_back(const T &); void pop_back(); int size(); int capacity(); private: void reallocate();//重新分配内存,动态扩容要用的 private: static std::allocator _alloc; T *_start; //指向数组中的第一个元素 T *_finish; //指向最后一个实际元素之后的那个元素 T *_end_of_storage; //指向数组本身之后的位置 }; Vector模型 ______________________________ |_|_|_|_|_|____________________| ↑ ↑ ↑ _start _finish _end_of_storage ``` # Day68 调试allocator源码. # Day69 1. 扩展阅读(阅读,加深对面向对象的理解) [OO真经]:https://www.cnblogs.com/leoo2sk/archive/2009/04/09/1432103.html 2. 类与类之间的关系有哪几种?各自的特点怎样的? 3. 面向对象设计有哪些原则?各自的特点是什么? 4. 运用所学的UML类图的知识,画出“文本查询程序的扩展”作业的类图。【C++ Primer 15.9节作业】(可以贴图) 5. 设计模式可以分为几类?分别有哪些? 6. 什么是单例模式?它有哪些特点? # Day70 1. 什么是工厂模式?它有哪些特点? 2. 什么是观察者模式?它有哪些特点? 3. 实现工厂模式,并画出其类图 4. 实现观察者模式,并画出其类图 # Day71 1. 使用C++11的线程、互斥锁、条件变量实现生产者消费者代码 2. 根据Linux下的POSIX标准,封装互斥锁与条件变量的对象 MutexLock类,封装加锁、解锁、尝试上锁函数,以及锁的初始化与销毁。甚至为了避免死锁,可以封装MutexLockGuard类,利用RAII思想实现,构造函数中上锁,析构函数中解锁。 Condition类,封装条件变量的等待、唤醒(唤醒至少一个与唤醒所有)、以及条件变量的初始化与销毁函数。 根据以上思路,自己封装互斥锁与条件变量类 3. 根据面向对象的设计原则,自己独立对Linux下,POSIX标准线程的封装。 ```cpp /* 数据成员: */ pthread_t _thid; //线程id bool _isRunning;//线程是否运行的标志 /* 成员函数:*/ void start();//线程启动函数,封装pthread_create函数 void stop();//线程停止,封装pthread_join void *threadFunc(void *arg);//线程入口函数 virtual void run()=0;//线程需要执行的任务,纯虚函数,留给派生类使用 ``` 根据以上提示,实现POSIX线程的封装 # Day72 实现面向对象的线程池(重点掌握Threadpool的实现)以及 实现基于对象的线程池(两者对比看看) # Day73 1. TCP链接建立的过程需要三次握手,为什么? 2. TCP链接断开的过程需要四次挥手,为什么? 3. 关闭链接时,服务器端可不可以主动断开链接?为什么? 4. 为什么需要TIME_WAIT状态,该状态可以删除吗? 5. TCP协议和UDP协议有啥区别? 6. 网络IO复用模型有哪些?它们之间的异同是什么? 7. 网络IO模型有哪些? 8. 什么是同步、异步?什么是阻塞、非阻塞? 编程题:自己实现ReactorV1版本的类图与源码。 # Day74 ReactorV2版本特征: 1、封装了IO多路复用epoll的三个函数,这三个函数的封装,希望大家写出来,目的是熟悉epoll的使用 2、TCP网络通信过程中的三个事件是什么?连接建立、连接断开、消息到达(文件描述符可读),三个事件使用回调函数的写法,注册回调函数与执行回调函数。(这是一个难点,大家重点关注,搞懂并封装出来) 3、三个事件都是与TcpConnection相关的,但是需要通过EventLoop中转,因为TcpConnection是在EventLoop中创建出来的,所以EventLoop只中转,只注册不执行,但是TcpConnection既要注册也要执行 4、其他语法特性:键值对map或者unordered_map、智能指针以及智能指针的误用 搞清楚上述几点后,将ReactorV2的流程搞清楚,然后自己独立实现出来 # Day75 ReactorV4版本特征 1、要熟练写出面向对象线程池与基于对象线程池的代码,我们这里要用到的是基于对象线程池 2、EventLoop,也就是Reactor与线程池的通信,使用的关键是eventfd方式。(eventfd如何函数接口是什么、如何在进程间通信、如何在线程间通信),熟悉eventfd的用法 3、线程池与Reactor通信的方式,就是eventfd的使用方式,将线程池线程是A线程,将EventLoop看成是B线程,一个执行write函数,一个执行read函数,搞清楚这一点 根据以上三点提示,自己独立实现ReactorV4版本,这是项目要用到的版本,也是面试中项目的框架 # Day76 1. 什么是Redis?有哪些有优缺点? 2. 为什么要用 Redis /为什么要用缓存 3. Redis为什么这么快? 4. Redis有哪些常用数据类型? 5. 什么是Redis持久化? 6. Redis 的持久化机制是什么?各自的优缺点? 7. Redis key的过期时间和永久有效分别怎么设置? 8. Redis事务的概念?Redis事务的三个阶段?Redis事务相关命令和事务的特征? 9. 将每种数据类型的命令多敲击一下,加深印象?(这个自己下面多敲一敲,熟悉一下,此题不交) 10. 将每种数据类型的命令多敲击一下,加深印象?(这个自己下面多敲一敲,熟悉一下,此题不交) 11. 自己动手配置一下主从复制与哨兵模式、以及hiredis的封装(加深一下理解) # Day77 1. 说明一下Qt生成的项目模板中有哪些文件和文件夹,分别有什么作用? 2. Qt Creator中有哪几个模式,切换的快捷键是什么? 3. 如何查看某个Qt内置类的帮助文档,如何查看某个类的源代码?QApplication的继承体系是怎么样的? 4. QString和std::string和char数组有什么区别?QString增删改查用什么成员函数? 5. 给出一个路径'/usr/include/dir1/dir2': > 将路径切割并存入一个栈中。 > 实现cd 子目录和cd 上一级功能,返回路径的字符串。 7. 实现一个井字棋 点击空白按钮可以显示'X'或者'O' > 基本功能:悔棋,重开 8. 实现一个计算器 > 基本功能:清空,退格,小括号,加减乘除 # Day78 1. 使用元对象系统的注意事项有哪些? 2. 书写一个用于显示属性配置的程序 > 2个QLineEdit、3个QPushButton、1个QLabel > 左边QLineEdit可以输入 ip port username password 等其他字符串 > 右边QLineEdit可以输入 左边属性对应的值 > submit按钮可以提交数据 > 要求,所有的属性存入一个QMap中 3. connect函数有几种重载形式?哪一种更好为什么? 4. 信号和槽机制的目的是什么?书写代码实现一个自定义信号和自定义槽函数。 5. 现在有三个对象A,B,C > 需要实现下面效果: > A发射信号会导致 B调用槽函数 C调用槽函数 > B发射信号会导致 C调用槽函数 > C发射信号会导致 A发射信号 # Day79 1. 简述信号和槽机制的优势和劣势 2. 优化井字棋(请使用 sender 和 qobject_cast 重写) 3. 优化计算器(使用 sender 和 qobject_cast 重写) # Day80 1. 简述事件的产生、分发和处理流程,中间会产生哪些类型的对象,调用了什么方法。 2. 创建一个程序,存在一个窗口W,W的大小是800\*600,存在两个QPushButton子类对象A和B,位置是0,0 和 400,150。使用信号槽机制和事件机制,当在鼠标在A上按住并移动时,获取鼠标位置x和y,并将B的位置改成10\*x+400, 10\*y+150 3. 创建一个界面W,上面有QPushButton对象A,B,C,D,E,F: > 将A作为根,BCD是A的孩子,E、F是B的孩子: > 在E上触发鼠标按下事件,传递给W处理 > 在所有对象上触发鼠标移动事件,显示当前鼠标位置 > 进入E和F对象之后,C会移动到另一个位置 > 只要C移动,D也会移动 4. 实现一个“打蚊子”游戏 在屏幕中央有一个600\*400的QWidget,一个用来统计分数的QLabel 一开始会在QWidget内部随机位置生成一个蚊子,当鼠标点击到蚊子以后,旧蚊子消失然后在另一个位置生成新的蚊子,分数增加。 > 提示:这里需要继承QWidget类然后重写paintEvent,在paintEvent当中可以创建QPainter对象绘制各种图形和图片 5. 通过修改QWidget的构造函数的参数来实现下面不同风格的窗口,并显示窗口选项(官方示例的 Window Flags Example ) # Day81 1. 尝试使用Model View来展示一个好友名字列表。模型采用线性表即可。 # Day82 1. 绘制界面,向目标网站发送http请求,并将响应的报文体保存着本地的某个路径当中. [案例代码](https://github.com/LewisGu/Qt5.9C-DevelopmentTutorialCode/tree/master/Source/QT5.9Samp2019/chap14Network/samp14_5HTTP) 2. HTTP的中文全称是什么?从全称的每个字段来说明HTTP的特点。 3. URI由哪些部分组成? 4. HTTP请求报文和响应报文由哪些部分组成?HTTP常用方法有哪些?HTTP常用状态码有哪些? 5. 为什么需要将HTTP协议设计成无状态的呢? # Day83 1. Nginx和Apache最大区别是什么? 2. 使用Nginx部署一个图片服务器,使用markdown即可测试。 3. 有哪些负载均衡策略?各有什么优缺点? 4. 基于workflow实现一个类似于curl命令的可执行程序 # Day84 1. 存在下列的redis键值映射关系,使用workflow的redis任务和序列,假如只知道"x1",如何找到最终的"100"? > "x1" --> "x2" > "x2" --> "x3" > "x3" --> "x4" > "x4" --> "100" 2. 读取某个网站的内容,并且存入redis服务端当中(比如先访问淘宝,再set www.taobao.com 淘宝的html内容) 3. 部署一个登录网站 - 在redis服务端当中插入一条用户注册信息(比如 HSET USERINFO LIAO 123) - 当用户向ip:port/login发生请求的时候,返回postform.html(在今日的共享目录当中有提供)静态资源 - 在用户获取完网页界面之后,在网页上输入用户名和密码,再点击按钮,即可产生一个POST请求 - 使用wireshark可以获取报文的具体格式,并且根据请求数据,返回登录的结果 # Day85 1. 调试workflow的mysql 2. 安装wfrest 3. 调试网盘project_v1项目 > 1、数据库的用户名密码是root:123; > 2、需要参考tbl_sql.sql里面的指令创建几张表格,database的名字是cloudisk > 3、file.conf是nginx的配置文件,里面root的参数需要根据自己的本地路径进行修改)