解答:(1)轮询调度的原理是每一次把来自用户的请求轮流分配给内部中的服务器,从1开始,直到N(内部服务器个数),然后重新开始循环。只有在当前任务主动放弃CPU控制权的情况下(比如任务挂起),才允许其他任务(包括高优先级的任务)控制CPU。其优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度。但不利于后面的请求及时得到响应。
(2)抢占式调度允许高优先级的任务打断当前执行的任务,抢占CPU的控制权。这有利于后面的高优先级的任务也能及时得到响应。但实现相对较复杂且可能出现低优先级的任务长期得不到调度。
3.列出数据库中常用的锁及其应用场景
解答:数据库中的锁是网络数据库中的一个非常重要的概念,它主要用于多用户环境下保证数据库完整性和一致性。各种大型数据库所采用的锁的基本理论是一致的,但在具体实现上各有差别。目前,大多数数据库管理系统都或多或少具有自我调节、自我管理的功能,因此很多用户实际上不清楚锁的理论和所用数据库中锁的具体实现。在数据库中加锁时,除了可以对不同的资源加锁,还可以使用不同程度的加锁方式,即锁有多种模式,SQLServer中锁模式包括:
1)共享锁
SQLServer中,共享锁用于所有的只读数据操作。共享锁是非独占的,允许多个并发事务读取其锁定的资源。默认情况下,数据被读取后,SQLServer立即释放共享锁。例如,执行查询“SELECT*FROMmy_table”时,首先锁定第一页,读取之后,释放对第一页的锁定,然后锁定第二页。这样,就允许在读操作过程中,修改未被锁定的第一页。但是,事务隔离级别连接选项设置和SELECT语句中的锁定设置都可以改变SQLServer的这种默认设置。例如,“SELECT*FROMmy_tableHOLDLOCK”就要求在整个查询过程中,保持对表的锁定,直到查询完成才释放锁定。
2)修改锁
修改锁在修改操作的初始化阶段用来锁定可能要被修改的资源,这样可以避免使用共享锁造成的死锁现象。因为使用共享锁时,修改数据的操作分为两步,首先获得一个共享锁,读取数据,然后将共享锁升级为独占锁,然后再执行修改操作。这样如果同时有两个或多个事务同时对一个事务申请了共享锁,在修改数据的时候,这些事务都要将共享锁升级为独占锁。这时,这些事务都不会释放共享锁而是一直等待对方释放,这样就造成了死锁。如果一个数据在修改前直接申请修改锁,在数据修改的时候再升级为独占锁,就可以避免死锁。修改锁与共享锁是兼容的,也就是说一个资源用共享锁锁定后,允许再用修改锁锁定。
3)独占锁
独占锁是为修改数据而保留的。它所锁定的资源,其他事务不能读取也不能修改。独占锁不能和其他锁兼容。
4)结构锁
结构锁分为结构修改锁(Sch-M)和结构稳定锁(Sch-S)。执行表定义语言操作时,SQLServer采用Sch-M锁,编译查询时,SQLServer采用Sch-S锁。
5)意向锁
意向锁说明SQLServer有在资源的低层获得共享锁或独占锁的意向。例如,表级的共享意向锁说明事务意图将独占锁释放到表中的页或者行。意向锁又可以分为共享意向锁、独占意向锁和共享式独占意向锁。共享意向锁说明事务意图在共享意向锁所锁定的低层资源上放置共享锁来读取数据。独占意向锁说明事务意图在共享意向锁所锁定的低层资源上放置独占锁来修改数据。共享式独占锁说明事务允许其他事务使用共享锁来读取顶层资源,并意图在该资源低层上放置独占锁。
6)批量修改锁
批量复制数据时使用批量修改锁。可以通过表的TabLock提示或者使用系统存储过程sp_tableoption的“tablelockonbulkload”选项设定批量修改锁。
二、算法设计题1.给定N是一个正整数,求比N大的最小“不重复数”,这里的不重复是指没有两个相等的相邻位,如1102中的11是相等的两个相邻位故不是不重复数,而12301是不重复数。
算法思想:当然最直接的方法是采用暴力法,从N+1开始逐步加1判断是否是不重复数,是就退出循环输出,这种方法一般是不可取的,例如N=11000000,你要一个个的加1要加到12010101,一共循环百万次,每次都要重复判断是否是不重复数,效率极其低下,因此是不可取的。这里我采用的方法是:从N+1的最高位往右开始判断与其次高位是否相等,如果发现相等的(即为重复数)则将次高位加1,注意这里可能进位,如8921―>9021,后面的直接置为010101...形式,如1121―>1201,此时便完成“不重复数”的初步构造,但此时的“不重复数”不一定是真正的不重复的数,因为可能进位后的次高位变为0或进位后变成00,如9921―>10001,此时需要再次循环判断重新构造直至满足条件即可,这种方法循环的次数非常少,我认为不超过3次就能满足条件。