【面经】找实习两个月(面试题以及答案)

 题目转自:北邮人论坛https://bbs.byr.cn/#!article/Job/1888499



### 格灵深瞳 (平台开发)
一面:

1. 介绍你知道的传输层协议

答:TCP,UDP等
2. unix socket和socket了解吗

3. HTTP和HTTPS了解吗
4. 数据库触发器


### 携程 

1. 快速排序是稳定的还是非稳定的?时间复杂度呢?什么时候最坏复杂度?

答:不稳定,最坏:O(n^2),平均:O(nlogn);顺序或逆序


2. 贪心的计算思想是什么?

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。


3. TCP需要三次握手,两次行不行?为什么?
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误

client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送ack包。

但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。

### 小米 

一面:

1. 写个二叉树的中序遍历,递归几行写出来。然后说写个非递归的版本吧。

class Solution2 {  
public:  
    vector<int> inorderTraversal(TreeNode* root) {  
        vector<int> ret;  
        if(root==NULL)return ret;  
        TreeNode *curr=root;  
        stack<TreeNode*> st;  
        while(!st.empty()||curr!=NULL)  
        {  
            while(curr!=NULL)  
            {  
                st.push(curr);  
                curr=curr->left;  
            }  
            curr=st.top();  
            st.pop();  
            ret.push_back(curr->val);  
            curr=curr->right;  
        }  
        return ret;  
    }  
};

2. 求一个数组的最大子数组和,leetcode原题,先说了个O(n^2)的,然后努力回想dp的解法,写是写出来了;引申到二维就不会了,瞎说了个解法,想了想又说不可行,他也没继续问。

void MaxSum(int array[], unsigned int len)  
{  
    if(NULL == array || len <=0){  
        return;  
    }  
  
    int curSum = 0, maxSum = 0;  
    int i = 0;  
    for(i=0; i<len; i++){  
        curSum += array[i];     // 累加  
  
        if(curSum < 0){          // 当前和小于0,重置为0  
            curSum = 0;  
        }  
  
        if(curSum > maxSum){ // 当前和大于最大和,则重置最大和  
            maxSum = curSum;   
        }  
    }  
  
    if(maxSum == 0){            // 最大和依然为0,说明数组中所有元素都为负值  
        maxSum = array[0];  
        for(i=1; i<len; i++){  
            if(array[i] > maxSum){  
                maxSum = array[i];  
            }  
        }  
    }  
  
    printf("maxSum: %d", maxSum);  
} 

4. C++ vector的内存管理

STL实现者在对vector进行内存分配时,其实际分配的容量要比当前所需的空间多一些。就是说,vector容器预留了一些额外的存储区,用于存放新添加的元素,这样就不必为每个新元素重新分配整个容器的内存空间。


5. C++11的auto知道吗?使用时应该注意什么

用auto声明的变量必须初始化;
auto不能与其他类型组合连用;
函数和模板参数不能被声明为auto;
定义在堆上的变量,使用了auto的表达式必须被初始化;
以为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid;
定义在一个auto序列的变量必须始终推导成同一类型;


二面:

1. 给一个二叉树,用层次的方式输出它的结构(不是层序遍历,而是类似画图的方式利用位置显示结构)
2. 找到一棵二叉树中距离最远的两个节点(距离定义为边长),聊完思路刚要写他说这个写起来太麻烦了要不换一个吧

int HeightOfBinaryTree(BinaryTreeNode*pNode, int&nMaxDistance){  
    if (pNode == NULL)  
        return -1;   //空节点的高度为-1  
    //递归  
    int nHeightOfLeftTree = HeightOfBinaryTree(pNode->m_pLeft, nMaxDistance) + 1;   //左子树的的高度加1  
    int nHeightOfRightTree = HeightOfBinaryTree(pNode->m_pRight, nMaxDistance) + 1;   //右子树的高度加1  
    int nDistance = nHeightOfLeftTree + nHeightOfRightTree;    //距离等于左子树的高度加上右子树的高度+2  
    nMaxDistance = nMaxDistance > nDistance ? nMaxDistance : nDistance;            //得到距离的最大值  
    return nHeightOfLeftTree > nHeightOfRightTree ? nHeightOfLeftTree : nHeightOfRightTree;  
}

3. 换成背包问题,我说这个正好不会,他说哦那没关系我们再换一个
4. 堆排序,说你就写个维护堆的操作就行

