腾讯的面试题(很有科技含量)

原文地址:http://gc063tzf.blog.163.com/blog/static/112162922008101611184793/

 

昨天同学发过来一道思考题(下面的第1题),令我受益良多。

1、1000瓶药水,其中至多有1瓶剧毒,现在给你10只小狗在24小时内通过小狗试药的方式找出哪瓶药有毒或者全部无毒(小狗服完药20小时后才能判断是否中毒)。

下面的2-8题仅作存档用,没有仔细研究。

2、找规律填字母

   Z H A

   M E ( )

  A. K

   B. Y

   C. B

   D. W

3、网站上的媒体资源(图片、音频、视频等)很容易被盗链,相对比较安全的防范措施是:()

   A.检查refer

   B.为资源文件添加数字签名

   C.添加基于session的判断

   D.以上说法都正确

4、使用视频软件进行聊天时,视频数据几乎都通过udp协议传输。关于udp协议,下列说法错误的是______

   A.数据通过udp协议传输存在丢包的可能,安全性不如tcp协议

   B.udp协议传输执行速度比tcp快

   C.udp协议的数据传输是无序的,tcp协议的数据传输是有序的。

   D.视频、聊天、邮件等数据的传输都可以使用udp协议。

5、局域网甲内的主机A开启了p2p下载工具(如bt,emule等),他如何同局域网乙中的主机B建立连接______

   A.通过主机B的内网ip建立连接

   B.通过主机B的物理地址建立连接

   C.通过NAT穿越技术建立连接

   D.无法建立连接

6、Windows将遵循下面的那种搜索来定位DLL()

   1.进程的当前工作目录

   2.包含EXE文件的目录

   3.列在Path环境变量中的一系列目录

   4.Windows系统目录

   5.Windows目录

  A 12453 B 12543 C 21453 D 21345

7、设有一个递归算法如下

   int x(int n)

   {

   if(n <=3) return 1;

   else return x(n-2)+x(n-4)+1;

   }

  试问计算x(x(8))时需要计算______次x函数。

  至少列举5种windows下进程间通讯的方式

8、不用中间变量,实现strlen函数。(strlen为C语言中求给字符串长度库函数)

   int strlen(const char *str)

-=================================================================-

由于同学发过来的是第1题,所以其他的我也就没仔细看,不过即使仔细看了肯定也等于白看。

在没找答案之前,老王进行了一段分析。因为以前也见到过类似的考题,它们无一例外地有一个绝妙的答案,所以我想这个也是这样。

由题可知:由于20小时后才能知道小狗是否中毒,而且中毒的时间其实是无法精确到某一具体时间点或较短时间段的,所以每隔一段时间给狗吃药,根据20小时后记录小狗的发病时间来推算有毒药水的方法被我直接否定。而且其他所有拿细分时间段做文章的解题思路也一并摒弃。

因为那些方法除了可操作性几乎没有外,还有一种必然出局的理由就是每个人都会想到它,这就无法达到出题者测试应聘者能力的目的。因此,我觉得固守时间段思路的应聘者很难不被淘汰。

确定了思考角度,我所面临的难点就是如何将10只小狗和1000瓶药水建立某种联系,而这种联系还要受24-20=4小时的制约。

我所能想到的是将药水以某种形式交叉混合,然后喂给小狗,最终通过分析中毒小狗的数量和次序来确定有毒药水。

但是思前想后,最终我还是没能理出具体头绪,无奈只好求助于百度了。

找到题目出处很简单,当我看到原帖第6楼网友“OO”回复的答案后,我彻底拜服了,也自此绝了进腾讯等大公司的念想。

-=================================================================-

下面请看网友“OO”的解法:

把狗从0-9编号;

把药水按1-1000编号;

把药水编号按二进制,如果第i位(因为最大1000,所以bit位为0-9)bit位为1,则分给编号为i的狗狗喝;

最后得一二进制数,如果编号为i的狗狗死了,该数的第i bit位为1,该数就是有毒的药水编号。

他说的比较专业,下面我用实例给解析一下:

用 0、1、2、3、4、5、6、7、8、9 给小狗编号;

而药水按1-1000编号;

我们把每瓶药水的编号转换为二进制数,由于2的10次方=1024,所以我们将二进制数定为有10个数位,如:

1=0000000001

13=0000001101

214=0011010110

对二进制转换不熟悉的朋友可以用“开始-程序-附件-计算器-查看-科学型”来轻松转换。

这样转换以后,每个药水编号的二进制数的每一位都分别对应一只小狗;

我们定义每瓶药水要喂给其二进制编号位数为“1”的那位对应的小狗喝;

由于2的10次方=1024>1000,所以这些二进制编号组合都是唯一的;

当我们用不到4小时的时间将1000瓶药水分别喂给相应的小狗喝后,就可以去看看书,上上网,听听歌来打发剩下的20小时;

20小时候,在一个合理的药效发作时间后,我们统计有中毒症状小狗的编号,中毒的定为“1”,正常的定为“0”;

然后依照编号顺序排列,我们就可以得到一个10位的二进制数,而将这个二进制数再转换为十进制数后,这个数值就是有毒的药水的编号了;

例如,最终结果是编号为 2、4、6、7、9 的小狗有中毒症状,我们就将一个十位二进制数的2、4、6、7、9位设为“1”,其余各位设为“0”,即:0010101101;

而0010101101对应的十进制数=173,所以第173瓶药水就是有毒药水!

当然,如果都无毒,10只小狗就会都是活蹦乱跳的。

-=================================================================-

相信通过上面的解释,大家基本上都能理解这个解题思想的过程了吧。

回过头来反思为什么老王没能想出这么具体的解法呢?

最主要的一点还是思想不够活,没能将早就学过的计算机知识应用到实际解题过程中,这也就决定了我和OO等高手之间的差距。

介绍这种解题方法当然不等于没有其他更好的解法,只是我觉得这种解法就是出题者想要达成的目的。

而且在我看来,其他类似时间分块方法的可操作性和实现的科学性,照这个方法也确实是差的太多。

不过有一种现象很有趣,在原帖中,OO在第6楼就发布了他的解法,但下面还有数十上百个回帖在积极地发表和探讨各种漏洞百出的解法。看来人的思维的确很复杂,创新思想和求胜心理使很多人怀疑一个已经很不错的结论。不过我倒觉得适时肯定别人的成果并消化掉对自己的经验积累也很有用。

-=================================================================-

附言:

虽然我没能想出具体的解决方案,但是我很坚定的是不能沿着设时间点试毒的思路走。之所以这样,主要是我觉得,这种思路基本上每个人都能想到。

试想,随便找个人来问,是不是绝大多数人看到题目后最先想到的,都是把 24 - 20 = 4(小时) = 240(分钟) = 14400(秒) 分为1000份,然后每隔14秒给小狗依次试药,等到最后4个小时内观测小狗的中毒时间点呢?

所以,如果答案大家都能想到,也就失去了题目考察应聘者综合能力的效果。

于是,当看到“OO”的答案时,我才有了豁然开朗的感觉。

2。

找规律填字母

Z  H  A

M  E  (W)

A. K

B. Y

C. B

D. W

网站上的媒体资源(图片、音频、视频等)很容易被盗链,相对比较安全的防范措施是:(D)

A 检查refer

B 为资源文件添加数字签名

C 添加基于session的判断

D 以上说法都正确

使用视频软件进行聊天时,视频数据几乎都通过udp协议传输。关于udp协议,下列说法错误的是______
A 数据通过udp协议传输存在丢包的可能,安全性不如tcp协议
B udp协议传输执行速度比tcp快
C udp协议的数据传输是无序的,tcp协议的数据传输是有序的。
D 视频、聊天、邮件等数据的传输都可以使用udp协议

c

局域网甲内的主机A开启了p2p下载工具(如bt,emule等),他如何同局域网乙中的主机B建立连接______
A 通过主机B的内网ip建立连接
B 通过主机B的物理地址建立连接
C 通过NAT穿越技术建立连接
D 无法建立连接

c

Windows将遵循下面的那种搜索来定位DLL()
1 进程的当前工作目录
2 包含EXE文件的目录
3 列在Path环境变量中的一系列目录
4 Windows系统目录
5 Windows目录

A 12453  B 12543  C 21453  D 21345

c

系统函数:

int strlen (const char * str)

       {

          int length = 0;

          while( *str++ )

                  ++length;

           return( length );

       }

