前言
这里简单记录下
牛客在线刷题
记录
华为机试
题号 | 题名 | 知识点 | 难度 | 提交时间 |
---|---|---|---|---|
JC001 | 字符串最后一个单词的长度 | 字符串 | 较难 | 2020-06-28 |
JC002 | 计算字符个数 | 字符串 哈希表 | 较难 | 2020-06-28 |
JC003 | 明明的随机数 | 数组 | 较难 | 2020-06-28 |
JC004 | 字符串分隔 | 字符串 | 较难 | 2020-06-29 |
JC005 | 进制转换 | 字符串 | 中等 | 2020-06-29 |
JC006 | 质数因子 | 质数 | 中等 | 2020-06-29 |
JC007 | 取近似值 | 数学 | 入门 | 2020-06-29 |
JC008 | 合并表记录 | 字典 | 中等 | 2020-06-29 |
JC009 | 提取不重复的整数 | 数组 哈希 | 中等 | 2020-06-29 |
JC010 | 字符个数统计 | 字符串 哈希 | 中等 | 2020-06-29 |
JC011 | 数字颠倒 | 字符串 | 简单 | 2020-06-29 |
面试宝典
https://www.nowcoder.com/tutorial/93/8ba2828006dd42879f3a9029eabde9f1
基础知识
基础语言I
- static关键字
- c++和c的区别
- c++的四种强制类型转换
- 指针和引用的区别
- 给定三角形ABC和P,判断P时候在ABC内
面积法、向量叉乘
- 智能指针shared_ptr
- 数组和指针
- 指针和引用
基础语言II
- 析构函数
virtual
、虚表、虚指针
析构函数默认非virtual
析构函数的作用: - 函数指针和指针函数
指针函数:int* fun(int x, int y);
函数指针:int (*fun)(int x, int y); - 静态函数和虚函数
静态绑定、动态绑定、虚函数表
- 重载、重写(覆盖)、隐藏
重载(overload):在同一作用域中,同名函数的形式参数(参数个数、类型或者顺序)不同时,构成函数重载,与返回值类型无关
重写/覆盖(override):派生类中与基类同返回值类型、同名和同参数的虚函数重定义,构成虚函数覆盖,也叫虚函数重写,基类中被重写的函数必须有virtual
修饰
隐藏(hiding):指派生类的函数屏蔽了与其同名的基类函数。注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏 strcpy
和strlen
以’\0’为结束符
- 虚函数和多态
静态多态:重载、模板多态
动态多态:用虚函数机制实现的,在运行期间动态绑定,使用了虚函数,会增加访问内存开销,降低效率 ++i
和i++
1
2
3
4
5
6
7
8
9
10
11int& int::operator++()
{
*this += 1;
return *this;
}
const int int::operator(int)
{
int oldValue = *this;
++(*this);
return oldValue;
}- 写个函数在
main
函数执行前先运行1
2void before() __attribute__((constructor));
void after() __attribute__((destructor)); - 四行代码的区别
1
2
3
4const char* arr = "123";
char* brr = "123";
const char crr[] = "123";
char drr[] = "123";
基础语言III
- 栈空间的最大值
Windows下,默认栈空间大小为2MB
Linux下,默认栈空间大小为8MB,可通过ulimit -s
来设置
Windows更改栈空间大小的方法:
link时用/STACK
指定它的大小,或者在.def中使用STACKSIZE
指定它的大小。
使用控制台命令EDITBIN
更改exe的栈空间大小 - extern “C”
- new/delete与malloc/free区别
- RTTI(运行期类型识别)和RAII(以对象管理资源)
- c++虚函数表怎么实现运行时多态 虚函数表指针
- c语言怎么进行函数调用 函数栈
- c语言参数压栈顺序 从右往左
- c++如何处理返回值 生成临时变量,把它的引用作为函数参数传入函数内
- select模型
- fork、wait和exec函数
容器和算法
- map和set的区别,底层实现
都是关联式容器,底层实现都是红黑树(RB-Tree),一种平衡二叉搜索树
map:所有元素都是pair(key-value),会根据元素的value自动排序,key不允许重复
set:所有元素会根据元素的值(key即value)自动排序,且不允许重复 - STL的allocaotr
c++的内存配置和释放:new运算分为两个阶段:(1)调用operator new配置内存;(2)调用对象的构造函数构造对象内容
delete运算分为两个阶段:(1)调用对象的析构函数;(2)调用operator delete释放内存1
2
3
4
5
6
7STL allocator将两个阶段操作区分开来:内存配置有alloc::allocate()负责,内存释放由alloc::deallocate()
负责;对象构造由::construct()负责,对象析构由::destroy()负责
同时为了提升内存管理的效率,减少申请小内存造成的内存碎片问题,SGI STL采用了两级配置器,当分配的空间大小
超过128B时,会使用第一级空间配置器;当分配的空间大小小于128B时,将使用第二级空间配置器。第一级空间配置器
直接使用malloc()、realloc()、free()函数进行内存空间的分配和释放,而第二级空间配置器采用了内存池技术,
通过空闲链表来管理内存 - 迭代器删除元素
迭代器失效问题
- STL中map数据存放形式
map底层是红黑树;unordered_map底层是哈希表
- STL的基本组成
容器、迭代器、仿函数、算法、分配器和配接器
- STL中map与unordered_map
map(有序)底层是红黑树;unordered_map(无序)底层是哈希表
- vector与list的区别及应用
vector:动态数组,经常随机访问,不经常对非尾节点进行插入删除
list:动态链表,经常插入删除,随机访问效率差 - STL中迭代器的作用,有指针为何还有迭代器
迭代器不是指针,是类模板,表现的像指针
迭代器返回的是对象引用而不是对象的值,所以cout只能输出迭代器使用*
解引用后的值而不能直接输出迭代器本身 - epoll模型的原理
1
2
3int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); - STL迭代器是怎么删除元素的
迭代器失效问题
- STL的resize和reservere的区别
resize():改变当前容器内含有元素的数量(size()),会新增len-size个元素,默认值为0
reserve():改变当前容器的最大容量(capacity()),不会生成元素
ps. vector一次性分配好内存,内存不够时才进行2倍扩容(win+vs2019下测试与该说法不一致,如下)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18void test() {
std::vector<int> v;
v.reserve(100);
v.resize(50);
std::cout << v.size() << " " << v.capacity() << std::endl; //50 100
v.resize(150);
std::cout << v.size() << " " << v.capacity() << std::endl; //150 150
v.reserve(50);
std::cout << v.size() << " " << v.capacity() << std::endl; //150 150
v.resize(50);
std::cout << v.size() << " " << v.capacity() << std::endl; //50 150
v.shrink_to_fit();
std::cout << v.size() << " " << v.capacity() << std::endl; //50 50
} - O(n)实现无需数组,查找每个元素后比它大的第一个数
类和数据抽象
- 类成员的访问权限
private:只能在类的成员函数和友元函数中访问,不能被其他访问,类的对象也不能访问
protected:可以在类的成员函数、子类的成员函数和友元函数访问,但不能被该类的对象访问
public:可以在类的成员函数、子类的成员函数和友元函数访问,也可以被该类的对象访问 - struct和class的区别
struct默认继承权限和默认访问权限是public,而class的默认继承权限和默认访问权限是private
初次之外,二者没有其他区别,struct多用于定义数据类型,class多用于定义对象类型 - c++类内如何定义引用数据成员
c++类内可以定义引用成员变量,但要遵循以下三个规则:不能用默认构造函数初始化,必须提供构造函数来初始化引用成员变量,否则会造成引用未初始化错误
构造函数的形参也必须是引用类型
不能在构造函数里初始化,必须在初始化列表中进行初始化
面向对象与泛型编程
- 右值引用、移动语义和完美转发