2017秋招知识点小记(C/C++)

也许,现在是我为我大学前三年买单的时候了,虽有不甘,但是认了。我现在,只有一个选择,继续看书、刷题。趁着秋招才刚刚开始,我需要坚持不懈。每次笔试过后,我会在这里记录一些我的错题。

部分编程题记录--点击打开链接

多益:

1、字符串相加

string str{ "123" };
	str += 49;//此时49表示的ASCII码,str="1231"
	str += 4;//str="123\x4"



58:

1、字符串复制

        char a[2][10];
	char b[] = "sucee", c[] = "fail";
	//a[0] = b;//等式左边必须是可以被修改的左值!!!
	//a[1] = c;
	strcpy_s(a[0], b);
	strcpy_s(a[1], c);
	printf("%s\n", a[0]);
	printf("%s\n", a[1]);



58一面:

1、

#include <iostream>
using namespace std;
typedef void(*Fprint)();
void fun()
{
	cout << "fun()" << endl;
}
//传递函数指针(引用传递)的两种方式
void doSomething(Fprint &p)//void(*&p)()
{
	cout << "start" <<endl;
	p();
}
int main()
{
	Fprint f = fun;
	doSomething(f);
	system("pause");
	return 0;
}

2、删除字符串s中的字符c:

#include <iostream>
#include <string>
using namespace std;
void fun(string &str)
{
	string::size_type len = str.length(), count = 0,i = 0;
	while(i+count<len)
	{
		if (str[i + count] == 'c')
		{
			for (string::size_type j = i+count+ 1;j < len&&str[j] != 'c';++j,++i)
			{
				str[i] = str[j];
			}
			++count;
		}
		else
		{
			++i;
		}
	}
	str[i] = '\0';
}
int main()
{
	string s{ "1111111111111111c333333c444444c555555555" };
	cout << s << endl;//1111111111111111c333333c444444c555555555
	fun(s);
	cout << s << endl;//1111111111111111333333444444555555555 55
	printf_s("%s\n",s.c_str());//1111111111111111333333444444555555555
	system("pause");
	return 0;
}

当时跟我说给的是一个string,那我还不如一个字符一个字符的加起来来的干脆。亏我还在思考像c语言字符串那样处理。从上面的输出结果,可以看出字符串string的对象并不由于中间出现'\0'而停止输出。上述代码思路是c语言风格的移动,没有临时变量的写法。记住,是从前向后移动(与剑指上的题目区别很大)。


3、两分钟写快排,未能快速写出,需要加强。

写出项目核心代码。


4、TCP为什么是三次握手,不是两次。

三次的原因阐述:保证post、get机制完好。信道不可靠, 数据传输要可靠。参考点击打开链接点击打开链接。有两次的举例。


5、TCP主要用于哪方面,为什么有了TCP(传输控制协议)还要有UDP(用户数据报协议)。

TCP:可靠的数据流传输方法。比如传输信令,数据量较小的场合等。

UDP:无排序的,不可靠的传输服务。适用于对传输速率要求较高、通信量比较大,而对于可靠和安全的要求较低的场合。多媒体通信。--RPC、RTP。


6、SQL:有一张表,下面是定义

create table sg
(id char(9),/*以逗号结尾*/
course char(9) ,
score smallint,
 primary key(id,course)
);
A、求取总分前十名

select id,sum(score) as total
from sg
group by id
order by total desc
limit 3;
B、求取单科第一名

select id,A.course,A.score
from sg as A,
(select course,max(score) as highest_score
from sg
group by course )as B
where A.course=B.course
and A.score=B.highest_score;



京东:

1、算法五大特征:有限性、确定性、输入、输出、可行性。最基本的是有限性、确定性和可行性。(没有中间处理!)


2、snmp报文:首部、数据、版本。(并不含有安全类型啥的)


3、volatile用法:表示可变的,用来在进程间传递参数,特殊功能寄存器。


