这个是抄的,写这篇文章的目的也是为了自己复习
一、Java 基础备份
1. 一个 .Java 源文件中是否可以包含多个类? 有什么限制?
可以有多个类,但是只能有一个类,并且 public 的类名必须与文件名一致
2. Java 有没有 goto ?
goto 和 const 是 Java 中的保留字,现在没有在 Java 中使用。
3. 说一下 & 和 && 的区别?
& 和 && 都可以用作逻辑与的运算符,表示逻辑与,当运算符两边的表达式的结果都为 true 时,整个运算结果才为 true,否则,只要有一方为 false,则结果为 false。
&& 还有短路 的功能,即如果第一个表达式的结果为false,则不再计算第二个表达式。
if(str != null && !str.equal(""))
当str为null时,后面的表达式就不会执行,
& 还可以用作为运算符,当 & 操作符两边的表达式不是 boolean 类型时,& 表示按位与操作,通常用0x0f来与一个整数进行 & 运算,来获取改整数的最低4个 bit 位,
4. 在Java中如何跳出当前的多重嵌套循环?
在Java中,想要跳出多重嵌套循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的 break 语句,即可以跳出外层循环。
ok;
for(int i=0;i<10;i++){
for(int j=0;i<10;j++){
System.out.println("i="+i+",j="+j);
if(j == 5) break ok;
}
}
另外,可以让外层的循环条件表达式的结果可以收到里层循环的代码的控制。
在二维数组中查找某个数字
int arr[][] = {{1,2,3},{4,5,6},{7,8,9}};
boolean found = false;
for(int i=0;i<arr.length && !found;i++){
for(int j=0;j<arr[i].length;j++){
System.out.println("i="+i+",j="+j);
if(arr[i][j] == 5){
found = true;
break;
}
}
}
5. switch 语句能否作用在 byte 上?能否作用在 long 上?能否作用在 String 上?
在 switch(exprl) 中,exprl 只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是 int 基本数据类型或者是 Integer 包装类型,由于 byte、short、char 都可以隐含转换为 int,所以这些类型以及这些类型的包装类型也是可以的。显然, long、double、folat、boolean 都不符合 switch 的要求,值得注意的是: 在 JDK1.7 之后,switch 是支持 String 类型的。
String str="c";
switch(str){
case "a":System.out.println("a");break;
case "b":System.out.println("b");break;
case "c":System.out.println("c");break;
default :System.out.println("请输入正确的字母");
}
6. short s1 = 1; s1 = s1 + 1;有什么错?short s1 =1;s1 += 1;有什么错?
对于 short s1 = 1; s1 = s1 + 1; 由于 s1 + 1 运算时会自动的转换成 int 类型,再复制给 short类型的 s1 时,编译器会报告需要强制类型转换的错误。
对于 short s1 = 1; s1 += 1; 由于 += 是Java语言规定的运算符, 是会自动的进行数据类型的转换,因此可以正确的解释。
7. char 类型变量中能不能储存一个中文汉字?为什么?
char 类型变量的用来存储 Unicode 编码的字符, Unicode 编码字符集中包含了汉字,所以 char 类型中当然可以存储汉字。 Unicode 编码占用两个字节,所以 char 类型的变量也是占用两个字节。
8. 用最有效率的方法算出 2 乘以 8 等于几?
2 << 3
因为将一个数左移 n 位,就相当于乘以了 2 的 n 次方,那么一个数乘以 8 ,只要将其左移 3 位就可以了。而且位运算是 CPU 直接支持的,效率最高。
9. 使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向 的对象中的内容还是可以改变的。
对于下列语句:
final StringBuffer a = new StringBuffer(immutable);
执行如下语句时将报编译器错误
a = new StringBuffer("");
但是,执行如下语句则可以通过编译
a.append("broken");
10. == 与 equals 的区别
= =: 它的作用是判断两个对象的地址是不是相等,即两个对象是不是同一个对象.(基本数据类型 = = 比较的是值,引用类型 = = 比较的是内存地址)
equals: 它的作用也是判断两个对象是否相等,但是一般分为两种情况:
情况1: 类没有覆盖 equals() 方法,则通过 equals() 比较该类的两个对象时,等价于 “= =” 比较这两个对象。
情况2: 类覆盖了 equals() 方法。一般我们都覆盖 equals() 方法来判断两个对象的内容相等,若内容相等,则返回true。
说明: String 中的 equals() 方法是被重写过的,因为 Object 的 equals 方法时比较对象的内存地址,而 String 的 equals 方法比较的是对象的值。
当创建 String 类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,吐过有就把它赋值给当前引用,如果没有就在常量池中重新创建一个String对象。
11. 静态变量和实例变量的区别?
- 在语法定义上的区别: 静态变量前要加 static 关键字,而实例变量前则不用
- 在程序运行时的区别; 实例变量属于某个对象的属性,必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量.静态变量不属于某个实例对象,而是属于类,所以也被称为类变量,只要程序加载了类的字节码,不用创建任何的实例对象,静态变量就会被分配空间,静态变量就可以被使用了。总之,实例变量必须创建对象后才可以通过这个对象来使用,静态变量则可以直接使用类名来使用。
例如: 对于下面扥程序,无论创建多少个实例对象,永远都值分配了一个 staticVar 变量,并且每创建一个实例对象,这个 staticVar 就会加 1 ;但是,每创建一个实例对象,就会分配一个 instanceVar ,即可能分配多个 instanseVar ,并且每个 instanceVar 的值都只自加了 1 次。
public class VariantTest{
public static int staticVar = 0;
public int instanceVar = 0;
public VariantTest(){
staticVar ++;
instanceVar ++;
System.out.println("staticVar="+staticVar+",instabceVar ="+instanceVar);
}
}
12. 是否可以从一个 static 方法内部发出对非 static 方法的调用?
不可以。因为非 static 方法是要与对象关联在一起,必须创建一个对象后,才可以在该对象上进行方法调用,而 static 方法调用时不需要创建对象,可以直接调用,也就是说,当一个 static 方法被调用时,可能还没有创建任何实例对象,所以,一个 static 方法内部不能发出的非 static方法的调用的。
13. Integer 与 int 的区别
int 是 Java 提供的 8 种原始数据类型之一。Java 为每个原始类型提供了封装类,Integer 是 Java 为 int 提供的封装类。int 的默认值为 0。Integer 的默认值是 null。即 Integer 可以区分出未赋值和值为 0 的区别, int 则无法表达出为赋值的情况。另外,Integer 提供了多个与证书相关的操作方法,还定义了表示整数的最大值和最小值的常量。
14. 请说出作用域 public、private、protected 以及不写是的区别
- public: public 表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
- private: private 表示私有,私有的意思就是除了 class 自己之外,任何人都不可以直接使用
- protected: protected对于子女或者是朋友是 public ,可以自由使用,对于其他的类,protected 就是 private
- default: 则是包内包外的子类都可见
15. Overload 和 Override 的区别?Overloaded 是否可以改变返回值的类型?
Overload 是重载的意思,Override 是覆盖的意思,也就是重写
1.) 重载 Overload 表示同一个类中可以有多个名称相同的方法,但这些方法的参数各不相同(即参数个数或类型不同)。
重写 Override 表示子类中的方法可以与父类中的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。
子类覆盖父类的方法时,只能比父类抛出更少的异常,或者是抛出父类抛出的异常的子类异常,因为子类可以解决父类的一些问题,不能比父类有更多的问题。
子类方法的访问权限只能比父类的更大,不能更小,如果父类的方法是 private 类型,那么子类则不存在覆盖的限制,相当于子类中增加了一个全新的方法。
2.) overload 是重载的意思,是指我们可以定义一些名称相同的方法,通过定义不同的输入参数来区分这些方法,然后在调用,JVM 就会根据不同的参数样式,来选择合适的方法执行。在使用重载要注意一下几点:
2.1) 在使用重载时只能通过不同的参数样式。例如: 不同的参数类型,不同的参数顺序
2.2) 不能通过访问权限、返回值类型、抛出的异常进行重载
2.3) 方法的异常类型和数目不会对重载造成影响
2.4) 对于继承来说,如果某一方法在父类中是访问权限是 private ,那么就不能在子类对其进行重载,如果定义的话,也只是定义了一个新的方法,而不会达到重载的效果
16. 构造器 Constructor 是否可被 override ?
1.) 构造器 Constructor 不能被 override ,但是可以被 overload
2.) 使用构造器时需要记住:
2.1) 构造器必须与类同名(如果一个源文件中有多个类,那么构造器必须与公共类同名)
2.2) 每个类可以有一个以上的构造器
2.3) 构造器可以有 0 个、1 个或 1 个以上的参数
2.4) 构造器没有返回值
2.5) 构造器总是伴随着 new 操作一起调用
2.6) 不添加任何构造器会默认有空的构造器
3.) 继承与构造器
3.1) 使用 super 调用父类构造器的语句必须是子类构造器的第一条语句
4.) 为什么加上super?
Java的构造器并不是函数,所以它并不能被继承,这在我们extends的时候写子类的构造器比较常见,及时子类的构造器参数和父类的完全一样,我们也要写 super 就是因为这个原因。
如果子类构造器没有显式的调用父类的构造器,则将自动调用父类的默认(没有参数)的构造器。如果父类没有不带参数的构造器,并且在子类的构造器中又没有显式的调用父类的构造器,则Java编译器将报告错误。
17. 面向对象有哪些特征
17.1 封装
- 定义: 隐藏对象的属性以及实现细节,仅对外公开访问接口,控制外部访问对接口的 访问权限,使对象内部数据及数据操作结合一个整体。
- 目的: 增强对象的安全性以及简化编程,访问者不需要了解内部具体实现,只用通过开放的外部接口,当然对外的接口我们可以设置访问权限,对于封装而言,一个对象所封装的是自己的属性和方法,所以它是不需要依赖其他对象就可以完成自己的操作。
- 好处:
3.1 隐藏信息,实现细节,对外开放接口,并控制接口的访问权限,
3.2 良好的封装能减少代码的耦合,
3.3 专业分工,单一职责原则–每一个类只负责一项任务
17.2 继承
如果两个类的属性,方法相同或相似,我们可以使用继承降低代码的复用。Java中所有的类直接或间接继承于 Object 类, Object 类是所有类的超类
- 特点
1.1 派生类可以拥有超类中非私有的属性和方法,超类中的构造方法派生类也无法继承。
1.2 派生类可以拥有自己的属性和方法
1.3 派生类可以重写超类中的方法,一般这个时候超类的方法不能满足派生类的需求
1.4 Java的继承是单继承,派生类最多只能拥有一个超类
1.5 向上转型 - 缺点
2.1 继承破坏了封装,超类的属性方法对于派生类来说是透明的,这与封装是相背离的
2.2 继承是一种强耦合关系,代码结构中乱用继承会造成牵一发而动全身的后果 - 使用
考虑派生类是否要向上转型
17.3 抽象
抽象是现实的真实反映,Java的抽象主要是抽象类和接口
抽象的好处:
- 把对象的共性抽象起来,使代码编写简单,容易维护
- 定义接口或抽象类规范,所有实现或继承的类或派生类都要遵循这些规范
- 抽象是对现实的真实反映,但有时高度抽象的,是不能被实例化
17.4 多态
不同的类对象对统一消息作出不同的反应
存在条件:
- 必须是继承条件
- 子类重写父类的方法
- 父类引用指向子类对象
分类: - 编译期间: 即同一个类中方法的重载
- 执行期间: 即子类对父类的方法的重写
好处: - 扩充性: 多态对代码有扩充性,增加子类不影响其他子类的执行
- 接口性: 多态是超类对子类提供共同接口,子类根据自己情况进行覆盖或实现
18. Java中实现多态的机制是什么?
靠的是超类或接口定义的引用变量可以指向派生类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法
19. abstract class 和 interface 有什么区别?
- 含有 abstract 修饰符的 class 是为抽象类,abstract 类不能创建实例对象。含有 abstract 方法的类必须定义为 abstract class,abstract class 类中的方法不必是抽象的。 abstract class 类中定义抽象方法必须在具体子类中实现,所以不能有抽象构造方法或抽象静态方法。如果子类没有实现超类中的所有抽象方法,那么子类也必须定义为 abstract 类型。
- 接口( interface )可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为 public abstract 类型,接口中的成员变量类型默认为 public static final。
- 比较两者的语法区别:
3.1) 抽象类可以有构造方法,接口不能有构造方法
3.2) 抽象类中可以有普通成员变量,接口中没有普通成员变量
3.3) 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须是抽象的,不能有非抽象的普通方法。
3.4) 抽象类中的抽象方法的访问类型可以是 public 和 protected;但接口中的抽象方法只能是 public 类型的,并且默认是 public abstract 类型的
3.5) 抽象类中可以包含静态方法,接口中不能包含静态方法
3.6) 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但是借口中定义的变量只能是 public staticfinal 类型,并且默认是 public static final
3.7) 一个趔可以实现多个接口,但只能继承一个抽象类 - 应用上的区别:
4.1) 接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约
4.2) 抽象类在代码实现方面发挥作用,可以实现代码的复用
20. String 和 StringBuffer 的区别
Java 平台提供了两个类: String 和 StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据,这个String 类提供了述职不可改变的字符串。而这个 StringBuffer提供的字符串可以进行修改。
21. 数组有没有 length() 这个方法?String 有没有 length() 这个方法?
数组没有 length() 这个方法,有 length 属性,String 有length() 这个方法
22. final,finally,finalize 的区别
final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承
finally 是异常处理语句结构的一部分,表示总是执行
finalize 是 Object 类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,JVM不保证这个方法总被调用
23. sleep() 和 wait() 有什么区别?
sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,把执行机会给其他线程,但是监控状态依然保持,到时候会自动恢复,sleep就是正在执行的线程主动让出CPU,CPU去执行其他线程,在 sleep 在指定的时间过后,CPU 才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep 并不会释放同步锁,即使当前线程调用了 sleep() 方法让出 CPU,但其他被同步锁挡住了的线程也无法得到执行。
wait() 是Object 类的方法,对此对象调用 wait 方法导致本县城放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出 notify 方法(或 notifyAll) 后本线程才进入对象锁定池准备获得对象锁进入运行状态; wait 就是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了 notify 方法,调用 wait 方法的线程就会解除 wait状态和程序可以再次得到锁后继续向下运行。notify 并不释放锁,只是告诉调用过 wait 方法的线程可以参与获得锁的竞争,但是不是马上得到锁,因为锁还在别人手里。线程死的时候会自己notifyAll,释放掉所有的持有自己对象的锁
24. 同步和异步有何异同?
如果数据将在线程间共享,那么这些数据就是共享数据,必须进行同步存取
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用一部编程,在很多情况下采用异步途径往往更有效率。
25. 多线程有几种实现方法?同步有几种实现方法?
多线程有两种实现方法,分别是继承 Thread 类与实现 Runnable 接口
同步的实现方法有两种,分别是 synchronized ,wait 与 notify
wait(): 使一个线程处于等待状态,并且释放所持有的对象的lock
sleep(): 使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉 InterruptedException异常
notify(): 唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且不是按优先级
notifyAll(): 唤醒所有初入等待状态的线程,注意并不是所有唤醒线程一个对象的锁,而是让它们竞争。
26. 启动一个线程是用 run() 还是 start()?
启动一个线程是调用 start() 方法,使线程就绪状态,以后可以被调度为运行状态,一个线程必须关联一些具体的执行代码,run() 方法是该线程所关联的执行代码
27.当一个线程进入一个对象我的一个 synchronized 方法后,其他线程是否可以进入此对象的其他方法?
分几种情况:
- 其他方法前是否加了 synchronized 关键字,如果没加,则能
- 如果这个方法内部调用了wait,则可以进入其他 synchronized 方法
- 如果其他方法都加了 synchrionized 关键字,且内部没有调用wait,则不能
- 如果其他方法是 static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是 this
28. ArrayList 和 Vector 的区别
- 都实现了List接口,他们都是有序集合,即存储在这两个几个中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,并且其中的元素是允许重复的
- 同步性:
Vector 是线程安全的,也就是说它的方法之间是线程同步的,而 ArrayList 是线程不安全的,它的方法之间是线程不同步的,如果只有一个线程会访问到集合,那最好是使用 ArrayList,因为它不考虑线程安全,效率会高一些,如果有多个线程会访问到集合,那最好是使用 Vector,因为我们不需要去写线程安全的代码 - 数据增长
ArrayList 与 Vector 都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加 ArrayList 与 Vector 的存储空间,每次增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间取得一定的平衡.Vector 默认增长为原来的两倍,ArrayList 从源码上看是增长为原来的1.5倍大小。
29. HashMap 和 HashTable 的区别
HashMap 是 Hashtable 的轻量级实现(非线程安全的实现),它们都实现了 Map 接口,主要区别在于 HashMap 允许空键值,由于非线程安全,在只有一个线程访问的情况下,效率高于 Hashtable。
HashMap 允许将 null 作为一个 entry 的 key或者value,而 Hashtable 不允许
30. List 和 Map 区别
一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List 中存储的数据是有顺序,并且允许重复;Map 中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。
31. Collection 和 Collections的区别
Collection 是集合类的上级接口,继承与他的接口主要有Set 和 List
Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作
32. Set 是怎么去重的?
当添加到 Set 的对象 HashCode 码不相同时,不会调用 equals 方法,对象直接存储进 Set 集合中。
当 HashCode 相同时,才会调用 equals 方法,查看是否是同一个对象,如果是则去除。
33. Java中有几种类型的流?
字节流 和 字符流
字节流继承于 InputStream 和 OutputStream
字符流继承于 InputStreamReader 和 OutputStreamWriter
34. 字节流 和 字符流 的区别
字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为1 个字节,操作字节和字节数组
字节流可以用于任何类型的对象,包括二进制对象,而自毒瘤只能处理字符或者字符串。
35. 序列化 与 反序列化
- 什么是序列化?什么是反序列化?
Java序列化就是指将对象转换为字节序列的过程,反序列化则是指将字节序列转化成目标对象的过程。
有时我们需要将一个Java对像变成字节流的形式传出去或者从一个字节流中恢复成一个Java对象。例如,要将Java对象存储到硬盘或者传送到网络上的其他计算机,这个过程我们可以写代码去把一个Java对象变成某个格式的字节流在传输,但是, JRE 本身就提供了这个支持,我们可以调用OutputStream 的 writedObject 方法来做,如果Java帮我们做的话就,那么要被传输的对象就必须实现 serializable 接口
36. 描述一下 JVM 加载 class 文件的原理机制?
JVM 类中的装载是由 ClassLoader 和它的子类来实现的,Java ClassLoader 是一个重要的Java 运行时系统组件,它负责在运行时查找和装入类文件的类。
37. Linux的常用指令
cd /home 进入 /home 目录
cd … 返回上一级目录
cd …/… 返回上两级目录
cd 进入个人的主目录
pwd 显示工作路径
ls 查看目录中的文件
ls -F 查看目录中文件
ls -L 显示文件和目录的详细资料
ls -a 显示隐藏文件
mkdir dir1 创建一个叫 dir1 目录
mkdir dir2 dir3 同时创建两个目录
rm -f file1 删除一个叫做 file1 的文件
rmdir dir1 删除一个叫做 dir1 目录
rm -rf dir1 删除一个叫做 dir1 的目录并同时删除其内容
mv dir1 dir2 重命名/移动 一个目录
cp file1 file2 复制一个文件
cp dir/*. 复制一个目录下的所有文件到当前工作目录
find / -name file1 从 / 开始进入共文件系统搜索 文件和目录
find / -user user1 搜索属于用户 user1 的文件和目录
find /home.user1 -name *.bin 在目录 /home/user1 中带有 .bin 结尾的文件
tar -xvf 解压文件包
38. 常见的关系型数据库
MySQL、Oracle、SQL Server、SQLite、MariaDB、PostgreSQL
39. 非关系型数据库
Redis、MongoDB、HBase、Noe4j、Cassandra、CouchDB
40. 数据库优化的方式
- 创建索引
- 复合索引
- 索引不会包含有NULL值的列
- 使用短索引
- 排序的索引问题
- like语句操作
- 不要在列上进行运算
- 不使用NOT IN和<>操作
- https://blog.csdn.net/zhangbijun1230/article/details/81608252
41. drop,delete与truncate的区别
- drop
- drop 直接删掉表
- drop 语句将表所战友的空间全释放掉
- drop 语句将删除表的结构被依赖的约束(constrain),触发器(trigger),索引(index);依赖于该表的存储过程/函数将被保留,但是其状态会变为: invalid
- delete
- delete 删除表中数据,可以加 where 子句,加上 where子句是按条件删除,不加上where 是删除掉整个表
- delete 操作不会减少表或索引所占用的空间
- 范围: 可以是 table 和 view
- 只删除数据,而不删除表的结构
- delete 语句为 DML,这个操作会被放到 rollback segment 中,书屋提交之后才会生效,如果有相应的 tigger,执行的时候会被触发
- delete 语句每删除一行,并在事务日志中为所删除的每行记录一项
- truncate
- truncate 删除表中数据,再插入时自增长id又从1 开始,值删除数据而不删除表的结构
- truncate、drop是DDL,操作立即生效,原数据不放到rollback segment中,不能回滚
- truncate table 表名,速度快而且效率高,因为 truncate table 在功能上与不带 where 子句的delete 语句相同,二者均删除表中的全部行。但 truncate table 比 delete速度快,且使用的系统和事务日志资源少
- 对于 foreing key 约束引用的表,不能使用 truncate table
42. union和union all的区别
union 和 union all的用法
1.
union all 是将连接的两个查询结果表连接起来;
union 是将连接的两个查询结果表连接起来并做去重处理
2.
union用的比较多,union all 是直接连接,取得的是所有值,记录可能有重复
union 取得的是唯一值,记录没有重复
3.
union 语法
[sql语句1]
union
[sql语句2]
union all 语法
[]
union all
[]
union 和 union all 关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同
对重复结果的处理:
union在进行表链接后会筛选掉重复的记录;union all 不会
对排序的处理:
union 将会按照字段的顺序进行排序;union all 只是简单的将两个结果合并后就返回
从效率上讲:
union all 要比 union 快很多,所以如果可以确认合并的两个结果集中不包含重复的数据而且不需要排序时的话,那么就使用 union all
43. 数据库的并集、差集、交集
并集
- union 形成并集
union 可以对两个或多个结果集进行连接,形成“并集”
子结果集所有的记录组合在一起形成一个新的结果集 - 限定条件
- 子结果集要具有相同的结构
- 子结果集的列数必须相同
- 子结果集对应的数据类型必须可以兼容
- 每个子结果集不能包含 order by 和 compute子句
- 语法形式
select name from table1
union
select name from table2
差集
- except形成差集
except 可以对两个或多个结果集进行连接,形成“差集”
返回左边结果集合中已经有的记录,而右边结果集合中没有的记录 - 限定条件
- 子结果集要具有相同结构
- 子结果集的列数必须相同
- 子结果集对应的数据类型必须可以兼容
- 每个子结果集不能包含 order by 和 conpute 子句
- 语法形式
select name from table1
except
select name from table2
并集
inner join可以对两个或多个结果集进行连接,形成“交集”
返回左边结果集和右边结果集中都有的记录
- 限定条件
- 子结果集要具有相同的结构
- 子结果集的列数必须相同
- 子结果集对应的数据类型必须可以兼容
- 每个子结果集不能包含 order by和conpute子句
- 语法形式
select name from table1
join table2
in table2.name = table1.name