首页 > 技术文章 > 牛客网题目解析

mswangblog 2017-03-24 14:28 原文

1、IP地址与它的掩码取反相与,所得的非零点分十进制数是此IP地址的(主机地址)

IP地址包括网络地址和主机地址,IP地址与它的掩码取反相与,其实就是将网络部分全部赋值为0,网络地址部分和1相与操作,所得的非零点分十进制数是此IP地址的。

2、

/etc/hosts 主机名到 IP 地址的映射关系的文件
/etc/resolv.conf DNS 服务的配置文件 
/etc/gateways 建立动态路由需要用到的文件 
3、
  SQL(Structured Query Language)结构化查询语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。同时也是数据库脚本文件的扩展名。
  TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议.
  超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
  QoS(Quality of Service)服务质量,是网络的一种安全机制, 是用来解决网络延迟和阻塞等问题的一种技术。 在正常情况下,如果网络只用于特定的无时间限制的应用系统,并不需要QoS,比如Web应用,或E-mail设置等。但是对关键应用和多媒体应用就十分必要。当网络过载或拥塞时,QoS 能确保重要业务量不受延迟或丢弃,同时保证网络的高效运行。
   STL = Standard Template Library,标准模板库 XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Markup Language,标准通用标记语言)。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。
4、段的逻辑地址形式是段号10位,段内地址20位,内存1MB,辅存10GB。那么虚拟存储器最大实际容量可能是()。
  虚拟存储器最大实际容量= min(计算机地址,内存+辅存)。
  计算机地址= 2^ 10* 2^20=1024M(2^10是1024k)
5、
发送数据帧时,交换机从1号端口接收此数据帧,因目的MAC地址不在转发表中,所以交换机采用洪泛法向其它端口(2、3)转发此帧,同时将源MAC地址登记在转发表中;发送确认帧时,交换机从3号端口接收此帧,查找转发表,从相应1号端口转发此帧。
6、浏览器和服务器在基于https进行请求链接到数据传输过程中,用到了如下哪些技术?
  a、非对称加密算法用于在握手过程中加密生成的密码
  b、对称加密算法用于对真正传输的数据进行加密
      非对称加密算法会生成公钥和私钥,公钥只能用于加密数据,因此可以随意传输,而网站的私钥用于对数据进行解密,所以网站都会非常小心的保管自己的私钥,防止泄漏。
  c、HASH算法用于验证数据的完整性。
  d、HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一次握手,在握 手过程中将确立双方加密传输数据的密码信息,通常情况下会配合数字证书实现。TLS/SSL协议不仅仅是一套加密传输的协议,更是一件经过艺术家精心设计的艺术品,TLS/SSL中使用 非对称加密,对称加密以及HASH算法。
7、下列关于文件索引结构的叙述中,哪些是正确的?
系统为每个文件建立一张索引表
采用索引结构会引入存储开销
从文件控制块中可以找到索引表或索引表的地址

为了提高文件的检索效率,可以采用索引方法组织文件。采用索引这种结构,逻辑上连续的文件可以存放在若干不连续的物理块中,但对于每个文件,在存储介质中除存储文件本身外,还要求系统另外建立一张索引表,索引表记录了文件信息所在的逻辑块号和与之对应的物理块号。索引表也以文件的形式存储在存储介质中,索引表的物理地址则由文件说明信息项给出。

    在很多情况下,有的文件很大,文件索引表也就较大。如果索引表的大小超过了一个物理块,可以采用间接索引(多重索引),也就是在索引表所指的物理块中存放的不是文件信息,而是装有这些信息的物理块地址。这样,如果一个物理块可装下n个物理块地址,则经过一级间接索引,可寻址的文件长度将变为n×n块。如果文件长度还大于n×n块,还可以进行类似的扩充,即二级间接索引。

    不过,大多数文件不需要进行多重索引,也就是说,这些文件所占用的物理块的所有块号可以放在一个物理块内。如果对这些文件也采用多重索引,则显然会降低文件的存取速度。因此,在实际系统中,总是把索引表的头几项设计成直接寻址方式,也就是这几项所指的物理块中存放的是文件信息;而索引表的后几项设计成多重索引,也就是间接寻址方式。在文件较短时,就可利用直接寻址方式找到物理块号而节省存取时间。
    索引结构既适用于顺序存取,也适用于随机存取,并且访问速度快,文件长度可以动态变化。索引结构的缺点是由于使用了索引表而增加了存储空间的开销。另外,在存取文件时需要至少访问存储器两次以上,其中,一次是访问索引表,另一次是根据索引表提供的物理块号访问文件信息。由于文件在存储设备的访问速度较慢,因此,如果把索引表放在存储设备上,势必大大降低文件的存取速度。一种改进的方法是,当对某个文件进行操作之前,系统预先把索引表放入内存,这样,文件的存取就可直接在内存通过索引表确定物理地址块号,而访问存储设备的动作只需要一次。当文件被打开时,为提高访问速度将索引表读入内存,故又需要占用额外的内存空间。