A中断服务程序中修改的供其它程序检测的变量需要加volatile;
B多任务环境下各任务间共享的标志应该加volatile;
C存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。


4、菱形继承:定义:两个子类继承同一个父类,而又有子类同时继承这两个子类。


5、分支限界法与回溯法的相同点和不同点
相同点:二者都是一种在问题的解空间树T上搜索问题解的算法。
不同点:
A在一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。
B回溯法与分支-限界法对解空间的搜索方式不同,回溯法通常采用尝试优先搜索,而分支限界法则通常采用广度优先搜索。
C对节点存储的常用数据结构以及节点存储特性也各不相同,除由搜索方式决定的不同的存储结构外,分支限界法通常需要存储一些额外的信息以利于进一步地展开搜索。

参考自点击打开链接


6、计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的做法,而且当O(k)>O(n*log(n))的时候其效率反而不如基于比较的排序(基于比较的排序的时间复杂度在理论上的下限是O(n*log(n)), 如归并排序,堆排序)。


7、基于比较的排序:一般的排序都是基于比较的。非基于比较的有计数排序、桶排序、基数排序。



腾讯:

1、二叉树对称序列:即中序遍历序列。


2、DNS协议运行在UDP协议之上,使用端口号53。在传输层TCP提供端到端可靠的服务,在UDP端提供尽力交付的服务。其控制端口作用于UDP端口53。


3、学会的一种编程风格:

/*风格:
*   if(nullptr= =node)
*      break;
*/

我们可以防止出现node=nullptr的问题。


4、

#include <iostream>
using namespace std;
int main(void)
{
	const int n = 10;
	const int m =2;
	int a[n];
	for (int i = 0;i < n;++i)
	{
		a[i] = (0 == i % 2) ? (i + 2) : (i + 0);
	}
	int(*b)[n / m] = (int (*)[n / m])a;//将a数组划分为m部分
	for (int j = 0;j < m;++j)
	{
		for (int i = 0;i < n / m;++i)
		{
			cout << b[j][i];
		}
	}
	cout << endl << "\t\t\t\t@zem" << endl;
	system("pause");
	return 0;
}


5、就绪队列有10个线程,cpu执行一个大概花费200ms,切换线程约花费10ms,求出系统开销约占0.045。


6、x64平台:

#include <iostream>
using namespace std;
class St {
public:
	int a;//8
	short *p;//8
	char b[32];//32
};//48
int main(void)
{
	St st[10];
	char *pointer = st[2].b + 32;
	char *head = (char *)st;
	cout << pointer - head << endl;//48*3=144
	cout << endl << "\t\t\t\t@zem" << endl;
	system("pause");
	return 0;
}

x86运行:


7、

#include <iostream>
using namespace std;
int main(void)
{
	char *p[] = { "Twww","Cwww","Rwww" };
	char **pp[] = { p + 2,p + 1,p };
	char ***ppp = pp;
	cout << **++ppp << endl;
	cout << *++*++ppp << endl;//此时的ppp已经指向pp[1]了,然后++取出p,再++取出Cwww。
	cout << endl << "\t\t\t\t@zem" << endl;
	system("pause");
	return 0;
}


腾讯一面:

1、关键字容器与文本:判断给定文本是否包含关键字。

很详细的讲解:点击打开链接。构建关键字的树,状态机,可以合并多个关键字于一棵树,然后扫描关键字。


2、对于给定内存分配、释放。阐述相关数据结构、申请固定大小内存块getBlock(int sz=100)和释放free(char *p)的实现。


3、UNIX进程间通信:

A.管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信; 有名管道克服了管道没有名字的限制,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。
B.信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身。
C.消息队列:消息队列是消息的链接表,包括Posix消息队列systemV消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
D.共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
E.信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。
F.套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。


4、生产者和消费者问题。


5、UDP实现TCP需要添加哪些功能。

重传策略、重复检测、流控、连接建立、连接结束、故障恢复。(个人认为应该添加所有传输层保证可靠传输的功能,UDP使用的底层协议传送报文--数据报传送机制)