void mheap(vector<int> &vec, int idx, int n){
	int lhs = 2*idx+1, rhs = 2 * idx + 2;
	int bigger = idx;
	if(lhs<=n && vec[lhs]>vec[bigger]) bigger = lhs;
	if(rhs<=n && vec[rhs]>vec[bigger]) bigger = rhs;
	if(bigger!=idx){
		std::swap(vec[idx], vec[bigger]);
		mheap(vec, bigger, n);
	}
}
void heapSort(vector<int> &vec){
	for(int i = vec.size()/2-1; i>=0; --i){
		mheap(vec, i, vec.size()-1);
	}

	for(int i = vec.size()-1; i>0;--i){
		std::swap(vec[0], vec[i]);

		mheap(vec, 0, i-1);
	}
}


### MSRA 一面挂 


1. 给两个有序链表,去求它们合并起来的有序链表。naive的我就写了个merge,写前面试官提示我不清楚的设定可以问他我也懵懂无知。写完高潮就来了,问你考虑链表有环的情况了吗?相交呢?我...
2. 乱序数组求第k大的数。先说了用排序和用小根堆的做法。又在提示下说了快排里partition的做法,代码写得漏洞百出。
感觉微软很重视测试用例,面试时数次问“那么你有没有设计测试用例呢?”,自己平时真没这个习惯。一面挂得不冤;特别后来参加微软的笔试被虐成狗,才意识到自己当初想着能进微软的念头是多么天真。

### 腾讯(内推) 

1. TIME_WAIT状态什么情况下会产生
2. 浏览器里敲一个URL,访问了一个网址,然后它整个的过程大概是什么样的(DNS、ARP、路由...)

1、浏览器的url请求
2、递归寻找DNS服务器
3、连接目标IP并建立TCP连接
4、向目标服务器发送http请求
5、web服务器接收请求后处理
6、web服务器返回相应的结果【无效、重定向、正确页面等】
7、浏览器接收返回的http内容


3. 一个IP包大概是多大呢,有限制没有(真的忘了,也没仔细想就蒙了一个说1500字节?后来想想当时如果能从IP Header 16位的size字段推论也该知道是65535)
4. 什么情况下会考虑UDP、什么情况下会考虑TCP

1.基于连接与无连接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。


5. 如果要进行可靠的传输,又想要用UDP,你觉得可行吗

UDP它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。
传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参照tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。
实现确认机制、重传机制、窗口确认机制。
如果你不利用linux协议栈以及上层socket机制,自己通过抓包和发包的方式去实现可靠性传输,那么必须实现如下功能:
发送:包的分片、包确认、包的重发
接收:包的调序、包的序号确认
目前有如下开源程序利用udp实现了可靠的数据传输。分别为RUDP、RTP、UDT。


6. HTTP请求在服务器应答、数据传完之后会怎么样一个操作呢?(蒙了,不知道服务器是主动close还是被动close了,当时TCP的状态转移也记不清楚;跟他扯长连接短连接,最终还是没答到他想要的点)

7. select和epoll的区别

(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。

(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。


8. hash表和二叉树的搜索时间差别
9. 操作系统内存管理
10. 如果申请一个动态内存它是放在堆里面还是栈里面


11. 虚拟内存和物理内存是怎样一个关系
12. 用C语言的malloc去申请内存,它这个时候会立即去分配物理内存吗?(什么鬼...您是想问C Runtime的内存管理么?)
13. 统计一个文件的行数(wc -l 但是当时没答上来——裸考的代价)
14. 一个二进制的程序跑起来的它各个段在内存中的分布是什么样的
15. 最后一个问题,static这个修饰符在C和C++里面有什么区别(区别?C/C++?真不知道啊,为什么这么问啊;后来才知道问的其实是静态局部变量、static method/variable这些)


### 阿里菜鸟(内推) 一面挂


1. 介绍一个你认为做得最好的C++项目。由哪些模块组成呢?有什么难点或者亮点吗?
2. 面向对象语言的三个特征是什么(封装、继承、多态;当时没记住这个,在那瞎聊思想)
3. 你了解多态吗?(面试官还是忍不住..)
4. C++对象模型中是如何实现动态的绑定的
5. 编译器会给空类会生成哪些函数

对于一个没有实例化的空类,编译器是不会给它生成任何函数的,当实例化一个空类后,编译器会根据需要生成相应的函数。这条理论同样适合非空类(只声明变量,而不声明函数)。(C++编译器不允许对象为零长度。试想一个长度为0的对象在内存中怎么存放?怎么获取它的地址?为了避免这种情况,C++强制给这种类插入一个缺省成员,长度为1。如果有自定义的变量,变量将取代这个缺省成员。)


6. 一个描述起来很复杂的C++的类的题,主要考察的点在内存泄露,感觉更应该现场问;聊了快10分钟

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值