在网上看到这篇文章,转载过来和阿友们分享一下。
第一面,面技术,问了我的项目,STL,红黑树,练表反转+笔试错题重做
我后面面的很不好,很多都不会,分数较低
第二面,面技术,给我出了个算法题,星际在地图上点一块,如何找到该块上的所有物体
有可能会出逻辑推理题或者数学题
第三面,综合面,链表排序,easy
第四面,HR面试,胡扯了。有没有Offer听天由命了,嘻嘻,给后来的人一个参考
软件开发职位笔试试题
一、单项选择
1、向单链表插入节点;
2、排序的稳定性比较;
3、带头节点的单链表的判空条件;
4、二叉树的节点总数的计算;
5、递归向非递归的转化使用什么?队列,还是栈;
6、中断响应时间的定义;
7、面向对象程序设计语言不同于其他语言的主要特点;
二、填空题
1、正弦函数用泰勒展开式来计算:
下面的流程图描述了利用上述展开式计算并打印sinx的近似值的过程,其中e(>0)表示误差要求,小于该误差就可以结束计算,打印结果,请填写流程图中的空格部分。
图略
2、双循环链表的排序问题;
应该比较简单,相信你们能够搞定!
三、附加题
“背包问题”的基本描述是:有一个背包,能盛放的物品总重量为S,设有N个物件,其重量分别为W1,W2, ……… , Wn , 希望从N件物品中选择若干物品,所选择的物品的重量之和恰能放入该背包,即所选物品的重量之和等于S。递归和非递归解法都可以求得“背包问题”的一组解,试写出“背包问题”的非递归解法。
----
1, 使用Linux epoll模型,水平触发模式(Level-Triggered);当socket可写时,会不停的触发socket可写的事件,如何处理?
2, 从socket读数据时,socket缓存里的数据,可能超过用户缓存的长度,如何处理? 例如,socket缓存有8kB的数据,而你的缓存只有2kB空间。
3, 向socket发送数据时, 可能只发送了用户缓存里的一半,如何处理?例如,需要向socket发送8kB数据,返回值只有2kB发送成功。
4, C++的虚函数是怎么实现的?
5, C++的虚函数有什么作用?
6, 非阻塞connect()如何实现?
7,sizeof()问题
class A
{
char c;
int val;
short sh;
}
class B
{
char c;
int val;
short sh;
void func1(void);
virtual func2(void);
}
sizeof(A), sizeof(B) 分别是多少?
8, 实现字符串比较函数 strcmp(char *src, char * sub)
9, 实现内存拷贝函数 strcpy(void*dst, char * src, size_t len)
10,条件变量的如何使用? 你使用的线程函数是什么?
11, deamon进程如何实现?
12, HTTP和CGI是什么?
13, TCP的三次握手, TIME_WAIT和CLOSE_WAIT状态是什么?
因为第7题之后的属于客观题,不打算在此写答案。 朋友们如有好的答案也欢迎跟贴。
本人在此写出自己对前6个问题的回答:
1, 使用linux epoll模型,水平触发模式(Level-Triggered);当socket可写时,会不停的触发socket可写的事件,如何处理?
第一种最普通的方式:
当需要向socket写数据时,将该socket加入到epoll模型(epoll_ctl);等待可写事件。
接收到socket可写事件后,调用write()或send()发送数据。。。
当数据全部写完后, 将socket描述符移出epoll模型。
这种方式的缺点是: 即使发送很少的数据,也要将socket加入、移出epoll模型。有一定的操作代价。
第二种方式,(是本人的改进方案, 叫做directly-write)
向socket写数据时,不将socket加入到epoll模型;而是直接调用send()发送;
只有当或send()返回错误码EAGAIN(系统缓存满),才将socket加入到epoll模型,等待可写事件后,再发送数据。
全部数据发送完毕,再移出epoll模型。
这种方案的优点: 当用户数据比较少时,不需要epool的事件处理。
在高压力的情况下,性能怎么样呢?
对一次性直接写成功、失败的次数进行统计。如果成功次数远大于失败的次数, 说明性能良好。(如果失败次数远大于成功的次数,则关闭这种直接写的操作,改用第一种方案。同时在日志里记录警告)
在我自己的应用系统中,实验结果数据证明该方案的性能良好。
事实上,网络数据可分为两种到达/发送情况:
一是分散的数据包, 例如每间隔40ms左右,发送/接收3-5个 MTU(或更小,这样就没超过默认的8K系统缓存)。
二是连续的数据包, 例如每间隔1s左右,连续发送/接收 20个 MTU(或更多)。
回来查了资料,发现以下两种方式:
第三种方式: 使用Edge-Triggered(边沿触发),这样socket有可写事件,只会触发一次。
可以在应用层做好标记。以避免频繁的调用 epoll_ctl( EPOLL_CTL_ADD, EPOLL_CTL_MOD)。 这种方式是epoll 的 man 手册里推荐的方式, 性能最高。但如果处理不当容易出错,事件驱动停止。
第四种方式: 在epoll_ctl()使用EPOLLONESHOT标志,当事件触发以后,socket会被禁止再次触发。
需要再次调用epoll_ctl(EPOLL_CTL_MOD),才会接收下一次事件。 这种方式可以禁止socket可写事件,应该也会同时禁止可读事件。会带来不便,同时并没有性能优势,因为epoll_ctl()有一定的操作代价。
2, 从socket读数据时,socket缓存里的数据,可能超过用户缓存的长度,如果处理?
可以调用realloc(),扩大原有的缓存块尺寸。
但是临时申请内存的有一定性能损失。
这种情况要看接收缓存的方式。
第一种方式: 使用100k的大接收缓存为例。
如果要等待数据,并进行解析。可能发生缓存不够的情况。此时只能扩充缓存,或先处理100k的数据,再接收新的数据。
第二种方式: 使用缓存队列,分成8K大小的队列。
不存在接收缓存不够的情况。 除非用户解析已出错,使用数据接收、使用脱勾。这种方式的代价是,可能需要将缓存队列再次拷贝、拼接成一块大的缓存,再进行解析。而在本人的系统中,只需要将socket接收的数据再次原样分发给客户, 所以这种方案是最佳方案。
3, 向socket发送数据时, 可能只发送了用户缓存里的一半,然后失败,如何处理?
记录缓存的偏移量。 下一次socket写事件时, 再从偏移的位置接着发送。
那个面试官居然对这个问题问了我两次, 看来我解释的不够清晰。。。。。。 郁闷。
4, C++的虚函数是怎么实现的?
使用虚函数表。
回来查下资料: C++对象使用虚表, 如果是基类的实例,对应位置存放的是基类的函数指针;如果是继承类,对应位置存放的是继承类的函数指针(如果在继承类有实现)。所以,当使用基类指针调用对象方法时,也会根据具体的实例,调用到继承类的方法。
5, C++的虚函数有什么作用?
虚函数作用是实现多态, 很多人都能理解这一点。但却不会回答下面这一点。
更重要的,虚函数其实是实现封装,使得使用者不需要关心实现的细节。在很多设计模式中都是这样用法,例如Factory、Bridge、Strategy模式。 前两天在书上刚好看到这个问题,但在面试的时候却没想起来。
个人觉得这个问题可以很好的区分C++的理解水平。
6, 非阻塞connect()如何实现?
将socket设置成non-blocking,操作方法同非阻塞read()、write();
面试官是在听到我介绍之后,才问我这个问题。可惜还是问我两遍。
**************
1.cache 的作用是什么
2.一下集中排序中,哪种是不稳定排序
3.排序算法的效率由什么衡量
4.在双向链表中,将一个节点P插入到链表中的节点Q后面,一下正确的操作是?
(2)填空题
1.是一个sin函数问题,给出sin的泰勒展开公式,和一个带有空格的程序流程图,完成程序流程图的空格。
sin(x)=x/1! - x3/3!+ x5/5! - …(-1)m-1 x(2m-1)/(2m-1)!
首先读入X,要求最后误差不差过m,流程图如下
2.链表,结构体 包括 1数据 2该节点被访问次数freq 要求一个节点每次被访问则freq++,整个链表按被访问次数(即访问频度)非升序排列。每次访问完节点后都对链表进行排序。
附加题:
背包问题。一个背包刚好装S克东西,有N个物体 重量分别是:W1 W2 W3….WN 请编程 用非递归的方法 得出一组解。
第一面,面技术,问了我的项目,STL,红黑树,练表反转+笔试错题重做
我后面面的很不好,很多都不会,分数较低
第二面,面技术,给我出了个算法题,星际在地图上点一块,如何找到该块上的所有物体
有可能会出逻辑推理题或者数学题
第三面,综合面,链表排序,easy
第四面,HR面试,胡扯了。有没有Offer听天由命了,嘻嘻,给后来的人一个参考
软件开发职位笔试试题
一、单项选择
1、向单链表插入节点;
2、排序的稳定性比较;
3、带头节点的单链表的判空条件;
4、二叉树的节点总数的计算;
5、递归向非递归的转化使用什么?队列,还是栈;
6、中断响应时间的定义;
7、面向对象程序设计语言不同于其他语言的主要特点;
二、填空题
1、正弦函数用泰勒展开式来计算:
下面的流程图描述了利用上述展开式计算并打印sinx的近似值的过程,其中e(>0)表示误差要求,小于该误差就可以结束计算,打印结果,请填写流程图中的空格部分。
图略
2、双循环链表的排序问题;
应该比较简单,相信你们能够搞定!
三、附加题
“背包问题”的基本描述是:有一个背包,能盛放的物品总重量为S,设有N个物件,其重量分别为W1,W2, ……… , Wn , 希望从N件物品中选择若干物品,所选择的物品的重量之和恰能放入该背包,即所选物品的重量之和等于S。递归和非递归解法都可以求得“背包问题”的一组解,试写出“背包问题”的非递归解法。
面试官以提问+代码
相结合。我的问题有:自我介绍,项目介绍,这两个是必须的,在介绍项目的时候,面试
官会深入问问题,会对某些细节,例如数据机构,算法复杂度,数据库连接问一些问题。
随后是专业面试,题目都是相当经典的题目,大致有:进程与线程;Unix和windows进程间
通信的主要方式和系统调用;叙述TCP/UDP协议,他们的应用,TCP的三次握手,滑动窗口
,超时重传;HTTP协议和COOKIE机制和一些COOKIE的问题(这个我不会);让你设计一个PD
A上的通信簿,你会用树还是哈希,从这个问题会引申出hash,平衡数,红黑数的一系列问
题;面向对象的多态是什么,设计一个多态的例子;C++的虚函数实现机制。问题不难,但
是你回答问题的手段和技巧很重要。几个经验:要有自信,敢说精通,熟悉这些词语,对
自己的强项一定要毫不犹豫的说精通。回答问题之前,好好组织一下语言,不要说的颠三
倒四,逻辑不清。问题一定要回答的全面,你说的越多越好,如果能把相关方面说出来更
好。
面我的据
说是互动娱乐部的一个manager(HR说的),面的问题很无聊:进程和线程,TCP/UDP,排序算
法(让我给他完整的说了一遍我所知道的排序算法和他们的时间复杂度),Windows的内存寻
址方式,Socket中阻塞模式干什么用的,你所认为的软件开发模式和你对你所做项目的一
些评价。最后是一个程序题,写代码,个题非常重要,如果做不出来或者做错了,那就
估计没戏了。题目是给定一个字符串,例如abc123de4f67,把里面所有的数字字串找出来,
并且存贮起来,例如你要把123,4,67找出来,放到3个char型数组里。这个题目很经典了
,相信很多人都知道。
两道算法题:
1. 给出一个字符串str及指定一个位置p,交换p的前后两段字符串,要求额外空间开销尽量小。例如给出str=”people”,p=2,结果串变为str=”oplepe”。其实只要一个char型变量作为临时空间,将p前的字符一个一个“沉”到最后就OK了,当时没想得出来真是丢脸啊!呜呜!
2. 给出串A=”iqwqrpwpetppwanepnvomzlplte”,B=”people”,问能否通过在串B的任意位置插入位置个字符生成串A,如果可以,计算出有多少种不同的生成方法,要求时间复杂度尽量小。一看这道题很容易误导思维,让人以B为考虑的出发点。事实上,换过来思考,问题就是找串A中有没有顺序地出现过B中的所有字符,这样就简单多啦,时间复杂度仅为O(m+n)!
第一大部分:
15道选择题,都是C/C++ 和数据结构的最基础的,基本上不会做错那种。
第二大部分:
程序填空2题:
1.前序遍历的
2.数组静态链表的插入
每题4空共40分
第三大部分:(每题20分,共60分)
附加题
1.实现3D镜像转换矩阵(题目不太明白,明白的同学给解释一下吧)
2.数据库SQL
a)建立employe表,包括工号、姓名、性别、年龄、部门、工资。
b)查询每个部门的工资总数
c)查询工资高于本部门平均工资的员工姓名
3.到商店里买200的商品返还100优惠卷(可以在本商店代替现金),请问
实际上折扣是多少?请写出推理过程。
两道编程题填空:
1.建链表,将链表倒置
2.统计一个相加为某一个整数的数列:8=4+2+1+1;8=3+2+2+1……
附加题:判断斗地主的玩家出牌的合法性!