6、如何实现流量控制。

TCP采用滑动窗口机制(提供了可靠传输服务)解决了端到端的流量控制,但并未解决整个网络的拥塞控制。


7、流量控制和拥塞控制的区别。

拥塞控制:慢启动算法,逐步扩大发送窗口,以防止网络拥塞;

流量控制:放置数据发送过多,导致接收机高负荷,过少,导致利用率过低,于是两边进行窗口大小通信告知。



8、数据库索引是怎么实现的。对B+树的了解。为什么不用别的算法。

常见索引:顺序文件上的索引、B+树索引、散列索引、位图索引等

顺序文件上的索引是针对按指定属性值升序或降序存储的关系,在该属性上建立一个顺序索引文件,索引文件由属性值和相应的元组指针组成;(估计是查找用二分)

B+树索引是将索引属性组织成B+树形式,B+树的叶节点为属性值和相应的元组指针;

散列索引是建立若干个桶,将索引属性按照其散列函数值映射到相应桶中,桶中存放索引属性值和相应的元组指针;(查找速度快)

位图索引是用位向量记录索引属性中可能出现的值,每个位向量对应一个可能的值。

位图索引参考-点击打开链接点击打开链接

后三种的简介-点击打开链接

B系列树:BST、B-树、B+树、B*树点击打开链接

B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于走右结点;

B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点;所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;

B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;

B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率从1/2提高到2/3;


9、map的实现机制。

红黑树。


10、红黑树和平衡二叉树的区别。

红黑树和AVL树的区别在于它使用颜色来标识结点的高度,它所追求的是局部平衡而不是AVL树中的非常严格的平衡。都是自动调整平衡的。

点击打开链接



11、web服务器需要实现哪些功能。


WPS:

1、

#include <iostream>
using namespace std;
class A {
public:
	A():a(2){}
	int getA() { return a; }
	void fun() const
	{
		cout << "a" << endl;
	}
	void fun()
	{
		cout << "b" << endl;
	}
private:
	int a = 1;
};
int main() {
	//test unsigned==unsigned int
	unsigned i = 0;
	cout << i << endl;
	//test printf()
	//printf("11" + "22");//编译不通过
	//test fun()
	A obja;
	obja.fun();//b,优先匹配普通函数
	const A objb;
	objb.fun();//a,只能调用常量函数
	//test a
	cout << obja.getA() << endl;
	//如果有初始化列表则初始化为该值,如果没有则初始化为类类初始值
	system("pause");
	return 0;
}


WPS一面:

1、
class A {
private:
	int _a;
public:
	int getA() { return _a; }
	void fun() 
	{
		cout << "fun()" << endl;
		getM();//成员函数可以调用静态成员函数
	}
	static int m;
	static int getM() 
	{
		//cout << getA() << endl;//错误
		//fun();//错误
		//只能访问静态成员
		return m; 
	}
};

2、 set集合容器实现了红黑树(Red-Black Tree)的平衡二叉检索树的的数据结构,在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个子树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,还得确保根节点的左子树的高度与有字数的高度相等,这样,二叉树的高度最小,从而检索速度最快。要注意的是,它不会重复插入相同键值的元素,而采取忽略处理。平衡二叉检索树的检索使用中序遍历算法,检索效率高于vector、deque、和list的容器。另外,采用中序遍历算法可将键值由小到大遍历出来,所以,可以理解为平衡二叉检索树在插入元素时,就会自动将元素按键值从小到大的顺序排列。构造set集合的主要目的是为了快速检索。


3、面试问了很多编译器行为问题,应该冷静分析,根据平时写的代码进行判断,而不是畏惧。


CVTE(一面):

1、单列模式:参考的别人的C++代码