8、下列选项中,()是分时系统中确定时间片大小需要考虑的因素。

    就绪队列中进程的数目
    系统的处理能力
    系统对响应时间的要求

 确定时间片长度要从进程数目、切换开销、系统效率和响应时间等多方面因素加以考虑。
如果时间片取值太小,将导致大多数进程/线程都不可能在一个时间片内运行完毕,就会频繁切换,开销显著增大,所以从系统效率来讲,时间片应该大些好;如果时间片长度较大,那么随着就绪队列中进程/线程数目的增加,轮转一次所耗费的总时间加长,即对每个进程/线程的响应速度 放慢,甚至时间片大到让进程/线程足以完成其所有任务,时间片调度算法便退化为FCFS算法。为了满足用户对响应时间的要求,要么限制就绪队列中进程/线程的数量,要么采用变化的时间片长度,根据当前负载情况及时调整时间片大小。
9、下面属于进程间通信的有?

 管道:  管道中还有命名管道和非命名管道之分, 非命名管道只能用于父子进程通讯,命名管道可用于非父子进程,命名管道就是FIFO,管道是先进先出的通讯方式。FIFO是一种先进先出的队列。它类似于一个管道,只允许数据的单向流动。每个FIFO都有一个名字,允许不相关的进程访问同一个FIFO,因此也成为命名管。

    消息队列: 是用于两个进程之间的通讯,首先在一个进程中创建一个消息队列,然后再往消息队列中写数据,而另一个进程则从那个消息队列中取数据。需要注意的是,消息队列是用创建文件的方式建立的,如果一个进程向某个消息队列中写入了数据之后,另一个进程并没有取出数据,即使向消息队列中写数据的进程已经结束,保存在消息队列中的数据并没有消失,也就是说下次再从这个消息队列读数据的时候,就是上次的数据!!!

    信号量: 不能传递复杂消息,只能用来同步

    共享内存: 只要首先创建一个共享内存区,其它进程按照一定的步骤就能访问到这个共享内存区中的数据,当然可读可写;

 

10、A,B两台机器都正常工作,B机器未监听任何端口.如果A机器向B机器80端口发送SYN包,会收到何种类型的回包?

端口未打 

服务器程序端口未打开而客户端来连接。这种情况是最为常见和好理解的一种了。去 telnet 一个未打开的 TCP 的端口可能会出现这种错误。这个和操作系统的实现有关。在某些情况下,操作系统也会完全不理会这些发到未打开端口请求 。

比如在下面这种情况下,主机 241 向主机 114 发送一个 SYN 请求,表示想要连接主机 114 的 40000 端口,但是主机 114 上根本没有打开 40000 这个端口,于是就向主机 241 发送了一个 RST 。这种情况很常见。特别是服务器程序 core dump 之后重启之前连续出现 RST的情况会经常发生 。

 当然在某些操作系统的主机上,未必是这样的表现。比如向一台 WINDOWS7 的主机发送一个连接不存在的端口的请求,这台主机就不会回应 。

请求超

曾经遇到过这样一个情况 : 一个客户端连接服务器, connect 返回 -1 并且 error=EINPROGRESS 。 直接 telnet 发现网络连接没有问题。 ping 没有出现丢包。用抓包工具查看,客户端是在收到服务器发出的 SYN 之后就莫名其妙的发送了 RST 。

比如像下面这样 :

 有 89 、 27 两台主机。主机 89 向主机 27 发送了一个 SYN ,表示希望连接 8888 端口,主机 27 回应了主机 89 一个 SYN 表示可以连接。但是主机 27 却很不友好,莫名其妙的发送了一个 RST 表示我不想连接你了 。

后来经过排查发现,在主机 89 上的程序在建立了 socket 之后,用 setsockopt 的 SO_RCVTIMEO 选项设置了 recv 的超时时间为100ms 。而我们看上面的抓包结果表示,从主机 89 发出 SYN 到接收 SYN 的时间多达 110ms 。(从 15:01:27.799961 到15:01:27.961886 , 小数点之后的单位是微秒)。因此主机 89 上的程序认为接收超时,所以发送了 RST 拒绝进一步发送数据 。

