滴滴2022
1.redis过期策略
定时删除,定期删除,惰性删除
定时删除:设定一个过期时间,时间到了就把它删掉,对cpu不太友好,但是对内存友好
定期删除:每隔一个周期删除一次,对cpu和内存都比较友好
惰性删除:等需要查找的时候再看它是否过期,过期了再删,对cpu友好但是对内存不友好
2.Mysql索引应用场景
索引好是好能提高查找效率,但它也是有资源消耗的。
频繁需要查找的列;
唯一性低的列(性别不需要,学号需要);
经常需要排序、分组、联查的列;
数据重复度低的列。
需要注意的是,对于比较小的表,没有索引查找效率也高,对于大表,有索引可能查找效率也低,这时可能需要分库分表。
3.Tcp和Udp的区别
tcp是面向连接,udp无连接
tcp传递数据包大小不限,udp最大传64k
tcp可靠,udp不可靠
tcp头部20字节,udp头部8字节
4.手撕代码:合并两有序数组
注意是把其中一个数据合并到另一个数组里还是把两个数组的数据放到一个新数组里。
使用双指针遍历,当一个数组数据遍历完了而另一个没完需要再把剩余的数据加进去
void merge(int A[], int m, int B[], int n) {
int i=m-1;
int j=n-1;
int k=m+n-1;
while(i>=0&&j>=0)
{
if(A[i]>B[j])
A[k--]=A[i--];
else
A[k--]=B[j--];
}
if(j>=0)
{
while(j>=0){
A[k--]=B[j--];
}
}
}
腾讯2021
1.如何在数据库创建一个表
CREATE TABLE `class` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) DEFAULT NULL,
`gender` INT(3) DEFAULT NULL,
`subject` VARCHAR(30) DEFAULT NULL,
`score` INT(3) DEFAULT 0,
PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.创建后如何添加一个记录、删除一个记录
添加一个记录:insert stu('id','name') with value(1,'he');
删除一个记录:delete from stu where id=1;
3.编写C++中的两个类 一个只能在栈中分配空间 一个只能在堆中分配
可以通过重载new和delete运算符来控制内存的分配和释放
4.编写实现malloc()内存分配函数功能一样的代码
typedef struct _mem_block
{
size_t size; // 分配的内存块大小(不包括头部)
int free; // 是否空闲
struct _mem_block *next; // 下一个内存块
} mem_block;
mem_block *head = nullptr; // 内存块链表头指针
// 分配内存
void *malloc(size_t size)
{
mem_block *block, *last;
void *result; // 对齐到 8 字节
size = (size + 7) & ~7; // 查找可用内存块
last = nullptr;
for (block = head; block != nullptr; last = block, block = block->next)
{
if (block->free && block->size >= size)
{ // 找到合适的内存块
block->free = 0;
result = (void *)(block + 1);
if (block->size - size >= sizeof(mem_block))
{ // 剩余空间足够大,可以切割出新的内存块
mem_block *new_block = (mem_block *)((char *)block + sizeof(mem_block) + size);
new_block->size = block->size - size - sizeof(mem_block);
new_block->free = 1;
new_block->next = block->next;
block->next = new_block;
block->size = size;
}
if (last != nullptr && last->free)
{ // 合并前一个空闲内存块
last->size += sizeof(mem_block) + block->size;
last->next = block->next;
block = last;
}
return result;
}
} // 找不到可用内存块,分配新的内存块
block = (mem_block *)sbrk(sizeof(mem_block) + size);
block->size = size;
block->free = 0;
block->next = nullptr;
if (last != nullptr)
{
last->next = block;
}
else
{
head = block;
}
return (void *)(block + 1);
}
5.请编写能直接实现strstr()函数功能的代码
函数的功能是在一个字符串中查找另一个字符串,并返回第一次出现的位置
int SearchStr(char* s1, char* s2)
{
if (s2 == '\0') return 0;
int i = 0;
while (s1 != '\0')
{
int k = i;
int j = 0;
while (s1 != '\0' && s2 != '\0' && s1[i] == s2[j])
{
i++;
j++;
if (s2[j] = '\0')
return k;
}
i++;
}
return -1;
}
6.static关键字的作用
在C语言中,主要定义全局静态变量,定义局部静态变量,定义静态函数。
定义全局静态变量:在全局变量前面加上关键字static
特点:在全局数据区内分配内存;如果没有初始化,默认值为0;该变量从定义到本文本结束可见;
定义局部静态变量:在局部变量前面加上关键字 static
特点:在全局数据区内分配内存;如果不显示初始化,会被隐式初始化为0;它始终驻留在全局数据去,直到程序结束;其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束。
定义静态函数:函数前面加上static
特点:静态函数只能在本源文件使用;
在文件作用域中声明的inline 函数默认为 static
在C++语言中新增两种作用:定义静态数据成员,定义静态成员函数
静态成员数据特点:在程序的全局数据区分配内存;静态数据成员定义时要分配空间,所以不能在类声明里定义;
静态成员函数特点:静态成员函数与类相联系,不与类的对象相联系。静态成员函数不能访问非静态数据成员。原因很简单,非静态数据成员属于特定的类实例,主要用于对静态数据成员的操作。
静态成员函数和静态数据成员都没有 this 指针。
7.写string类的构造,析构,拷贝函数
class Mystring
{
public:
Mystring(){}
Mystring(const char* s)
{
str = new char[strlen(s) + 1];
strcpy_s(str,strlen(s)+1, s);
}
Mystring(const Mystring& s)
{
this->str = new char[strlen(s.str) + 1];
strcpy_s(this->str, strlen(s.str) + 1, s.str);
}
~Mystring()
{
if (str != nullptr)
{
delete str;
str = nullptr;
}
}
private:
char* str;
};