#include <iostream>
using namespace std;
class Singelton
{
private:
	Singelton() {}
	static Singelton* singel;
public:
	static Singelton* GetInstance()
	{
		if (singel == NULL)
		{
			singel = new Singelton();
		}
		return singel;
	}
};
Singelton* Singelton::singel = NULL;//注意静态变量类外初始化
//客户端:
int main()
{
	Singelton* s1 = Singelton::GetInstance();
	Singelton* s2 = Singelton::GetInstance();
	if (s1 == s2)
		cout << "ok" << endl;
	else
		cout << "no" << endl;
	system("pause");
	return 0;
}

2、STL六大组件

Container(容器) 各种基本数据结构
Adapter(适配器) 可改变containers、Iterators或Function object接口的一种组件
Algorithm(算法) 各种基本算法如sort、search…等
Iterator(迭代器) 连接containers和algorithms
Function object(函数对象)
Allocator(分配器)

参考自:点击打开链接


3、

#include <iostream>
#include <vector>
using namespace std;
int main()
{
	vector<int> ia;
	ia.reserve(5);//仅仅预留空间,尽在要求容量大于本有容量时候起作用
	cout << ia.size() << "\t" << ia.capacity() << endl;
	ia.resize(2);//相当于含有2个元素,但是此时,并不修改容量
	cout << ia.size() << "\t" << ia.capacity() << endl;
	system("pause");
	return 0;
}


4、vector和list区别

vector:随机访问、数量变化小、对象简单(否则扩容开销比较大);

list:插入删除、数量变化大、对象较为复杂。


5、vector从8K扩容到了128K,如果前8K常用,后面的不常用,此时vector是怎么做的(面试官的意思是系统操作,并非人为)。

这里,我确实不知道,还在寻找答案。对于人为干预:点击打开链接

容量变大后,是变不回来的,我们在这里可以使用shrink_to_fit(),但是系统可以选择忽视。

#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
	vector <string> v;
	for (int i = 0; i<1000000; i++)
		v.push_back("abcdefghijklmn");
	v.clear();
	cout << "Vector 的 容量为" << v.capacity() << endl;
	vector<string> (v).swap(v);//这种写法还真是第一次见
	cout << "Vector 的 容量为" << v.capacity() << endl;
	// 此时容量为0
	system("pause");
	return 0;
}

6、指针和引用的区别:一个是别名,一个是指向某对象的量(本身是对象)。


7、static_cast和dynamic_cast区别作用:

static_cast:一般只要不包含底层const都可以转换,可以找回存在的void *指针。

dynamic_cast:运行时类型识别。将基类的指针或引用安全的转换为派生类的指针或引用。dynamic_cast<type*>(e):type是类,通常有虚函数。什么情况下转换成功:type与e同类、type是e的子类、type是e的公有基类。


8、C11特性举例:auto自动类型判断。点击打开链接


9、函数指针和lambda区别:传统的函数指针是一个指针, lambda是一个对象。


10、哈希表冲突处理:

开放定址法:线性探测再散列(容易产生二次聚集,即处理同义词冲突又导致非同义词冲突。几次出现冲突。但是他一定可以找到不冲突的地址)、二次探测再散列(k^2,k正负跳跃,属于跳跃式探测)、伪随机数探测再散列(确定一个伪随机数序列);

再哈希法:同时构造多个不同的哈希函数,不易聚集,但是开销变大。

链地址法:将同义词构成单链表,适合经常要插入删除情况。(同义词指哈希函数计算结果一样的词);

建立公共溢出区:哈希表分为基本表和溢出表。


11、如何消抖:硬件消抖和软件消抖(检测后延时再检测)。


烽火:

1、IPV6里面没有广播,只有:单播、多播(组播)、任播(群集:选择最近一台)。


2、不能重载的运算符如:
:: .*(类成员指针) . ?:(三目条件)
重载运算符定义更佳准则:
A 赋值(=)、下标([])、调用(())、成员访问箭头(->)运算符必须是成员
B 复合赋值运算符一般来说是成员;
C 改变对象状态的运算符或与给定类型密切相关的运算符,如递增递减解引用运算符等常为成员;
D 具有对称性的运算符可能转换任意一端的运算符,例如算数、相等性、关系和位运算等常为普通非成员函数。