提前关

关于 TCP ,我想我们在教科书里都读到过一句话, 'TCP 是一种可靠的连接 ' 。 而这可靠有这样一种含义,那就是操作系统接收到的来自 TCP 连接中的每一个字节,我都会让应用程序接收到。如果应用程序不接收怎么办?你猜对了, RST 。

在一个已关闭的 socket 上收到数

如果某个 socket 已经关闭,但依然收到数据也会产生 RST 。

 

11、在请求分页系统中,页表中的访问位是供()参考的。

页表项(页描述子)中各个位的作用:
1. 页号
2. 块号(页框号)
3. 中断位: 用于判断该页是不是在内存中,如果是0,表示该页面不在内存中,会引起一个缺页中断
4. 保护位(存取控制位):用于指出该页允许什么类型的访问,如果用一位来标识的话:1表示只读,0表示读写
5. 修改位(脏位):用于页面的换出,如果某个页面被修改过(即为脏),在淘汰该页时,必须将其写回磁盘,反之,可以直接丢弃该页
6. 访问位:不论是读还是写(get or set),系统都会设置该页的访问位,它的值用来帮助操作系统在发生缺页中断时选择要被淘汰的页,即用于页面置换
7. 高速缓存禁止位(辅存地址位):对于那些映射到设备寄存器而不是常规内存的页面有用,假设操作系统正在循环等待某个I/O设备对其指令进行响应,保证硬件不断的从设备中读取数据而不是访问一个旧的高速缓存中的副本是非常重要的。即用于页面调入
 
12、在数据库系统中,产生不一致的根本原因是( )

造成数据不一致的原因主要有:

  • 数据冗余

如果数据库中存在冗余数据,比如两张表中都存储了用户的地址,在用户的地址发生改变时,如果只更新了一张表中的数据,那么这两张表中就有了不一致的数据。

  • 并发控制不当

比如某个订票系统中,两个用户在同一时间订同一张票,如果并发控制不当,可能会导致一张票被两个用户预订的情况。当然这也与元数据的设计有关。

  • 故障和错误

如果软硬件发生故障造成数据丢失等情况,也可能引起数据不一致的情况。因此我们需要提供数据库维护和数据恢复的一些措施。

 

13、数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

 

14、进程中线程同步的四种常用方式:

  1、 临界区(CCriticalSection)
  当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止。具体应用方式:
  1、 定义临界区对象CcriticalSection g_CriticalSection;
  2、 在访问共享资源(代码或变量)之前,先获得临界区对象,g_CriticalSection.Lock();
  3、 访问共享资源后,则放弃临界区对象,g_CriticalSection.Unlock();
  
  2、 事件(CEvent)
  事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。比如在某些网络应用程序中,一个线程如A负责侦听通信端口,另外一个线程B负责更新用户数据,利用事件机制,则线程A可以通知线程B何时更新用户数据。每个Cevent对象可以有两种状态:有信号状态和无信号状态。Cevent类对象有两种类型:人工事件和自动事件。
  自动事件对象,在被至少一个线程释放后自动返回到无信号状态;
  人工事件对象,获得信号后,释放可利用线程,但直到调用成员函数ReSet()才将其设置为无信号状态。在创建Cevent对象时,默认创建的是自动事件。
  1、1234CEvent(BOOL bInitiallyOwn=FALSE,          BOOL bManualReset=FALSE,          LPCTSTR lpszName=NULL,          LPSECURITY_ATTRIBUTES lpsaAttribute=NULL);

  bInitiallyOwn:指定事件对象初始化状态,TRUE为有信号,FALSE为无信号;
  bManualReset:指定要创建的事件是属于人工事件还是自动事件。TRUE为人工事件,FALSE为自动事件;
  后两个参数一般设为NULL,在此不作过多说明。
  2、BOOL CEvent::SetEvent();
  将Cevent类对象的状态设置为有信号状态。如果事件是人工事件,则Cevent类对象保持为有信号状态,直到调用成员函数ResetEvent()将其重新设为无信号状态时为止。如果为自动事件,则在SetEvent()后将事件设置为有信号状态,由系统自动重置为无信号状态。
  
  3、BOOL CEvent::ResetEvent();
  将事件的状态设置为无信号状态,并保持该状态直至SetEvent()被调用为止。由于自动事件是由系统自动重置,故自动事件不需要调用该函数。
  一般通过调用WaitForSingleObject()函数来监视事件状态。
  
  3、 互斥量(CMutex)
  互斥对象和临界区对象非常相似,只是其允许在进程间使用,而临界区只限制与同一进程的各个线程之间使用,
  但是更节省资源,更有效率。
  4、 信号量(CSemphore)
  当需要一个计数器来限制可以使用某共享资源的线程数目时,可以使用“信号量”对象。CSemaphore类对象保存了对当前访问某一个指定资源的线程的计数值,该计数值是当前还可以使用该资源的线程数目。如果这个计数达到了零,则所有对这个CSemaphore类对象所控制的资源的访问尝试都被放入到一个队列中等待,直到超时或计数值不为零为止。

  
  CSemaphore(
  LONG lInitialCount = 1,
  LONG lMaxCount = 1,
  LPCTSTR pstrName = NULL,
  LPSECURITY_ATTRIBUTES lpsaAttributes = NULL
  );
  
  lInitialCount:信号量对象的初始计数值,即可访问线程数目的初始值;
  lMaxCount:信号量对象计数值的最大值,该参数决定了同一时刻可访问由信号量保护的资源的线程最大数目;
  后两个参数在同一进程中使用一般为NULL,不作过多讨论;
  一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数就减1,只要当前可用资源计数大于0,就可以发出信号量信号。如果为0,则放入一个队列中等待。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可用资源数加1。

