1.如何判断单链表有环?
设置两个指针互相追逐。一个指针每次前进一步,第二个指针每次前进两步,如果有相遇,则说明有环。
2.值为1到99的100个数中有两个数是重复元素,设计算法找出这两个数?
先求和1+2+...+99=x,然后用你的100个数字求和,减去这里的x,就得到了重复的那个数。
3.对Linux系统的用户态和内核态了解吗?系统调用的整个过程是什么?
可以把Linux 系统看成一个环状结构,最里面的是硬件(CPU,磁盘,网卡等),Linux 系统给这些硬件注入了灵魂,让这些硬件可以按指令运行起来。硬件的上一层就是驱动层,它属于Linux内核,然后内存管理器,文件系统等就可以通过驱动运行最底层的硬件。内核中指挥硬件如何操作的叫系统调用,由于它偏向于底层,所以只需要向外层暴露接口就可以了(隐藏了具体实现的细节),用户态的程序只需要调用接口,就可以切换到内核态,该模式下的CPU指令变为特权指令,可以执行某些关键操作。系统调用是原子的操作,如果某个操作比较复杂,需要好多原子的操作,那么就可以将其封装称库函数,让用户态程序调用。当一个程序执行系统调用而进入内核代码中执行时,该进程就处于内核态,此时CPU处于特权最高的内核代码中执行。
(CPU有很多重要的指令,如清空内存,new一个进程,磁盘操作等,这些必须要有非常高的特权太能够执行。所以,CPU将指令分为特权指令和非特权指令,对于那些非常重要的指令,只允许操作系统及其相关模块使用,普通的应用程序只能使用那些不会造成灾难的指令(ring0特权指令,ring3非特权指令)。
4.死锁产生的条件?
互斥,请求并保持条件,非抢占,循环等待
5.数据库三范式是什么?
数据库范式代表关系模式设计的不同级别,好比装修房子,有裸装,普通装和豪华装。
数据库的范式越高,说明表的设计越精良。
第一范式:关系模式中的每个属性都不能再细分了(原子性)。通常数据库表都满足第一范式。
第二范式:2NF在1NF的基础上,消除了非主属性对码的部分函数依赖。
先要理解几个重要的概念
码:设K为某表中的一个属性或属性组,如除K之外的所有属性都完全函数依赖于K,则称K 为码
主属性:码中的每个属性都是主属性
非主属性:除码以外的属性都是非主属性
函数依赖:y=f(x),x的值能唯一确定y的值。
完全函数依赖 :<X,Y>----->Z 必须要x和y一起,才能推出z
部分函数依赖 :<X,Y>----->Z z并不是完全依赖的,X ----->Z
传递函数依赖 :若X---->Y,Y----->Z,那么X----->Z
若存在非主属性对码的部分函数依赖,则不满足2NF的要求,那要怎么办呢?
模式分解,将大数据表拆分成两个或者更多的小数据表
第三范式:3NF在2NF的基础上,消除了非主属性对码的传递函数依赖。
(学号,姓名,系名,系主任)
学号------>系名,系名------>系主任,那么学号----->系主任
必须消除这种传递函数依赖,才能满足第三范式,怎么做呢?
继续模式分解,将表继续拆分。
5.BigInteger:可以保存任意长度的整数
public class Main {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
BigInteger m=scan.nextBigInteger();
BigInteger n=BigInteger.valueOf(1);
System.out.println(m.add(n));
}
}
BigDecimal:java的float,double只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。
6.正则表达式\s
表示匹配任何空白字符,+
表示匹配一次或多次
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
String str=scan.nextLine();
String[] words=str.trim().split("\\s+");
StringBuffer sb=new StringBuffer();
for(int i=words.length-1;i>=0;i--){
sb.append(words[i].trim()+" ");
}
System.out.println(sb.toString());
}