3、编程题难。还需要好好锻炼。


4、

#include <iostream>
using namespace std;
template<class T>
void fun()
{
	cout << "templat fun()" << endl;
}
void fun()
{
	cout << "fun()" << endl;
}
int main()
{
	fun<int>();//实例化函数模板及调用
	fun();
	system("pause");
	return 0;
}


烽火一面:

1、C和C++的区别:

C是面向过程的,C++面向对象。C++三个主要特点:封装、继承、多态。


2、多态:

重载多态,强制多态,包含多态,参数多态。
普通函数和类的成员函数的重载属于重载多态,还有运算符重载。
强制多态包括类型强制转换等。
包含多态主要通过虚函数来实现。(动态多态,其余为静态多态)
参数多态:函数模板、类模板。


3、删除vector<int>中值为3的元素:

思路一:直接用一个新的vector装入不是3的元素;

思路二:排序,找到首尾迭代全3的序列,删除(erase)。

在面试的时候应该多与面试官沟通,得到更多的信息,选择合适的思路。


烽火终面:

1、RAII:这个问题在Effective C++有详细介绍,暂不写。

2、虚函数底层实现机制。


携程:

1、

#include <iostream>
using namespace std;
int main()
{
	int a = -1;
	unsigned b = 0;
	int c = (a + b > 0 ? 1 : -1);
	cout << c << endl;//1
	system("pause");
	return 0;
}
2、对于http状态:

1**表示确定、2**表示、3**重定向、4**请求错误、5**服务器错误。


携程面试:

1、volatile

2、如何从一堆图片中删除重复图片:MD5或Hash值。

3、八皇后问题。可以全排列再check,我当时回溯写的。

4、聚集索引和非聚集索引: 点击打开链接
聚集索引:全表只有一个,确定表的物理形式。
非聚集索引:表上的目录。

5、面试有一定难度。

爱奇艺:

1、mysql_fetch_object() 和 mysql_fetch_array() 类似,只有一点区别 - 返回一个对象而不是数组。间接地也意味着只能通过字段名来访问数组,而不是偏移量(数字是合法的属性名)。速度上,本函数和 mysql_fetch_array() 一样,也几乎和 mysql_fetch_row() 一样快(差别很不明显)。(竟然连这都考--PHP)


2、RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。非对称密码算法。你只要想:既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。


七牛模拟:

1、不能建立索引的数据类型是哪一个:int、date、blob、varchar。目测是blob(二进制大对象)。


2、git命令,合并远程分支于本地。点击打开链接

git pull:从远程获取最新版本并merge到本地。


3、请求式分页存储管理---页面置换算法:最佳页面淘汰(理论上的)、先进先出淘汰、最近最不常用淘汰、最近最久未用淘汰。


4、http报文格式::起始行(start line)、首部(header)、主体(body)。 点击打开链接

5、kill普通用户是可以操作的,但是ldconfig管理动态链接的,还真没有用过,排除到这里了,估计要root权限。


完美:

1、BSR-逆向位扫描指令(从高位开始),BSF - 正向位扫描(从低位开始)

1234H 的二进制为 0001 0010 0011 0100
BSF找值为1的最低bit,
找到0001 0010 0011 0(1)00,是(从0数)第2位,cx值2
BSR找值为1的最高bit
找到000(1) 0010 0011 0100, 是(从0数)第12位,cx值12


2、关于左值和右值:左值是类型、右值是取其值。概念要清楚,会区分。


360:

1、@@fetch_status是MicroSoft SQL SERVER的一个全局变量
其值有以下三种,分别表示三种不同含义:【返回类型integer】
0 FETCH 语句成功
-1 FETCH 语句失败或此行不在结果集中
-2 被提取的行不存在

@@fetch_status值的改变是通过fetch next from实现的
“FETCH NEXT FROM Cursor”

