第一次笔试及面试总结与反思

2019届秋招笔试题(考试时间120分钟)

一、目录

一. 选择题-第一部分(C/C++语法-10分)
二. 选择题–第二部分(数据结构和算法–10分)
三. 选择题–第三部分(Linux/操作系统–13分)
四. 选择题–第四部分(网络协议知识–10分)
五. 选择题–第五部分(智力题–2分)
六. 编程题 (共计 55 分)
1) Fibonacci数列 (10分)
2) 分苹果 (15分)
3) 求连续子数组的最大和 (15分)
4) 回文串 (15分)

一. 选择题-第一部分(C/C++语法-10分)

1、 有一个二维数组A[10][5],每个数据元素占1个字节,且A[0][0]的存储地址是1000,
则A[i][j]的地址是1000+5i+j
解析:

2、
const char str1[] = “abc”; const char str2[] = “abc”;
const char *p1 = “abc”; const char *p2 = “abc”;
str1和str2地址不同,P1和P2指向的地址相同
指针所指的字符串占用同一块空间,数组分配不同的内存空间。

3、 C语言,设有宏定义:

#define A 4+5
#define B A*A

则表达式B*B的值为 ( 69);
解析: B*B = A*A*A*A = 4+5*4+5*4+5*4+5 = 4+20+20+20+5 = 69

4.对于以下递归函数f,调用 f(4),其返回值为(10 )。

int f (int n)
{
   if (n)
     return f (n -1) + n;
  else
     return n;
}

解析: f(3)+4 —》 f(2)+4+3—》f(1)+4+3+2—》f(0)+4+3+2+1 = 10

5.语句char str[] = “abcde”;请问表达式sizeof(str)的值是( 6)
解析: sizeof()求字符串长度,包含\0

6.已知表达式++a中的”++”是作为成员函数重载的运算符,则与a++等效的运算符函数调用形式为(a.operator++(0))

7.有这样一个类:

class Eye
{
   public:
   void Look(void);
};

现在希望定义一个Head类,也想实现Look的功能,应该使用(组合 )的方法,实现代码重用。

8.有如下代码:

#include<iostream>
using namespace std;
class MyClass
{
public:
    MyClass(int i = 0)//111
    {
        cout<<i;
    }

    MyClass(const MyClass &s)//222
    {
        cout<<2;
    }
    MyClass &operator=(const MyClass &x)//333
    {
        cout<<3;
        return *this;
    }

    ~MyClass()//444
    {
        cout<<4;
    }

};

int main()
{
    MyClass obj1(1);
    MyClass obj2(2);
    MyClass obj3 = obj1;
    return 0;
}
//122444请按任意键继续. . .

解析:如上所示,为了方便描述,将四个成员函数分别标为111,222,333,444, MyClass obj1(1) 和MyClass obj2(2)调用构造函数111,所以输出自带值1,2, ,MyClass obj3 = obj1;属于用一个对象构造另一个对象,故而需要调用拷贝构造函数222,故输出2,三个对象构造完之后,进行对象的销毁,分别调用三次析构函数,故4,4,4
综上所述,输出 1,2,2,4,4,4

9.关于迭代器失效的描述:
A vector的插入操作会导致迭代器失效
B map的插入操作不会导致迭代器失效
C vector的删除操作只会导致指向被删除元素及后面的迭代器失效
D map的删除操作只会导致指向被删除元素的迭代器失效

10.下列关于模板的说法正确的是 (类模板中的成员函数不全是模板函数 )

二. 选择题–第二部分(数据结构和算法–10分)

