**
1. 冒泡排序的优化算法
**
(1) 冒泡排序的基础算法有哪些缺点?
答:每一趟比较都要比较到数组的最后,没有必要,只要比较到无序数列即可。
package bubbleproject;
import java.util.Arrays;
public class Bubble {
public static void main(String[] args) {
int[] array = { 52, 14, 75, 23, 9 };
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
}
(2) 可以从哪几个方面来对基础算法进行优化?
1.可以从内层循环的判断次数,不用去比较已经排好序的数字。
2.可以从定义变量来优化,在使用交换时,可以用异或来执行交换,不用在去声明第三遍量。
3.可以定义一个boolean类型的变量,用来判断每次循环之后是否有序,进入循环之间默认有序。
package bubbleproject;
import java.util.Arrays;
public class Bubble2 {
public static void main(String[] args) {
int[] array = {52,14,75,23,9};
int temp = 0;
boolean flag;//判断数组是否有序
for(int i = 0;i<array.length-1;i++) {
flag = true; //每次默认为有序
for (int j = 0; j < array.length-1-i; j++) {
if(array[j]>array[j+1]) {
array[j] = array[j]^array[j+1];
array[j+1] = array[j]^array[j+1];
array[j] = array[j]^array[j+1];
flag = false;//如果发生交换,则是无序
}
}
if(flag) { //如果有序,则停止判断
return ;
}
}
System.out.println(Arrays.toString(array));
}
}
**
2. 二分法
(1) 折半查找算法的原理是什么?
答:一组按升序排好顺序的数字,先查找中间的数字是否与需要查找的数字匹配,如果中间的数字大于所查找的数字,则舍弃大于该中间数字后面的数字,在小于它的前面的数字中去查找。如果中间的数字小于所查找的数字,则舍弃小于该中间数字前面的数字,在大于它的后面的数字中去查找。反复该过程。
(2) 简述如何进行折半查找?
答:先对数组进行排序,并且是升序排序。然后查找数组中间的数字,进行比较,如果中间的数字大于所查找的数字,将高位设置为中间数字索引-1,如果中间的数字小于所查找的数字,则将低位设置为中间数字索引+1,如果中间数字等于所查找的数字,则返回该下标的索引。如果找不到该数字,则返回-插入点-1.
package binarysearchproject;
public class BinarySearch {
public static void main(String[] args) {
int[] array = { 5, 16, 23, 34, 48, 58, 69, 72, 85 };
int low = 0;
int high = array.length - 1;
int mid = 0;
int num = 57;
boolean flag = false;
while (low <= high) {
mid = (low + high) / 2;
if (array[mid] > num) { //如果中间值大于比较的数
high = mid - 1; //移动高位的位置
} else if (array[mid] < num) { //如果中间值小于比较的数
low = mid + 1; //移动地位的位置
} else {
System.out.println(mid);
flag = true;
break;
}
}
if(!flag) { //如果这个数不在数组中,则打印所对应的-插入点
System.out.println(-low-1);
}
}
}
**
3. 异常概念_分类
**
(1) 什么叫异常?
答:在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序。
(2) 请简述异常的分类?
答:error异常,仅靠程序本身无法恢复的严重错误。 Exception,由java应用程序抛出和处理的非严重错误。Exception异常分为:运行时异常(runtime exception)和Checked异常。
运行时异常(runtime exception),不要求程序必须做处理。
Checked异常,程序必须处理该异常。
**
4. 异常处理方式之一_捕获异常
(1) 捕获异常所使用的关键字有哪些?
答:try、catch、finally
(2) try-catch-finally有几种结合形式,每种组合形式的执行顺序是什么?
1.try-catch组合。先执行try中的程序,当try块中出现了异常,虚拟机创建相应的异常对象,立即将异常传入catch块中进行匹配,如果匹配成功,则执行catch中的语句,然后再执行catch块代码块后面的代码,如果匹配不成功,则中断程序,不执行后面的代码。当try中没有出现异常,则不执行catch块的代码,继续执行catch块以后的代码。
package exceptionproject;
public class TestException {
public static void main(String[] args) {
try {
int a = 10/0; //产生异常,jvm创建异常对象,程序跳到catch,看异常是否匹配
System.out.println("10/0;");
} catch (Exception e) {
e.printStackTrace();
System.out.println("catch");
}
System.out.println("退出");
}
}
2.try-finally组合。先执行try块中的代码,try块有异常或者没有异常finally中的代码都会执行,除非在try块中退出虚拟机(执行System.exit(0);),finally不执行(唯一一种使finally不执行代码的方法)。
package exceptionproject;
public class TestTryFinally {
public static void main(String[] args) {
try {
int sum = 10/1;
System.out.println("10/1="+sum);
System.exit(0); //退出虚拟机,finally唯一一种不执行finally的情况
} finally {
System.out.println("finally中的代码");
}
System.out.println("程序结束");
}
}
3.try-catch-finally,先执行try块中的代码,不发生异常使,执行try中和finally中的代码,不执行catch中的代码,发生异常使且异常类型匹配,执行try-catch-finally。如果发生异常且类型不匹配,只执行try-finally。如果在try中存在return语句,没有发生异常,则先执行完finally语句中的代码,在回头执行return语句,如果发生异常,执行完finally中的代码后不回头执行return语句。
package exceptionproject;
public class TestTryCatchFinally {
public static void main(String[] args) {
try {
System.out.println("开始");
int sum = 10/1;
System.out.println("10/1");
return ;
} catch (Exception e) {
System.err.println("异常");
System.out.println("获取异常信息的字符串描述:"+e.getMessage());
}finally {
System.out.println("finall y中的代码");
}
}
}
**
5. 异常处理方式之二_声明异常
**
(1) 继承关系中如何声明异常?
-
父类的方法声明了Exception类型的异常,子类在重写方法时,可以声明也可以不声明。但是如果子类重写后的方法使用super关键字调用父类的方法,那么要求必须对异常进行处理。
-
如果父类的方法的没有异常声明,那么子类重写该方法时,如果一定会有Exception或checked异常,要求子类必须自己使用try-catch处理,不然就需要给父类方法加上该异常的声明。
-
如果父类的方法中没有异常声明,那么子类重写该方法时,可以抛出RuntimeException异常。父类不用声明。
package exceptionproject;
import java.io.File;
import java.io.IOException;
public class Father{
public void show() throws Exception{
System.out.println("父类中的show");
}
public void method() {
}
public void method1() {
}
}
class Son extends Father{
@Override
public void show() { //子类重写父类的方法时,父类异常子类可以不做任何处理
//super.show(); 如果子类要调用父类的该方法时,子类必须对该方法做出异常处理
//处理方式有两种,要么就是用try-catch进行捕获,要么用throws向上抛出
}
@Override
public void method() {// throws IOException { 当子类重写父类方法时,父类的该方法没有声明异常,
//子类中的方法有异常需要处理,
//该异常只能由子类自己处理。不能往外抛出异常,
//不然必须给父类的方法也添加该异常方可抛出
File file = new File("C:\\file.txt");
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void method1() throws RuntimeException{
//当子类重写父类方法时,子类可以抛出RuntimeException异常,父类可以没有该异常的声明
}
}
(2) throw与throws的区别是什么?
-
throws用于声明方法可能会产生的异常类型。throw是手动抛出异常对象。
-
throws是写在方法名的后面,throw是写在方法的内部。
**
6. 常见简单异常的解决办法
(1) 请你列举出五个常见的运行时异常?
算术异常(ArithmeticException)
空指针异常(NullPointException)
类型转换异常(ClassCastException)
数组下标越界异常(ArrayIndexOutOfboundsException)
期望的数据类型与实际输入类型不匹配(InputMisMatchException)
public class TestRuntimeException {
public static void main(String[] args) {
int b = 0; //算术异常
int a = 5;
if(b == 0) {
System.out.println("除数不能为零!");
}else {
System.out.println(a/b);
}
String str = null;//空指针异常,没有创建对象而调用了对象的属性或方法
if(str!=null)
System.out.println(str.length());
Animal animal = new Dog(); //类型转换异常
if(animal instanceof Cat) {
Cat cat = (Cat)animal;
}
int[] arr = {1,2};//数组下标越界异常
int index = 3;
if(index >=0&&index <arr.length-1) {
System.out.println(arr[index]);
}else {
System.out.println("数组下标越界!");
}
//期望的数据类型与输入的数据类型不匹配
Scanner input = new Scanner(System.in);
// int i = input.nextInt(); //输入非数字符号是会产出异常
if(input.hasNextInt()) {
int i = input.nextInt();
System.out.println(i);
}else {
System.out.println("输入的数据不合法!");
}
}
}
class Animal{
}
class Dog extends Animal{
}
class Cat extends Animal{
}
(2) 请你列举出五个常见的检查时异常?
SQLException
IOException
ParseException
FileNotFoundException
ClassNotFoundException
**
7. 自定义异常
**
(1) 为什么需要自定义异常?
答:在程序中,可能会遇到任何标准异常类都没有充分的描述清楚的异常,这种情况下可以创建自己的异常类。
(2) 自定义异常的步骤是什么?
-
继承Execption或RuntimeException
-
定义构造方法
-
使用异常
**
package MyselfException;
public class SexException extends Exception{
public SexException() {
super();
// TODO Auto-generated constructor stub
}
public SexException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
}
package MyselfException;
import java.util.Scanner;
public class TestSexException {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String gender = input.next();
if("男".equals(gender) || "女".equals(gender)) {
System.out.println("性别正确");
}else {
try {
throw new SexException("性别只能为男或者女");
} catch (SexException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
}
8. 包装类的基本用法
**
(1) 为什么需要包装类?
答:Java并不是纯面向对象的语言。Java语言是一个面向对象的语言,但是java中的基本数据类型却不算面向对象的。但是我们在实际使用中经常需要将基本数据转化成对象,便于操作。比如:集合的操作中,这时,我们就需要将基本数据类型转换为对象。
(2) 包装类的继承关系是什么?
**
9. 自动装箱和拆箱
**
(1) 请你简述什么叫自动装箱?什么叫自动拆箱?
答:自动装箱是将基本数据类型自动地封装到与他相同的类型的包装类中。自动拆箱是将基本数据类型对应的包装类对象自动地转换成基本数据类型。
Integer i = 100; //自动装箱
int j = i; //自动拆箱
(2) 请你简述Integer类中的内部类IntegerCache的作用?
答:Cache为[-128,127],IntegerCache有一个静态的Integer数组,在类加载时就将-128到127的Integer对象创建了,并保存在cache数组中,一旦程序调用valueOf方法,如果取的值时在-128到127之间就直接在cache缓存数组中去取Integer对象,超出范围就new一个对象。
package wrapper;
public class TestAutoboxing {
public static void main(String[] args) {
Integer i = -128;
Integer j = -128;
System.out.println(i == j); //true
Integer i1 = 129;
//相当于 Integer i1 = Integer.valueOf(129);底层可以自动实现
Integer i2 = 129;
System.out.println(i1 == i2);//false
}
}
package wrapper;
public class TestInteger {
public static void main(String[] args) {
Integer i1 = new Integer(123);
Integer i2 = new Integer("123");
int i3 = i1.intValue();//将包装类对象转换为int
int i4 = Integer.parseInt("123");//将字符串转换为int
Integer i5 = Integer.valueOf(123);//将int转换为Interger
String str = i5+"";//将int转换为字符串
Integer i6 = new Integer("345");//字符串转换为Integer
String str1 = i6.toString();//将Integer转换为字符串
}
}