15、
UNIX操作系统,是一个强大的多用户、多任务 操作系统 ,支持多种 处理器架构 ,按照操作系统的分类,属于 分时操作系统
  1. UNIX系统是一个多用户,多任务的分时操作系统。
  2. UNIX的系统结构可分为三部分:操作系统内核(是UNIX系统核心管理和控制中心,在系统启动或常驻内存),系统调用(供程序开发者开发应用程序时调用系统组件,包括进程管理,文件管理,设备状态等),应用程序(包括各种开发工具,编译器,网络通讯处理程序等,所有应用程序都在Shell的管理和控制下为用户服务)。
  3. UNIX系统大部分是由C语言编写的,这使得系统易读,易修改,易移植。
  4. UNIX提供了丰富的,精心挑选的系统调用,整个系统的实现十分紧凑,简洁。
  5. UNIX提供了功能强大的可编程的Shell语言(外壳语言)作为用户界面具有简洁,高效的特点。
  6. UNIX系统采用树状目录结构,具有良好的安全性,保密性和可维护性。
  7. UNIX系统采用进程对换(Swapping)的内存管理机制和请求调页的存储方式,实现了虚拟内存管理,大大提高了内存的使用效率。
  8. UNIX系统提供多种通信机制,如:管道通信,软中断通信,消息通信,共享存储器通信,信号灯通信。

16在分区存储管理中,下面的()最有可能使得高地址空间变成为大的空闲区。

首次适应法:从空闲 分区表 的第一个表目起查找该表,把最先能够满足要求的空闲区分配给作业,这种方法目的在于减少查找时间。为适应这种算法,空闲分区表(空闲区链)中的空闲分区要按地址由低到高进行排序。该算法优先使用低址部分空闲区,在低址空间造成许多小的空闲区,在高 地址空间 保留大的空闲区。
最佳适应算法:从全部空闲区中找出能满足作业要求的、且大小最小的空闲分区的一种计算方法,这种方法能使碎片尽量小。
最坏适应分配算法:要扫描整个空闲分区或链表,总是挑选一个最大的空闲分区分割给作业使用。该算法要求将所有的空闲分区按其容量从大到小的顺序形成一空闲分区链,查找时只要看第一个分区能否满足作业要求。
循环首次适应算法: 该算法是首次适应算法的变种。在分配内存空间时,不再每次从表头(链首)开始查找,而是从上次找到空闲区的下一个空闲开始查找,直到找到第一个能满足要求的的空闲区为止,并从中划出一块与请求大小相等的内存空间分配给作业。该算法能使内存中的空闲区分布得较均匀。
 
17、如果一个程序为多个程序所共享,那么该程序的代码在执行的过程中不能被修改,即程序应该是()
可重入码:当被多个线程调用的时候,不会引用任何共享数据,他们是线程安全的。(注意与线程安全做区别 可重入是线程安全的真子集)
 
18、
  301重定向是永久的重定向,搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址。
  302重定向是暂时的重定向, Temporarily Moved   搜索引擎会抓取新的内容而保存旧的网址。由于效劳器前往302代码,搜索引擎以为新的网址只是暂时的。