不用中间变量:

int strlen (const char * str)

       {

          if(*str) return strlen(++str)+1;

          return 0;

       }

2 进程通信方法

2.1 文件映射

  文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。

  Win32 API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针。通过使用这些指针,不同进程就可以读或修改文件的内容,实现了对文件中数据的共享。

  应用程序有三种方法来使多个进程共享一个文件映射对象。

  (1)继承:第一个进程建立文件映射对象,它的子进程继承该对象的句柄。

  (2)命名文件映射:第一个进程在建立文件映射对象时可以给该对象指定一个名字(可与文件名不同)。第二个进程可通过这个名字打开此文件映射对象。另外,第一个进程也可以通过一些其它IPC机制(有名管道、邮件槽等)把名字传给第二个进程。

  (3)句柄复制:第一个进程建立文件映射对象,然后通过其它IPC机制(有名管道、邮件槽等)把对象句柄传递给第二个进程。第二个进程复制该句柄就取得对该文件映射对象的访问权限。

  文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步。

2.2 共享内存

  Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用文件映射实现的,所以它也有较好的安全性,也只能运行于同一计算机上的进程之间。

2.3 匿名管道

  管道(Pipe)是一种具有两个端点的通信通道:有一端句柄的进程可以和有另一端句柄的进程通信。管道可以是单向-一端是只读的,另一端点是只写的;也可以是双向的一管道的两端点既可读也可写。

  匿名管道(Anonymous Pipe)是 在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。通常由父进程创建管道,然后由要通信的子进程继承通道的读端点句柄或写 端点句柄,然后实现通信。父进程还可以建立两个或更多个继承匿名管道读和写句柄的子进程。这些子进程可以使用管道直接通信,不需要通过父进程。

  匿名管道是单机上实现子进程标准I/O重定向的有效方法,它不能在网上使用,也不能用于两个不相关的进程之间。

2.4 命名管道

  命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。

  命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。

2.5 邮件槽

  邮件槽(Mailslots)提 供进程间单向通信能力,任何进程都能建立邮件槽成为邮件槽服务器。其它进程,称为邮件槽客户,可以通过邮件槽的名字给邮件槽服务器进程发送消息。进来的消 息一直放在邮件槽中,直到服务器进程读取它为止。一个进程既可以是邮件槽服务器也可以是邮件槽客户,因此可建立多个邮件槽实现进程间的双向通信。

  通过邮件槽可以给本地计算机上的邮件槽、其它计算机上的邮件槽或指定网络区域中所有计算机上有同样名字的邮件槽发送消息。广播通信的消息长度不能超过400字节,非广播消息的长度则受邮件槽服务器指定的最大消息长度的限制。

  邮件槽与命名管道相似,不过它传输数据是通过不可靠的数据报(如TCP/IP协议中的UDP包)完成的,一旦网络发生错误则无法保证消息正确地接收,而命名管道传输数据则是建立在可靠连接基础上的。不过邮件槽有简化的编程接口和给指定网络区域内的所有计算机广播消息的能力,所以邮件槽不失为应用程序发送和接收消息的另一种选择。

2.6 剪贴板

  剪贴板(Clipped Board)实质是Win32 API中一组用来传输数据的函数和消息,为Windows应用程序之间进行数据共享提供了一个中介,Windows已建立的剪切(复制)-粘贴的机制为不同应用程序之间共享不同格式数据提供了一条捷径。当用户在应用程序中执行剪切或复制操作时,应用程序把选取的数据用一种或多种格式放在剪贴板上。然后任何其它应用程序都可以从剪贴板上拾取数据,从给定格式中选择适合自己的格式。

  剪贴板是一个非常松散的交换媒介,可以支持任何数据格式,每一格式由一无符号整数标识,对标准(预定义)剪贴板格式,该值是Win32 API定义的常量;对非标准格式可以使用Register Clipboard Format函数注册为新的剪贴板格式。利用剪贴板进行交换的数据只需在数据格式上一致或都可以转化为某种格式就行。但剪贴板只能在基于Windows的程序中使用,不能在网络上使用。