1.已知一棵二叉树,如果先序遍历的节点顺序是:ADCEFGHB,中序遍历是:CDFEGHAB,则后序遍历结果为:(CFHGEDBA
解析:

2.某二叉树有如下特性,每一个结点要么是叶子结点,要么有2个子树。如果有一个这样的数有m个叶子结点,则这棵树 的总结点数是( 2m-1
解析:举例子:

3.散列技术中的冲突是指( 不同键值的元素对应于相同的存储地址)。
解析: 解决冲突的方法有: 闭散列,开散列

4.折半查找的时间复杂性为(O(logn))
解析: 排序算法的时间复杂度及空间复杂度为:
插入排序:O(N^2),O(1)
希尔排序:O(N^2),O(1)
选择排序:O(N^2),O(1)
堆排序:O(NlogN),O(1)
冒泡排序:O(N^2),O(1)
快速排序:平均时间复杂度O(NlogN),最糟糕时间复杂度O(N^2),空间复杂度:O(1)
归并排序:O(NlogN),O(N)
[七种排序详解] (https://blog.csdn.net/dai_wen/article/details/80644772)

5.链表的特征插入或删除时,无需移动其他元素

6.设一个栈的输入序列是 1 2 3 4 5,则下列序列中,栈的合法输出序列的是(32154)。

7.将一个递归算法改为对应的非递归算法时,通常需要使用( )。
解析:如:逆向打印单链表

8.下列排序算法中,占用辅助空间最多的是(归并排序)
解析:归并排序:时间复杂度O(NlogN),空间复杂度:O(N)

9.给定一个 std::lista, 对于
方式一 std::sort(a.begin(), a.end())
方式二 a.sort() 两种操作, C 方式一编译报错, 方式二时间复杂度是O(NlogN)

三. 选择题–第三部分(Linux/操作系统–13分)

1.**linux系统中,给文件授予可执行权限的命令是(**chmod

2. 关于内存泄漏说法正确的是 如果一个进程在运行过程中占用的内存无限制上升,那么该进程有内存泄漏

3.进程和线程是操作系统中最基本的概念
A 进程是程序的一次执行,而线程可以理解为程序中运行的一个片段
B 由于线程没有独立的地址空间,因此同一个进程的一组线程可以访问该进程资源, 这些线程之间的通信也很高效
C 线程之间的通信简单(共享内存即可,但须注意互斥访问的问题),而不同进程之间 的通信更为复发,通常需要调用内核实现
D 线程有独立的虚拟地址空间,但是拥有的资源相对进程来说,只有运行所必须的栈, 寄存器等【错误】

4. 如果信号量的当前值为 -4,则表示系统中在该信号量上有(4)个进程等待。
在记录型信号量中,
解析:
S.value>0数值时,表示某类可用资源的数量。
S.value<0时,表示该类资源已分配完。若有进程请求该类资源,则被阻塞, 这时,S.value的绝对值等于等待该类资源的进程数。

5. 为了防止操作失误无意中修改某个已保存的重要历史文件,最好将该文件的属性改为 (只读 )

6. find -newer file1 ! file2 命令的意思是:查找更改时间比文件file1新但比文件file2旧的文件

7. 多线程中栈与堆的基本情况是 (多个线程各自有一个栈,共有一个堆)

8. 关于 Linux 中僵尸进程
A 僵尸进程对应于Linux中的一种进程状态.
B 僵尸进程的成因是由于父进程没有读取子进程的返回结果.
C 僵尸进程的危害是引起内存泄露.
D 僵尸进程的处理方式只有进程等待.【错误】
解析:
通常有两种方式处理僵尸进程:

(1)改写父进程,在子进程死后要为它收尸具体做法是接管SIGCHLD信号。子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。这是基于这样的原理:就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,尽管对的默认处理是忽略,如果想响应这个消息,可以设置一个处理函数。
(2)把父进程杀掉。父进程死后,僵尸进程成为孤儿进程,过继给1号进程init,init始终会负责清理僵尸进程.它产生的所有僵尸进程也跟着消失。
9

int main()
{
    for (int i = 0; i < 2; ++i)
      {
       fork();
       printf("-");
       }
    return 0;
}

则代码执行完毕后, 共打印8个 “-“

10.有一个程序中有A,B,C三个线程同时对一个文件进行读写操作,其中的A,B是写线程只负责往里面写数据,C是读线 程,同时把读取的数据从文件中删除,A线程
单独写满文件需要10个小时,B单独写程序需要6小时,C线程需要15小时才 能读取完整个文件,不考虑三个线程之间的相互影响的情况下现在*5*小时才能写满文件。

11.不可以作为进程间通信方式( * 条件变量*)
可以作为进程间通信方式: 信号、 socket、普通文件

12. Which Synchronization mechanism(s) is/are used to avoid race conditions among processes/threads in operating systems()
A Signal(信号)
B Mailbox(客户端)
C Local procedure call(本地过程调用)
D Semaphore(信号量)
解析: 选择D,Semaphore是操作系统用于控制进程同步互斥的量。

13. 以下哪种出现死锁的必要条件 ( 请求和保持、不可剥夺、循环等待)
解析同步和互斥不为出现死锁的必要条件
死锁产生的原因是:竞争资源和进程推进顺序不当
处理死锁的基本方法:预防死锁,避免死锁,检测死锁,解除死锁
死锁的预防就是破坏除互斥以外的其它三个必要条件。

四. 选择题–第四部分(网络协议知识–10分)

1.上网的时候发现网页不能访问,QQ使用正常,出现此问题最可能的原因是( )
A 网线问题
B DNS问题
C IP地址冲突
D 网关错误
**解析:**DNS域名系统,万维网作为域名和IP地址相互映射的一个分布式数据库,使用户更方便的访问互联网,而不用去记能够被机器直接读取的IP数串,通过域名,最终的到该域名对应的IP地址的过程叫做域名解析(主机名解析),DNS协议运行在UDP协议之上,使用端口号53;

2. 关于以下 URL的描述错误的是( )
http://www.baidu.com/
A url中的 http 表式使用TCP协议
B url又名统一资源定位符,方便确定一个资源,并表示出它在哪里
C url中隐藏了端口号,默认是80端口
D 访问URL可使用大写字母
解析:URL又名统一资源定位符,是互联网上资源的标准地址,每个文件都有一个唯一的URL。

3. 关于网络编程的一些描述
A 一个 Socket 可以绑定多个网卡
B 客户端和服务器端都可以主动关闭 Socket
C Socket 支持阻塞模式和非阻塞模式
D TCP 和 UDP 协议可以绑定同一端口

4. 为测试本地 TCP/IP 协议,通常可以 ping 下列哪个地址?
A 255.255.255.255,用于主机配置过程中IP数据报的目的地址
B 192.168.0.1 本地局域网IP,用于设计路由器
C 0.0.0.0 保留地址,默认路由
D 127.0.0.1 主机本地地址,通常用于测试本地协议

5.主机甲向主机乙发送一个(SYN=1, seq=11220)的 TCP 段,期望与主机乙建立 TCP 连接,若主机乙接受该连接 请求,则主机乙向主机甲发送的正确的 TCP段可能是( )。
A ( SYN=0, ACK=0, seq=11221, ack=11221)
B ( SYN=1, ACK=1, seq=11220, ack=11220)
C ( SYN=1, ACK=1, seq=11221, ack=11221)
D ( SYN=0, ACK=0, seq=11220, ack=11220)

6. ICMP报文通过协议来传输
A UDP
B TCP
C IP
D ARP
解析:UDP、TCP位于传输层,UDP是不可靠的,无连接,点到多点的传输方式,TCP是可靠地,有连接,点到点的传输, ARP数据报格式是用来根据IP地址获取吓一跳的MAC地址。RARP的作用是根据MAC地址获取IP地址。

7. 在TCP报文段中,接收窗口(receive window)字段用于( 流量控制 )

8.How long is a MAC address? ( )(译:一个MAC地址占几个字节?)
解析6 bytes

9.主机甲和主机乙新建一个TCP 连接,甲的拥塞控制初始阈值为 32KB,甲向乙始终以MSS=1KB 大小的段发送数据, 并一直有数据发送;乙为该连接分配 16KB接收缓存,并对每个数据段进行确认,忽略段传输延迟。若乙收到的数据全 部存入缓存,不被取走,则甲从连接建立成功时刻起,未发送超时 的情况下,经过 4 个RTT 后,甲的发送窗口是 ( 1KB)。

10.请从下列给定地址中找出与192.168.1.110/27属于同一个子网的主机地址()
A 192.168.1.94
B 192.168.1.96
C 192.168.1.124
D 192.168.1.136

五. 选择题–第五部分(智力题–2分)

1. 找出符合规律的数字填到括号中 24、26、25、25、(26)、24、27、(23)
解析
下标从1开始计算, 其中奇数下标为一组, 偶数下标为一组. 奇数下标的数字递增1, 偶数下标的数字递减1.

2. 用容积分别为15升和27升的两个杯子向一个水桶中装水,可以精确向水桶中注入( )升水?
A 53
B 25
C 33
D 52
解析: 15装满倒入27,再15装满倒入27至满,剩下3升。所以3的倍数可以获得。而且由于2个杯子都是3的倍数,所得也只能是 3的倍数。15+15+3

3.若某表最常用的操作是在最后一个结点之后插入一个节点或删除最后一二个结点,则采用(带头结点的双循环链表)省运算时间。

六. 编程题 (共计 55 分)

1) Fibonacci数列 (10分)
Fibonacci数列是这样定义的:
F[0] = 0
F[1] = 1
for each i ≥ 2: F[i] = F[i-1] + F[i-2]
因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, …,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把
当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数。

#include <iostream>
#include <vector>
using namespace std;
int main(void)
{
    int num;
    cin >> num;
    if (num < 0)
        {
            return 1;
        }
int first = 0;
int second= 1;
while(num > second)
{
    int newFib= first + second;
    first = second;
    second = newFib;
}
    int stepone = num - first;
    int steptwo= second - num;
    int step;
    step = stepone < steptwo ? stepone : steptwo;
    cout << step << endl;
    return 0;
}

2) 分苹果 (15分)

#include<iostream>
#include<algorithm>
using namespace std;
int buf[100];
int main()
{
    int number;
     while(scanf("%d",&number)>0)
     {
        int sum=0;
        for(int i=1; i<=number;i++)
        {
           scanf("%d",&buf[i]);
           sum=sum+buf[i];
        }
    int flag=0;
    if(sum%number!=0)//如果总数不能被平分,那么怎么挪也是失败
    flag=1;
    int avg=sum/number,cnt=0;
    for(int i=1;i<=number;i++)
   {
    if(abs(buf[i]-avg)%2!=0)//如果有的不能通过每次挪两个达到平均值那么就会失败
    flag=1;
    cnt+=abs(buf[i]-avg)/2;
    }
  if(flag)
  cout<<-1<<endl;
  else
    cout<<cnt/2<<endl;//每次挪动解决两个奶牛的问题,所以要除2
   }
}

3) 求连续子数组的最大和 (15分)

#include <iostream>
using namespace std;
int main()
{
   int n,curSum=0,maxSum=-1e5;
   cin>>n;
   int arr[n];
   for(int i=0;i<n;i++)
   {
     cin>>arr[i];
     curSum+=arr[i];
     if(curSum>maxSum)
     {
       maxSum=curSum;
      }
   if(curSum<0)
   {
     curSum=0;
   }
  }
cout<<maxSum<<endl;
return 0;
}

4) 回文串 (15分)

