【华为正式岗】数据存储1面

前一个是机器视觉组,另外一个组(数据存储)也想面一下,就重新从1面开始了

1.项目的一些实现:

例如:服务器架构、如何实现多个玩家数据同步、很多玩家同时登陆会怎么样
回答了一些游戏服务器架构的知识,合服原理以及玩家排队机制

2.session和token的区别,token是啥

Session和Token机制原理上差不多,都是用户身份验证的一种识别手段,它们都有过期时间的限制,但两者又有一些不同的地方。

1、Session是存放在服务器端的,可以保存在:内存、数据库、NoSQL中。它采用空间换时间的策略来进行身份识别,若Session没有持久化落地存储,一旦服务器重启,Session数据会丢失。

2、Token是放在客户端存储的,采用了时间换空间策略,它也是无状态的,所以在分布式环境中应用广泛。

3.设计模式

1.知道哪些策略模式:

单例模式、抽象工厂方法,策略模式、桥接器模式、装饰器模式、代理模式

2.单例模式如何实现:

说构造函数使用私有,然后每次创建时,都去检测一下,如果有这个私有变量,就返回私有变量,如果没有,就不返回这个私有变量
其实正确答案应该是静态指针
在这里插入图片描述

3.策略模式和装饰器模式区别

策略模式更趋向于多选1
装饰器模式应该是执行某个函数前,要先去执行某个前序函数……

4.多线程的单例会怎么样?

上面这个如果写成静态类就可以了。

4.c++的nullptr和NULL有什么区别?

NULL有二义性,可以是空指针,也可以是int类型的0,
void func()
和 int func()
重载时,NULL会调用int func()

5.你知道多路复用IO吗?

select和epoll

1.select和epoll的区别
2.epoll的底层实现

6.虚函数有什么作用?

可以用基类指针访问基类,实现动态多态,

1.虚指针的实现:

通过一个虚函数表
在这里插入图片描述

2.什么时候使用虚函数

我没有答出来。
答案参考
什么要用父类指针指向子类对象呢?这根本不需要声明为虚函数啊,直接定义一个子类对象,或是用子类指针指向子类对象,再来调用Show函数,即使不用声明为虚函数,也能调用我们派生后重写的Show函数啊。

虽然这样说,但是实际开发过程中不是这样的,当我们使用一些类库、框架的时候,这些类库、框架是事先就写好的。我们在使用的时候不能直接修改类库的源码,我们只能派生类库中的类来覆盖一些成员函数以实现我们的功能,但这些成员函数有的是由
框架调用的。这种情况下,用虚函数是很好的办法。

在面向过程的C语言中,在需要框架、类库回调我们自定义的函数的时候,往往是传入一个函数指针,让框架回调。

在面向对象的C++中,为了实现同样的目的,框架往往准备好了什么也不干的虚函数,由我们派生后重写这个虚函数,来实现我们的自定义功能。随后,框会调用这个虚函数。效果如同面向过程语言中的回调。

7.c++的函数调用里面,哪些内存是怎么保存的

1.栈里面的,例如局部变量等等
2.堆里面的,例如新分配的动态分配的内存
3.一些静态变量,会一直全局存在

在这里插入图片描述

8.你知道哪些STL

vector,set,map,string,list,stack,queue

9.STL里面String是深拷贝还是浅拷贝?

#include <string>//包含string
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
    string ss, s;
    ss = "1234567";
    s = ss;//用=号直接把ss的值1234567赋给s
    ss = "1";
    cout << s << endl;
    return 0;
}

请问s输出什么?这里s输出的还是1234567
是深拷贝

如何实现字符串的深拷贝

1.分配空间
2.给字符串赋值
3.返回新串
在这里插入图片描述

10.vector的迭代器

如果在vector迭代过程中,进行了删除操作,会怎么样
迭代器会失效,但是可以获取新的有效的下一个迭代器
在这里插入图片描述

11.你用过thread吗?c++里面thread的作用等等

没有 = =

12.函数调用压栈过程

函数怎么知道什么时候返回呢?返回地址是啥
在这里插入图片描述

13.多线程操作一个链表的话会出现什么问题

会出现异常结果,操作时需要加锁

如果是2个线程操作2个链表呢?

如果是 各自线程操作各自的链表不会有问题,不然需要同步

14.一个算法题

我没有做出来,贴一下后来的实现。。。。。