2、
#include <iostream>
using namespace std;
void print(char(*p)[5])
{
	for (int i = 0;i < 5;++i)
	{
		for (int j = 0;j < 5;++j)
		{//等效写法
			cout << p[i][j] << "\t"<<*((p[i])+j)<<"\t"<<*(*(p+i)+j)<<endl;
		}
	}
}
int main()
{
	char s[5][5] = { "1234","6789","asdf","ghjk","zxcb" };
	print(s);
	system("pause");
	return 0;
}

3、
#include <iostream>
using namespace std;

int main()
{
	int a[2][3] = { 1,2,3,4,5,6 };
	cout << a[0] << "\t" << *(a + 1) << "\t" << *a[1] + 1 << endl;
	//010FF9B8(地址,表示指向第一个数组的指针)       010FF9C4        5
	system("pause");
	return 0;
}


4、
#include <iostream>
using namespace std;
class A {
public:
	A(int _a):a(_a){}
	int getA() { return a; }
private:
	int a;
};
class B :private A {
public:
	B(int _a,int _b):A(_a),b(_b){}
	int getA()
	{
		//write code here
		return A::getA();
		//a不可访问,因为在private中,虽然是私有继承,但是public部分成为了自己的private部分,可以访问。
	}
private:
	int b;
};
int main()
{
	B b(1, 2);
	cout << b.getA() << endl;//1
	system("pause");
	return 0;
}


好未来:

1、构造函数不能是const的。


百度外卖一面:

1、平面上有2N个点,如何确定一个圆,使得N个点在圆内,N个点在圆外。(待解答)

2、进程间通信:以后还是就说UNIX的那几种吧,至少还懂一点。

3、临界资源:一次只允许一个进程使用的资源。
临界区:必须互斥执行的程序段。

4、TCP/IP模型介绍或OSI模型介绍。
TCP/IP模型:
物理层:在介质上传输位,提供机械 的和电子的规范;
(位到信号的转换、位率控制(数据率)、位同步、复用、交换)
数据链路层:将位组成帧,提供结点到结点的传递;
(分组(下一跳hop)、地址(MAC)、差错控制、流控(发帧速率不超过收帧速率)、介质访问控制MAC)
网络层:将分组从源地址传递到目的地址;提供网络互连;
(网络互连、地址、路由、分组、分段(拆分分段))
传输层:提供可靠的端到端的报文传递和差错恢复;
(分组、连接控制、寻址(对端应用端口的确定)、提供可靠性)
应用层:允许访问网络资源。
(提供用户接口和服务支持)

会话层:连接管理;
表示层:数据格式转换。


5、引用和指针区别: 点击打开链接
A、指针是一个实体,而引用仅是个别名;
B 、引用使用时无需解引用(*),指针需要解引用;
C、引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终” 
D 、引用没有 const,指针有 const,const 的指针不可变;
E 、引用不能为空,指针可以为空;
F、“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;
typeid(T) == typeid(T&) 恒为真,sizeof(T) == sizeof(T&) 恒为真,但是当引用作为类成员名称时,其占用空间与指针相同4个字节(没找到标准的规定)。
G、指针和引用的自增(++)运算意义不一样;


6、多态实现,虚函数底层机制
烽火一面指出多态种类,而对应的便是实现。
底层实现机制:每个(包含虚函数)类都有自己的虚函数指针VPTR来指向对应的VTBL,接着调用所指虚表中的函数。 点击打开链接

7、
#pragma pack(1)//1、2、4、8显然最高要小于电脑位数/8
#include <iostream>
using namespace std;
struct A {
	int a;
	float b;
	short c;
	char d;
};
int main()
{
	cout << sizeof(A) << endl;//11
	cout << endl;
	system("pause");
	return 0;
}



巨人网络:

1、空指针的成员函数调用:
#include <iostream>
using namespace std;
class A
{
public:
	void fun() { cout << "fun()" << endl; }
	void getM() { cout << m << endl; }
private:
	int m;
};
int main()
{
	A *pa = 0;//与nullptr等效
	pa->fun();//fun()
	pa->getM();//中断
	system("pause");
	return 0;
}