#include <iostream>
#include <cstdlib>
#include <string>
#include <algorithm>
using namespace std;
/*判断是否为回文串*/
bool isPalindrome(const string &str)
{
  string s = str;
  reverse(s.begin(), s.end());
  return s == str;
}
int main()
{
  string str;
  while (cin >> str)
  {
   if (str.empty() || str.length() == 1)
     cout << "YES";
   else
   {
    int len = str.length();
    string tmp;
    bool ret = false;
    for (int i = 0; i < len; ++i)
   {
    tmp = str.substr(0, i) + str.substr(i + 1);
    if (isPalindrome(tmp))
    {
       ret = true;
       break;
     } 
  }
    if (ret)
      cout << "YES" << endl;
   else
      cout << "NO" << endl;
    }
  }
   return 0;
}

面试总结

时:请做一下自我介绍?
我:您好,我叫XXX,来自西安工程大学,我的专业是电子信息科学与技术,虽然专业有些偏硬件,但是,大一的时候我发现自己对编程很感兴趣,所以就自学软件编程,直到现在,满打满算已经三年了。嗯,就这么多吧。
时:完了?
我:嗯,完了。
时:。。。
嗯,完了。
(接下来太惨烈了,就不一一叙述了)
本次面试问到的有以下几个问题:
(1)自我介绍包含:基本信息,行业兴趣,对公司了解,自学课程,如何学习,途径方法,列举一些课程名,看过的书,最后提一下求职意向,以上就是我的基本信息,谢谢。
(2)STL中,list如何删除所有节点?(clear)
(3)STL中,map中,如果要查找一个元素该怎么做?(find)
(4)智能指针:引入,原理,举例智能指针有哪些,应用场景,存在缺陷?
(5)编写一个简单的makefile?
(6)什么是socket套接字?
(7)项目五子棋:功能介绍,项目简介,项目优化:实现网络版
(8)什么是事务?

猜你喜欢

转载自blog.csdn.net/dai_wen/article/details/79175686