一个升序单链表(值不一定连续),头指针为head, 将其中值在[a,b]之间的数据反转,包含a和b,返回反转后的链表。
eg:
[2 3]
1 2 3 4 6
1 4 3 2 6

若有更清晰思路请不吝赐教。

#include <iostream>
#include<vector>
using namespace std;
struct LinkNode {
    LinkNode* pNext;
    int val;
};

LinkNode* GetMaxAPre(LinkNode* pHead, int a) {
	LinkNode* pre = pHead;
	while (pHead && pHead->pNext)
	{
		if (pHead->pNext->val<a)
		{
			pre = pHead;
		}
		else {
			return pre;
		}
		pHead = pHead->pNext;
		pre = pre->pNext;
	}
	return pre;
}

LinkNode* GetMinBPre(LinkNode* pHead, int b) {
	LinkNode* pre = pHead;
	while (pHead && pHead->pNext)
	{
		if (pHead->pNext->val <= b)
		{
			pre = pHead;
		}
		else {
			return pre;
		}
		pHead = pHead->pNext;
		pre = pre->pNext;
	}
	return pre;
}

LinkNode* ReverseList(LinkNode* pHead,LinkNode* tail) {
	LinkNode* pReverseHead = nullptr; //当前需要连接的头
	LinkNode* pNode = pHead;
	LinkNode* pPrev = nullptr;
	while (pNode != tail)
	{
		LinkNode* pNext = pNode->pNext;
		if (pNext == tail)
		{
			// 是空,到了最后一个节点了
			pReverseHead = pNode;
		}
		pNode->pNext = pPrev;
		pPrev = pNode;
		pNode = pNext;
	}
	return pReverseHead;
}


LinkNode* ReverseListA2B(LinkNode* pHead, int a, int b) {
	LinkNode* preA = GetMaxAPre(pHead, a);
	LinkNode* newTail = preA->pNext;
	LinkNode* B = GetMinBPre(preA, b);
	LinkNode* BNext;
	if (B==nullptr)
	{
		BNext = nullptr;
	}
	else {
		BNext = B->pNext;
	}
	if (preA==nullptr )
	{
		return nullptr;
	}
	LinkNode* newhead;
	if (pHead->val>=a)
	{
		newhead = ReverseList(pHead, BNext);
		preA->pNext = BNext;
		return newhead;
	}
	else {
		newhead = ReverseList(preA->pNext, BNext);
	}
	preA->pNext = newhead;
	newTail->pNext = BNext;
	return pHead;
}


void testcase(const string caseName, vector<int> data,int a,int b) {
	cout << caseName<<" : \n";
	LinkNode* pHead = new LinkNode();
	pHead->pNext = nullptr;
	pHead->val = data[0];
	LinkNode* p = pHead;
	for (int i = 1; i < data.size(); i++)
	{
		LinkNode* newNode = new LinkNode();
		newNode->pNext = nullptr;
		newNode->val = data[i];
		p->pNext = newNode;
		p = p->pNext;
	}
	p = pHead;
	while (p != nullptr)
	{
		if (p && p->pNext != nullptr)
		{
			cout << p->val << " ->";
		}
		else {
			cout << p->val << endl;
		}
		p = p->pNext;
	}
	p = ReverseListA2B(pHead, a, b);
	while (p != nullptr)
	{
		if (p && p->pNext != nullptr)
		{
			cout << p->val << " ->";
		}
		else {
			cout << p->val << endl;
		}
		p = p->pNext;;
	}
	cout << endl;
}

int main()
{
	vector<int> data{ 0,1,3,4,5,7,9,10 };
	testcase("case1", data,1,5); //0 ->5 ->4 ->3 ->1 ->7 ->9 ->10
	testcase("case2", data,0,9); //9 ->7 ->5 ->4 ->3 ->1 ->0 ->10
	testcase("case3", data,1,10);// 0 ->10 ->9 ->7 ->5 ->4 ->3 ->1
	testcase("case4", data,0,10);// 10 ->9 ->7 ->5 ->4 ->3 ->1 ->0
	testcase("case5", data, -5, 20);//10 ->9 ->7 ->5 ->4 ->3 ->1 ->0
	testcase("case6", data, 1, 20);//0 ->10 ->9 ->7 ->5 ->4 ->3 ->1
	testcase("case7", data, 6, 9);//0 ->1 ->3 ->4 ->5 ->9 ->7 ->10
	testcase("case8", data, 5, 8);//0 ->1 ->3 ->4 ->7 ->5 ->9 ->10
	
    return 0;
}



用例:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值