2.7 动态数据交换

  动态数据交换(DDE)是使用共享内存在应用程序之间进行数据交换的一种进程间通信形式。应用程序可以使用DDE进行一次性数据传输,也可以当出现新数据时,通过发送更新值在应用程序间动态交换数据。

  DDE和剪贴板一样既支持标准数据格式(如文本、位图等),又可以支持自己定义的数据格式。但它们的数据传输机制却不同,一个明显区别是剪贴板操作几乎总是用作对用户指定操作的一次性应答-如从菜单中选择Paste命令。尽管DDE也可以由用户启动,但它继续发挥作用一般不必用户进一步干预。DDE有三种数据交换方式:

  (1) 冷链:数据交换是一次性数据传输,与剪贴板相同。

  (2) 温链:当数据交换时服务器通知客户,然后客户必须请求新的数据。

  (3) 热链:当数据交换时服务器自动给客户发送数据。

  DDE交换可以发生在单机或网络中不同计算机的应用程序之间。开发者还可以定义定制的DDE数据格式进行应用程序之间特别目的IPC,它们有更紧密耦合的通信要求。大多数基于Windows的应用程序都支持DDE。

2.8 对象连接与嵌入

  应用程序利用对象连接与嵌入(OLE)技术管理复合文档(由多种数据格式组成的文档),OLE提供使某应用程序更容易调用其它应用程序进行数据编辑的服务。例如,OLE支持的字处理器可以嵌套电子表格,当用户要编辑电子表格时OLE库可自动启动电子表格编辑器。当用户退出电子表格编辑器时,该表格已在原始字处理器文档中得到更新。在这里电子表格编辑器变成了字处理器的扩展,而如果使用DDE,用户要显式地启动电子表格编辑器。

  同DDE技术相同,大多数基于Windows的应用程序都支持OLE技术。

2.9 动态连接库

  Win32动态连接库(DLL)中的全局数据可以被调用DLL的所有进程共享,这就又给进程间通信开辟了一条新的途径,当然访问时要注意同步问题。

  虽然可以通过DLL进行进程间数据共享,但从数据安全的角度考虑,我们并不提倡这种方法,使用带有访问权限控制的共享内存的方法更好一些。

2.10 远程过程调用

  Win32 API提供的远程过程调用(RPC)使应用程序可以使用远程调用函数,这使在网络上用RPC进行进程通信就像函数调用那样简单。RPC既可以在单机不同进程间使用也可以在网络中使用。

  由于Win32 API提供的RPC服从OSF-DCE(Open Software Foundation Distributed Computing Environment)标准。所以通过Win32 API编写的RPC应用程序能与其它操作系统上支持DEC的RPC应用程序通信。使用RPC开发者可以建立高性能、紧密耦合的分布式应用程序。

2.11 NetBios函数

  Win32 API提供NetBios函数用于处理低级网络控制,这主要是为IBM NetBios系统编写与Windows的接口。除非那些有特殊低级网络功能要求的应用程序,其它应用程序最好不要使用NetBios函数来进行进程间通信。

2.12 Sockets

  Windows Sockets规范是以U.C.Berkeley大学BSD UNIX中流行的Socket接口为范例定义的一套Windows下的网络编程接口。除了Berkeley Socket原有的库函数以外,还扩展了一组针对Windows的函数,使程序员可以充分利用Windows的消息机制进行编程。

  现在通过Sockets实现进程通信的网络应用越来越多,这主要的原因是Sockets的跨平台性要比其它IPC机制好得多,另外WinSock 2.0不仅支持TCP/IP协议,而且还支持其它协议(如IPX)。Sockets的唯一缺点是它支持的是底层通信操作,这使得在单机的进程间进行简单数据传递不太方便,这时使用下面将介绍的WM_COPYDATA消息将更合适些。

2.13 WM_COPYDATA消息

  WM_COPYDATA是一种非常强大却鲜为人知的消息。当一个应用向另一个应用传送数据时,发送方只需使用调用SendMessage函数,参数是目的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了数据共享。

  WM_COPYDATA是一种非常简单的方法,它在底层实际上是通过文件映射来实现的。它的缺点是灵活性不高,并且它只能用于Windows平台的单机环境下。

第二个问题,我的答案是k,思路是z、e、a的字母顺序加起来是32,m、h、k加起来也是32。

你可能感兴趣的:(windows,面试,网络,服务器,腾讯,Sockets)