危害:
  302重定向很容易被搜索引擎误认为是利用多个域名指向同一网站,那么你的网站就会被封掉,罪名是“利用重复的内容来干扰Google搜索结果的网站排名”。因为302重定向经常被用于做url劫持, 黑帽 seo技术中,而且百度在处理302重定向技术还不成熟,经常将它纳入到黑帽seo的范畴中,而google对这方面识别处理就完善了许多。所以302重定向在现阶段的搜索引擎技术中,还是容易导致网站 降权的,尽量不用。但从seo、网站优化方面来说是弊大于利。
  302重定向与URL 劫持
  从网址A 做一个302 重定向到网址B 时, 主机 服务器的隐含意思是网址A 随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到302 重定向时,一般只要去抓取目标网址就可以了,也就是说网址B。如果搜索引擎在遇到302 转向时,百分之百的都抓取目标网址B 的话,就不用担心网址URL 劫持了。问题就在于,有的时候搜索引擎,尤其是Google,并不能总是抓取目标网址。比如说,有的时候A 网址很短,但是它做了一个302 重定向到B 网址,而B 网址是一个很长的乱七八糟的URL 网址,甚至还有可能包含一些 问号 之类的参数。很自然的,A 网址更加用户友好,而B 网址既难看,又不用户友好。这时Google 很有可能会仍然显示网址A。由于 搜索引擎排名 算法只是程序而不是人,在遇到302 重定向的时候,并不能像人一样的去准确判定哪一个网址更适当,这就造成了网址 URL  劫持的可能性。也就是说,一个不道德的人在他自己的网址A 做一个302 重定向到你的网址B,出于某种原因, Google 搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B 上的内容,这种情况就叫做网址URL 劫持。你辛辛苦苦所写的内容就这样被别人偷走了。302 重定向所造成的网址URL 劫持现象,已经存在一段时间了
 
  403错误,禁止访问。资源不可用。服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致
  500 Internal Server Error
       服务器遇到一个妨碍它为请求提供服务的错误时
  501 Not Implemented 
      客户端发起的请求超出服务器的能力范围(比如,使用了服务器不支持的请求方法)
  502 Bad Gateway
      作为代理或网关使用的服务器从请求响应链的下一条链路上收到了一条伪响应(比如,它无法连接到其父网关)
  503 Service Unavailable 
      用来说明服务器现在无法为请求提供服务,但将来可以。如果服务器知道什么时候资源会变为可用的,可以在响应中包含一个 Retry-After 首部
  504 Gateway Timeout 
      与状态码 408 类似,只是这里的响应来自一个网关或代理,它们在等待另一服务器对其请求进行响应时超时了
  505 HTTP  Version  Not Supported
      服务器收到的请求使用了它无法或不愿支持的协议版本时。有些服务器应用程序会选择不支持协议的早期版本
 
19以下关于多线程的叙述错误的是:
线程同步的方法包括使用临界区,互斥量,信号量等
两个线程同时对简单类型全局变量进行写操作也需要互斥
实现可重入函数时,对自动变量也要用互斥量加以保护(错误)
可重入函数不可以调用不可重入函数
可重入函数可认为是可以被中断的函数,自动变量定义的时候才被创建,函数返回时,系统回收空间,他是的是局部作用域变量,不需要互斥量。可重入函数对全局变量才需要互斥量保护。
 
20、假设Apache产生的日志文件名为access_log,在apache正在运行时,执行命令mv  access_log access_log.bak,执行完后,请问新的apache的日志会打印到哪里,请选择下列描述正确的是?

虽然此时文件被改名,但是由于服务正在运行,因为它的inode节点的位置没有变,程序打开的fd仍然会指向原来那个inode,不会因为文件名的改变而改变。apache会继续向已改名的文件中追加日志。
mv对inode的影响:

前提:使用mv命令搬移的文件目的地跟原文件在同一文件系统内

1. 系统会新建一个目录项,将新档案名称对应到inode number (注意,inode number并没有变,只是对应了新的名字)

2. 删除旧档案

(搬移档案的行为对inode table没有任何影响,也不会将档案搬移到其他的block)
 
由此可见,在我们看来access_log  和  access_log.bak  是两个不同的文件,其实他们是同一个文件,只是换了名字而已。
由于程序打开的fd指向原来的iNode,而MV操作并不会改变这个inode,因此对正在运行的程序不会产生影响。
 
21、

 

 

 

推荐阅读