从谷歌面试题中反思基础教育人才培养

某天一大早肖同学就拿着一本厚厚的《c++3D游戏编程》书来找我,想要在运动会期间让我开一个机房,他想自学。肖同学一向对编程很感兴趣。但是这次被我一口拒绝了,我随手一翻,就是矩阵运算、欧拉公式等等,好高骛远不行,必须要脚踏地,一步步来,高三了当然必须要先进一个211再说。必须要有良好的数学素养、扎实的语言功底、一流的沟通能力与好的思维品质。

如何面向未来10年培养人,因个人水平非常有限。我们通过一道题一起来看看,全球500强的企业需要我们培养什么样的人才。

一、背景

谷歌是全球最大的IT公司之一,一直通过不拘一格的方式来解决一些问题。2004年的招聘题居然在101号公路的广告牌上,101号公路是硅谷的动脉,因为这条路边全部是大家耳熟能详的各种科技巨头,2004年那时候的巨头包括Adobe,微软,思科,甲骨文,Yahoo,eBay,太阳微电脑等等。

我们一起来看看霸气十足的招聘第一关的题目吧?谷歌2004年的年薪当时在20-100万美金。这是第一关,有趣、霸气、灵感十足。

翻译一下:{e的连续数字中最先出现的10位质数}.com,拿中国人的思维来说太张扬了,但可以看出谷歌求贤若渴,有趣,创意的做事方式,解出这道题才能登录网站。该题目上过时代周刊。

二、大素数的判定

   有时候我们想快速的知道一个数是不是素数,而这个数又特别的大导致 O(开根号n ) 的算法不能通过,这时候我们可以对其进行 Miller-Rabin 素数测试,可以大概率测出其是否为素数。

1、两个基本定理

(1)费马小定理:当 p 为质数,有 a^{p-1}Ξ 1(mod , p),不过反过来不一定成立,也就是说,如果 a , p 互质,且 a^{p-1}Ξ 1(mod , p),不能推出 p 是质数。

  我们来算两个数试试:

  3100 Ξ  mod 17)  用费马小定理: 17为质数,3与17互质,ok, 3100 =316 *316*316*316*316*316*34  由费马小定理可得316Ξ1(mod 17) ∴3100Ξ34 mod 17)   最终等于13。

  第二个:3110 Ξ  mod 17)   3112/32mod 17)Ξ1/32mod 17) 这里的1相当于18任何数被17取模余1,18是其中之一。即2为本题结果

(2)二次探测:如果  是一个素数,0<x<p, 则方程x2Ξ1(mod p)的解为x=1 或 x=p-1

 证明:x2Ξ1(mod p) =>  x2-1Ξ0(mod p)  =>(x+1)(x-1)Ξ0(mod p)  =>x=1或如果p为质数则x=p-1

证明如下:

 2、算法的基本流程

1)对于偶数和 0,1,2 可以直接判断。

2)设要测试的数为 x,我们取一个较小的质数 a,设 s,t,满足 2^s.t=x-1(其中 t 是奇数)。

3)我们先算出 a^t,然后不断地平方并且进行二次探测(进行 s 次),并且还要对X取模。要么等于1,要么等于x-1这两种情况是返回真的,即为质数

4)最后我们根据费马小定律,如果最后 a^{x-1}≠1(mod , x),则说明 x 为合数。

5)多次取不同的 a 进行 Miller-Rabin 素数测试,这样可以使正确性更高

注意点:

1)我们可以多选择几个 a,如果全部通过,那么 x 大概率是质数。

2)Miller-Rabin 素数测试中,“大概率”意味着概率非常大,基本上可以放心使用。

3)当 a 取遍小等于 30 的所有素数时,可以证明 int 范围内的数不会出错。

4)代码中我用的 int 类型,不过实际上 Miller-Rabin 素数测试可以承受更大的范围。

5)另外,如果是求一个 long long 类型的平方,可能会爆掉,因此有时我们要用“快速积”,不能直接乘。

3、万能的python登场

e='''271828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750'''

e=e.replace(" ","")

n=len(e)

prime=[2,3,5,7,11,13,17,19,23,29]

from random import randrange

def miller_rabin(n, k=10):

if n == 2:

return True

if not n & 1:

return False

 def check(a, s, d, n):

x = pow(a, d, n)

if x == 1:       #小费马定理结论

return True

for i in range(s - 1):

if x == n - 1:

return True

x = pow(x, 2, n)  #再次平方取余

return x == n - 1     #二次探测定理中n-1为一个解,为n-1时为正

 s = 0

d = n - 1

while d % 2 == 0:     #计算出s测试的次数,2^s*d

d >>= 1

s += 1

 for i in range(k):

a = prime[i]    #前面十个素质都试过,保证没问题

if not check(a, s, d, n):

return False  #如果有一个有问题就全为假

return True

for i  in range(0,n-9):

    num=int(e[i:i+10])

    if miller_rabin(num):

        print(str(i)+": "+str(num))

答案是:

 就是7427466391.com

 三、回顾

一个问题从开始要解决,需要用到小费尔马定理,通过上述两个小题,定理并不难,从上面可以看出数学基础很重要,但是不死做题,从定理化为代码涉及要语言与基本的数据处理技巧。题目重发现,从另一个侧面可以看出,谷歌招什么样的人?有趣、灵活、对问题乐于钻研、对问题求解着迷、个性张扬的人。首先还是要脚踏实地,如果一群小孩本身学习能力不强,我们还提高考学难度与思维广度,这是对牛弹琴,也无形中制造了差生,大多数学生接受不了的东西,讲了也没意思。其次,对于感兴趣的学生可以点拔点拔,看看其悟性如何,最关键作为老师本身,要脚踏实地刷题,刷题,再刷题,还要不间断的带学生。本人水平有限,认识也不一定到位,相信诸位一定对这道霸气的题有更深入的感想。

原文地址:https://www.cnblogs.com/macren/p/13951001.html