2、计算当前日期(如20160606是星期几) 点击打开链接
#include <iostream>
#include <string>
using namespace std;
int tran(string str)
{
	int i = 0, len=str.length();
	int y = 0;
	if (len != 8) return 0;
	while (i < 4)
	{
		y = 10 * y + str[i++] - '0';
	}
	int m = 0;
	while (i < 6)
	{
		m =10 * m + str[i++] - '0';
	}
	int d = 0;
	while (i < 8)
	{
		d = 10 * d + str[i++] - '0';
	}
	if (m == 1) m = 13;
	if (m == 2) m = 14;
	return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7+1;
}
int main()
{
	string str;
	while (cin >> str)
	{
		switch (tran(str))
		{
		case 0:break;
		case 1:cout << "星期一";break;
		case 2:cout << "星期二";break;
		case 3:cout << "星期三";break;
		case 4:cout << "星期四";break;
		case 5:cout << "星期五";break;
		case 6:cout << "星期六";break;
		case 7:cout << "星期七";break;
		default:break;
		}
	}
	
	cout << endl;
	system("pause");
	return 0;
}



有道:

1、2016!有多少个尾0。(10:1;101:0)
leetcode原题,但是需要具体分析几个数。
class Solution {
public:
    int trailingZeroes(int n) {
        while(n%5)
        {
            --n;
        }
        if(n<25)
        {
            return n/5;
        }
        return n/5+trailingZeroes(n/5);
    }
};



2、编程题真难。


滴滴:

1、冯诺依曼:I/O、运算、存储、控制


小米:

1、SCAN算法在磁头当前移动方向上选择与当前磁头所在磁道距离最近的请求作为下一次服务的对象。
磁盘调度算法: 点击打开链接
先来先服务算法(FCFS),
最短寻道时间优先算法(SSTF),
扫描算法(SCAN),
循环扫描算法(CSCAN)

畅游:

1、
#include <iostream>
using namespace std;
class A {
public:
	A() { cout << "A()" << endl; }
	~A() { cout << "~A()" << endl; }
};
int main()
{
	cout << "C" << endl;
	A *p1 = (A*)malloc(sizeof(A));
	free(p1);
	cout << "CPP" << endl;
	A *p2 = new A;
	delete p2;
	system("pause");
	return 0;
}




2、二分法插入排序是在插入第i个元素时,对前面的0~i-1元素 进行折半,先跟他们中间的那个元素比,如果小,则对前半再进行折半,否则对后半进行折半,直到left>right,然后再把第i个元素前1位与目标位置之间的所有元素后移,再把第i个元素放在目标位置上。

3、计数排序(基于非比较):假设数序列中小于元素a的个数为n,则直接把a放到第n+1个位置上。当存在几个相同的元素时要做适当的调整,因为不能把所有的元素放到同一个位置上。计数排序假设输入的元素都是0到k之间的整数。 点击打开链接



美团、点评:

1、最大堆插入:25、13、10、12、9插入18,比较次数:2(目测)。

2、数组中的数除一个数外都出现三次,找出来。通过比特位计数找出比较好理解。


TCL:


1、
#include <iostream>
using namespace std;
#define DIV(x) x/x
int fun(volatile int *ptr)//可能返回不同的值,直接从原始地址取出
{
	return (*ptr)*(*ptr);
}
int main()
{
	int a = 4;
	int b = DIV(a) / DIV(a);//0
	int $123 = 0123;//八进制
	cout << $123 << endl;
//	int _int&int = 0;//错误标识符
	cout << fun(&a) << endl;
	system("pause");
	return 0;
}

       感觉还是不是十分理解,暂时只能理解为volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,而不会利用cache当中的原有数值,以适应它的未知何时会发生的变化,系统对这种变量的处理不会做优化——显然也是因为它的数值随时都可能变化的情况。 点击打开链接
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值