1.简述数据库以及线程死锁产生的原理及必要条件,简述如何避免死锁。(10分)

2.请列举面向对象设计的三个基本要素及五种主要设计原则。(10分)

参考:

三个基本要素:封装、继承、多态。

五个基本原则:

1)单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。

2)开放封闭原则:软件实体对外扩展开放,对修改封闭。

3)里氏替换原则:子类的实例能够替换父类的实例。

4)接口分离原则:采用多个专门的接口比使用单一的总接口要好。一个类对另一个类的依赖性建立在最小的接口上。

5)依赖倒置原则:依赖抽象不要依赖具体实现。 

 

3.简述windows内存管理的几种方式以及优缺点。(10分)

参考:

(1)块式管理。把主存分为一大块、一大块的,当所需的程序片段不在主存时就分配一块主存空间,把程序片段加载到主存,就算所需要的程序片段只有几个字节也只能把这块分配给它。优点:易于管理;缺点:浪费空间。

(2)页式管理。把主存分为一页一页的,每一页的空间要比一块一块的空间小很多,显然这种方式的空间利用率要比块式管理高出很多。

(3)段式管理。把主存分为一段一段的,每一段的空间又要比一页一页的空间小很多,这种方法在空间利用率上比页式管理高出很多,但也有另外一个缺点,一个程序片段可能会被分为几十个段,这样很多时间就会浪费在计算每一段的物理地址上。(I/O操作)

(4)段页式管理。结合了段式管理和页式管理的优点。把主存分为若干页,每一页又分为若干段。

 

1.公司组织一次羽毛球比赛,采用淘汰制,假设公司共有1001个人,如果要评出“公司羽毛球第一高手”的称号,至少需要进行多少场比赛?请简述设计过程,并编写代码模拟比赛过程(语言不限,可以使用伪代码)。(15分)

 

def baidu1():
    pNum = 1001
    total_gNum = 0
    count = 0
    while(pNum > 1):
        gNum = pNum/2         # 此轮比赛的场数,也是参赛后胜出的人数
        direct = pNum%2       # 此轮直接晋级的人数
        pNum = gNum + direct  # 此轮胜出总人数

        count += 1            # 第几轮
        total_gNum += gNum    # 比赛总场数
        print "第 %d 轮,胜出 %d 人" % (count, pNum)

    return total_gNum

# 测试结果
>>> baidu1()
第 1 轮,胜出 501 人
第 2 轮,胜出 251 人
第 3 轮,胜出 126 人
第 4 轮,胜出 63 人
第 5 轮,胜出 32 人
第 6 轮,胜出 16 人
第 7 轮,胜出 8 人
第 8 轮,胜出 4 人
第 9 轮,胜出 2 人
第 10 轮,胜出 1 人
1000
# 至少要进行1000场比赛才能选出最好的选手

 

2.一百个灯泡排成一排,第一轮将所有灯泡打开;第二轮每隔一个灯泡关掉一个,即排在偶数的灯泡都被关掉。第三轮每隔两个灯泡,将开着的灯泡关掉,关掉的灯泡打开。以此类推,第100轮结束的时候,还有几盏灯泡亮着?(15分)

def baidu2():
    l = [0]*100
    for i in range(1,101):
        for j in range(100):
            if (j+1)%i == 0:
                l[j] += 1
    r = []
    count = 0
    for k in range(100):
        if l[k]%2 != 0 :
            r.append(k+1)
            count +=  1

    return r, count

# 测试结果 >>> baidu2() ([1, 4, 9, 16, 25, 36, 49, 64, 81, 100], 10)

 

3.k近邻方法(k nearest neighbor)是常用的分类算法之一,给定训练数据集D=(xi,yi),i=1…n,其中xi∈Rp是一个p维实数空间中的向量,yi∈{0,1}是xi对应的类标。(15分)

①给定一个待分类样例x∈Rp,要求获得他的预测分类y∈{0,1}。请写出k邻近分类算法。

②给定一个变长的p维的立方体,训练数据D均匀的在立方体内,待预测样例x∈Rp是位于原点o。近似的,我们认为位于原点边长为l的p维立方体内的样本均为邻近,如下图所示。如果我们希望选所有数据中r(0<r<1)比例的点计算点k近邻,那么边长l应为多少? l^p = r --> l = logp(r)

 

③接第二问,当p=10时,分别取r=0.01和r=0.1的情况下边长l分别等于多少?通过分析l的取值以及l随p变化的趋势,试简略解释机器学习中的维数灾难问题,(参考数据:10-0.1=0.794; 10-0.2=0.631; 10-0.3=0.501; 10-0.4=0.398)r = 0.01, l10 = 0.01, l = 10-0.2=0.631;     

④简要描述一种解决维灾的方法。

如何避免“维数灾难”?图1显示了分类器的性能随着特征个数的变化不断增加,过了某一个值后,性能不升反降。这里的某一个值到底是多少呢?目前,还没有方法来确定分类问题中的这个阈值是多少,这依赖于训练样本的数量,决策边界的复杂性以及分类器的类型。理论上,如果训练样本的数量无限大,那么就不会存在“维数灾难”,我们可以采用任意多的特征来训练分类器。事实上,训练样本的数量是有限的,所以不应该采用过多的特征。此外,那些需要精确的非线性决策边界的分类器,比如neural network,knn,decision trees等的泛化能力往往并不是很好,更容易发生过拟合问题。因此,在设计这些分类器时应当慎重考虑特征的数量。相反,那些泛化能力较好的分类器,比如naive Bayesian,linear classifier等,可以适当增加特征的数量。

如果给定了N个特征,我们该如何从中选出M个最优的特征?最简单粗暴的方法是尝试所有特征的组合,从中挑出M个最优的特征。事实上,这是非常花时间的,或者说不可行的。其实,已经有许多特征选择算法(feature selection algorithms)来帮助我们确定特征的数量以及选择特征。此外,还有许多特征抽取方法(feature extraction methods),比如PCA等。交叉验证(cross-validation)也常常被用于检测与避免过拟合问题。

还有正则,SVD奇异值分解