2.0 testNG常见问题

155 阅读7分钟

0、Java数据类型?

0.1)Java数据类型分为基础数据类型与引用数据类型

0.2)基础数据类型:

数值型:整数型:byteshortintlong
       浮点型:floatdouble
字符型:char
布尔型:boolean

0.3)引用数据类型:

类:Class
接口:Interface
数组:Array

1、Java中数组:

1.1)动态定义数组:

int test_int[] = new int[3];
test_int[0] = 10;
test_int[2] = 20;
test_int[3] = 30;

1.2)数组中常用的方法:

Arrays.equals(array1,array2):比较两个数组
Arrays.fill(array1,number):填充数组
Arrays.sort(array1):对数组进行排序

2、Java中的集合:

2.1)Collection(接口)集合下有List集合与Set集合

2.1.1)List(接口)集合有序,元素可以重复

2.1.1.1)List集合实现类:ArrayList、Vector、LinkedList

2.1.2)Set(接口)集合无序,元素不可重复

2.1.2.1)Set集合实现类:HashSet、TreeSet

2.2)Map接口存储一组键值对象,提供key(键)到value(值)映射

3、ArrayList动态数组类:

3.1)ArrayList常用方法

List<String> test = new ArrayList<String>();
test.add("a");      //添加元素方法
test.remove("a");   //移除元素方法
test.clear();       //清除所有元素
test.set(0,"b");    //设置元素到指定位置
test.get(0);        //获取指定位置的元素
test.size();        //获取ArrayList类的大小 

3.2)ArrayList类的遍历

List<String> test = new ArrayList<String>();
test.add("a");
for(int i = 0;i<test.size();i++){
    System.out.println(test.get(i));
}

3.3)ArrayList类特点

3.3.1)底层数据结构是数组,查询快、增删慢

3.3.2)线程不安全,效率高

4、Vector(向量)类:

4.1)Vector常用方法:与ArrayList类一样

List<Interger> test = new Vector<String>();

4.2)Vector类的遍历:与ArrayList类一样

4.3)Vector类特点:

4.3.1)底层数据结构是数组,查询快,增删慢

4.3.2)线程安全,效率底

5、LinkedList链表类:

5.1)LinkedList常用方法:与ArrayList类一样

5.2)LinkedList类的遍历:与ArrayList类一样

5.3)LinkedList类特点

5.3.1)底层数据结构是链表,查询慢,增删快

5.3.2)线程不安全,效率高

6、Set类:

6.1)Set常用方法

Set<String> test = new HashSet<String>();
test.add("a");       //添加元素
test.remove("a");    //移除元素
test.clear();        //清除集合所有元素
test.size();         //集合的大小
test.isEmpty();      //如果集合不包含元素,则返回 true ,否则返回false
test.iterator();     //返回在此集合中的元素上进行迭代的迭代器,遍历集合用
test.contains("a");  //如果集合包含指定的元素,则返回 true,否则返回false

6.2)Set类的遍历

Set<String> test = new HashSet<String>();
Set<String> test = new TreeSet<String>();
test.add("a");
Iterator<String> iterable = test.iterator();
while(iterable.hasNext()){
    System.out.println(iterable.next());
}

6.3)HashSet与TreeSet不同:            

HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key

7、Map接口:

7.1)Map接口常用方法

Map<Integer,String> test1 =new TreeMap<Integer,String>();
Map<Integer,String> test2 =new HashMap<Integer,String>();
test2.put(1,"a");         //添加元素
test2.get(1);             //通过指定key获取value
test2.size();             //获取集合中元素的个数
test2.isEmpty();          //判断集合元素个数是否为0,为0返回true,否则返回false
test2.remove(1);          //删除指定key对应的value
test2.keySet();           //获取集合中所有的key
test2.containsKey(1);     //判断集合中是否包含指定key,包含返回true,否则返回false
test2.containsValue("b"); //判断集合中是否包含指定value,包含返回true,否则返回false

7.2)Map接的遍历

Map<Integer,String> map =new HashMap<Integer,String>();
map.put(1,"a");
Set<Integer> keySet = map.keySet();
Iterator iterator = keySet.iterator();
while(iterator.hasNext()){
    Integer key = (Integer)iterator.next();
    String value = map.get(key);
    System.out.println(value);
}

7.3)TreeMap与HashMap不同:

7.3.1)HashMap通过hashcode对其内容进行快速查找
7.3.2)而TreeMap中所有的元素都保持着某种固定的顺序
7.3.3)如果你需要得到一个有序的结果你就应该使用TreeMap

8、Java中实现线程的方式(线程:计算机中一个任务就是一个进程,一个进程包含多个线程):

8.1)实现Runnable接口,重写run方法

public class Truth implements Runnable{
   @Override
   public void run() {
   }
}

8.2)继承Thread类

public class Truth extends Thread{
   @Override
   public void run() {
   }
}

9、线程常用方法:

9.1)start():启动线程的方法,如果继承Thread类直接调用,

      如果实现Runnable接口则需要先创建Thread类再将Runnable加入Thread类再调用

9.1.1)新建T_1实现Runnable接口,重写run方法

package com.test.exception;
public class T_1 implements Runnable{
   @Override
   public void run() {
       int i = 1;
       while(i<=100){
          System.out.println("执行"+i+"次");
          i++;
       }
   }
}

9.1.2)新建T_2调用start方法,start方法自动调用重写的run方法

package com.test.exception;
public class T_2{
      public static void main(String[] args) {
           T_1 t_1 = new T_1();
           Thread thread = new Thread(t_1);
           thread.start();
      }
}

9.2)Thread.sleep(5000):让线程休眠的方法,单位毫秒。调用sleep方法需要抛出或try/catch线程异常

9.3)join():让主线程进入暂停,等待其他线程完成后才唤醒,从而实现线程同步。调用join方法需要抛出或try/catch线程异常

9.3.1)新建T_1继承Thread类,编写run方法

package com.test.exception;
public class T_1 extends Thread{
    public String name;
    public T_1(String name){
        this.name = name;
    }
    public void run() {
        int i = 1;
        while(i<=100){
          System.out.println(this.name+"执行"+i+"次");
          i++;
        }
    }
}

9.3.2)新建T_2类,构建两个线程:A与B

package com.test.exception;
public class T_2{
    public static void main(String[] args){
         T_1 t_1_1 = new T_1("A");
         T_1 t_1_2 = new T_1("B");
         t_1_1.start();
         try {
             t_1_2.join();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
             t_1_2.start();
    }
}

9.3.3)t_1_2也就是B调用join方法,所以首先要保证B线程执行完,而A线程后执行完

wait(2000):当前线程处于等待状态,单位秒。调用wait方法需要抛出或try/catch线程异常
notify():唤醒当前处于wait与sleep状态的线程
notifyAll():唤醒所有处于wait与sleep状态的线程
interrupt():强制打断线程方法,不建议用

10、线程运行流程状态

10.1)新建或初始状态:如,Thread thread = new Thread();

10.2)就绪或可执行状态:新建线程调用start()方法,线程等待CPU调用即处于就绪状态

10.3)运行状态:线程获取CPU权限开始执行,线程只能从就绪状态进入运行状态

10.4)阻塞状态:因为某种原因放弃CPU使用权,暂停运行,直到线程进入就绪状态后才能机会转到运行状态

10.4.1)等待阻塞:运行的线程执行wait()方法进入等待

10.4.2)同步阻塞:获取的对象加(synchronized)同步锁时,若该同步锁被其他线程占用,则JVM会吧该线程放入“锁池”中

10.4.3)其他阻塞:通过调用线程的sleep()或者join()或发出了I/O请求时,线程会进入到阻塞状态

10.5)死亡状态:线程执行完或因异常退出了run()方法,则线程结束生命周期

11、多线程死锁问题

11.1)线程one和two需要获得资源AB才能执行
11.2)线程one获得资源A等待资源B
11.3)线程two获得资源B等待资源A
11.4)线程one在等资源B,因为线程two已经获得资源B,所以线程one永远无法活得资源A,就出现死锁

12、多线程双缓冲问题

12.1)如:顾客网上买票,需要售票网放出票,顾客才可以买票,售票网未放出票,顾客已经可以买到票,就是多线程双缓冲问题

12.2)多线程双缓冲问题所以加入线程锁(synchronized)

12.3)模拟测试多线程双缓冲买票(代码逻辑测试)

12.3.1)新建容器Container类,编写putTicket与getTicket方法(主要测试同步锁是否起到作用)

package com.test.thread;
public class Container {
     String[] containers = new String[10]; /*票数*/
     int number = 0;
     /*发票方法:一次放出10张票*/
     public synchronized void putTicket(String ticket){
          if(number == 9){
              try {
                 this.wait();
              } catch (InterruptedException e) {
                 e.printStackTrace();
              }
          }
          this.notifyAll();
          containers[number] = ticket;
          number ++;
     }
     /*发票方法:一次取出10张票*/
     public synchronized String getTicket(){
          if(number == 0){
              try {
                 this.wait();
              } catch (InterruptedException e) {
                 e.printStackTrace();
              }
          }
          this.notifyAll();
          String ticket = containers[number];
          number --;
          return ticket;
     }
}

12.3.2)构建测试Urbtx类,模拟售票网,调用putTicket方法

package com.test.thread;
/* 售票网类run方法放票 */
public class Urbtx implements Runnable{
     Container containers = null;
     Urbtx(Container containers){
         this.containers = containers;
     }
     @Override
     public void run() {
         for(int i=0;i<100;i++){
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             containers.putTicket("售票网放出"+i+"张票");
             System.out.println("售票网放出"+i+"张票");
         }
     }
}

12.3.3)构建测试Customer类,模拟顾客,调用getTicket方法

package com.test.thread;
/* 顾客类run方法取票 */
public class Customer implements Runnable{
     Container container = null;
     Customer(Container container){
         this.container = container;
     }
     @Override
     public void run() {
         for(int i=0;i<100;i++){
            try {
                Thread.sleep(1000);
             } catch (InterruptedException e) {
                e.printStackTrace();
             }
             String ticket = container.getTicket();
             System.out.println("顾客取第"+i+"票");
         }
     }
}

12.3.4)构建测试主类Test,运行后查看是否有售票网未发票而顾客已经买票

package com.test.thread;
/* 测试主类 */
public class Test {
    public static void main(String[] args) {
        Container container = new Container();
        Customer customer = new Customer(container);
        Urbtx urbtx = new Urbtx(container);
        Thread customer_Thread = new Thread(customer);
        Thread urbtx_Thread = new Thread(urbtx);
        urbtx_Thread.start();
        customer_Thread.start();
    }
}

13、Java中静态与非静态的区别

13.1)静态方法需要加static如,public static void a1(){}。非静态方法不需要如,public void a1(){}
13.2)静态方法可以通过类名直接调用Test1.a1();。非静态方法通过对象名调用。test1.a1();
13.3)静态变量需要加static如,static String test;。非静态方法不需要如,String test;
13.4)静态通过类加载是全局唯一,任何一次的修改都是全局性影响。非静态方法不是。

14、Java中关键字final

14.1final定义类表示不能被继承如,final class test{}
14.2final定义的变量必须赋值如,final static String test = "test";
14.3final定义的方法不能被重写,final final void getname(){}

15、Java中抽象类与接口的区别

15.1)定义抽象类关键字abstract如,public abstract class Test3 {}。定义接口关键字interface如,public interface Test3 {}

15.2)抽象类中可以有抽象方法与具体实现的方法如:

public abstract class Test3 {
    public abstract void a1();
    public void a2(){
       int i;
    }
}
接口只能由抽象方法如:
public interface Test1 {
     public void a1();
}

15.3)抽象类主要是用来被继承,其方法可以用protected与public修饰。接口只能用public修饰

15.4)继承抽象类只需要重写抽象方法。实现接口需要重写所有方法

15.5)抽象类只能单继承如,public class Test1 extends Test2{}。一个类可以实现多个接口如,public class Test1 implements Test2,Test3{}

16、同步锁:两个人取钱,余额共5000,两人各取钱3000,一人取钱成功,一人则提示:余额不足

16.1)新建取钱的人Person类,编写取钱的getMoney方法

package com.test.thread;
public class Person {
    private String name;
    /* set方法、get方法与构造方法快捷键:Alt+Insert */
    public Person(String name) {
        this.name = name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public double getMoney(Card card,double getbalance){
        if(card.getAccount().equals("123") && card.getPwd().equals("123456")){
             synchronized (card){  /* 锁取钱的动作 */
                  if(card.getBalance() >= getbalance){
                        card.setBalance(card.getBalance()-getbalance);
                        return getbalance;
                  }else{
                        System.out.println("余额不足");
                        return 0;
                  } 
             }
        }else{
             System.out.println("账号或密码错误");
             return 0;
        }
    }
}

16.2)新建卡Card类,并构建卡属性的账号、密码、余额、取钱的人

package com.test.thread;
public class Card {
    private String account;
    private String pwd;
    private Person person;
    private double balance;
    public void setAccount(String account) {
         this.account = account;
    }
    public void setPwd(String pwd) {
         this.pwd = pwd;
    }
    public void setPerson(Person person) {
         this.person = person;
    }
    public void setBalance(double balance) {
         this.balance = balance;
    }
    public String getAccount() {
         return account;
    }
    public String getPwd() {
         return pwd;
    }
    public Person getPerson() {
         return person;
    }
    public double getBalance() {
         return balance;
    }
    public Card(String account, String pwd, Person person, double balance) {
         this.account = account;
         this.pwd = pwd;
         this.person = person;
         this.balance = balance;
    }
}

16.3)新建线程MyRunnable类,每一个人取一次就调一次线程

package com.test.thread;
public class MyRunnable implements Runnable{
    Person person;
    Card card;
    double howMoney;
    public MyRunnable(Person person, Card card, double howMoney) {
         this.person = person;
         this.card = card;
         this.howMoney = howMoney;
    }
    @Override
    public void run() {
         double getMoney = person.getMoney(card,howMoney);
         System.out.println(person.getName()+"取钱"+getMoney);
    }
}

16.4)实现Test类

package com.test.thread;
/* 测试主类 */
public class Test {
    public static void main(String[] args) {
         Person sam = new Person("山姆");
         Person jim = new Person("吉姆");
         //一张卡
         Card card = new Card("123","123456",sam,5000);  
         //取一次就调一次线程
         MyRunnable samMyRunnable = new MyRunnable(sam,card,3000)
         //取一次就调一次线程
         MyRunnable jimMyRunnable = new MyRunnable(jim,card,3000);     
         Thread samThread = new Thread(samMyRunnable);
         Thread jimThread = new Thread(jimMyRunnable);
         samThread.start();
         jimThread.start();
    }
}

17、Java中常见io流(将数据以无序的输入/输出方式传递,所以io流的需要写入对象流的对象要继承Serializable(序列化接口))

17.1)数据类型不同分为字符流(Reader)与字节流(Writer)

17.1.1)BufferedReader:字符字节缓冲输入流,BufferedWriter:字符字节缓冲输出流
17.1.2)InputStreamReader:字符字节转换输入流,BufferedWriter:字符字节转换输出流
17.1.3)FileReader:字符字节文件输入流,FileWriter:字符字节文件输出流

17.2)流向不同分为输入流(InpuStream)与输出流(OutputStream)

17.2.1)FileInpuStream:文件输入流,FileOutputStream:文件输出流
17.2.2)ObjectInpuStream:对象输入流,ObjectOutputStream:对象输出流
17.2.3)ByteArrayInpuStream:字节数组输入流,ByteArrayOutputStream:字节数组输出流

18、io流中常用的方法

18.1)输入流read():是从输入流中读出数据
18.2)输出流write("test"):是从输出流中写入数据
18.3)对象输出流writeObject(test1):写入一个对象
18.4)对象输入流readObject():读出一个对象
18.5close():关闭输入与输出流
18.6)以上方法的调用都要抛出异常

19、io流例子:写入数据到文件

import java.io.*;
public class Test{
  public static void main (String[] args) throws Exception{
      String data[] = {"山姆","李丽"};
      File file1 = new File("D:/笔记/TestNG/1.txt");
      FileWriter fileWriter = new FileWriter(file1);
      BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
      for(int i=0;i<data.length;i++){
          bufferedWriter.write(data[i]);
          bufferedWriter.newLine();
          bufferedWriter.flush();
      }
      bufferedWriter.close();
  }
}

20、io流例子:把A文件里的内容输入到B文件中

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IODemo {
   public static void main(String[] args) throws IOException {
       FileInputStream inp = new FileInputStream("E:\\test\\A.txt");
       byte[] b = new byte[1024];
       int length = inp.read(b);
       String s = new String(b,0,length);
       System.out.println(s);
       inp.close();
        
       FileOutputStream out = new FileOutputStream("E:\\test\\B.txt");
       byte[] b2 = s.getBytes();
       out.write(b2);
       System.out.println("写入成功");
       out.close();
   }   
}

21、UDP协议与TCP/IP协议的不同

21.1)名称不同:UDP协议是用户数据报协议。TCP/IP协议是传输控制协议
21.2)UDP协议以广播形式传播,效率高,安全性低
21.3)TCP/IP协议三次握手过程和四次挥手,效率低,安全性高

22、TCP三次握手过程

22.1)主机A通过向主机B,并告诉主机B两件事:我想要和你通信,你可以用哪个序列号来回应我
22.2)当主机B收到主机A的请求后,也告诉主机A两件事:已经收到你的请求你可以传输数据了,你要用哪个序列号来回应我
22.3)当主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B的数据段,这样3次握手就完成了

23、TCP四次挥手过程

23.1)当主机A完成数据传输后,提出停止连接请求
23.2)主机B收到停止连接请求后对其作出响应,确认这一方向上的TCP连接将关闭
23.3)由主机B再次提出反方向的关闭请求
23.4)主机A对主机B的请求进行确认,将关闭请求,双方向的关闭结束

24、例子:通过服务端开启,客户端可以向服务端发送信息

24.1)新建信息implement类

package com.test.thread;
import java.io.Serializable;
public class Message implements Serializable {
     private String info;
     public void setInfo(String info) {
         this.info = info;
     }
     public String getInfo() {
         return info;
     }
     public Message(String info) {
         this.info = info;
     }
}

24.2)新建服务端Server类

package com.test.thread;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
   public static void main(String[] args) {
      try {
          ServerSocket serverSocket = new ServerSocket(9999);
          System.out.println("Server服务端开启");
          while(true){
                Socket socket = serverSocket.accept();
                InputStream inputStream = socket.getInputStream();
                ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
                Message message = (Message)objectInputStream.readObject();
                System.out.println("Client客户端发出信息:"+message.getInfo());
                Scanner scanner = new Scanner(System.in);
                String content = scanner.nextLine();
                Message reonseMessage = new Message(content);
                OutputStream outputStream = socket.getOutputStream();
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                objectOutputStream.writeObject(reonseMessage);
          }
      } catch (Exception e) {
          e.printStackTrace();
      }
   }
}

24.3)新建客户端Client类

package com.test.thread;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
   public static void main(String[] args) {
      try {
           Socket socket = new Socket("127.0.0.1",9999);
           System.out.println("Client客户端开启");
           while(true){
                Scanner scanner = new Scanner(System.in);
                String content = scanner.nextLine();
                Message message = new Message(content);
                OutputStream outputStream = socket.getOutputStream();
                ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
                objectOutputStream.writeObject(message);

                InputStream inputStream = socket.getInputStream();
                ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
                Message reponseMessage = (Message)objectInputStream.readObject();
                System.out.println("Server服务端:"+reponseMessage.getInfo());
           }
      } catch (Exception e) {
           e.printStackTrace();
      }
   }
}

25、Socket套接字类

25.1)用于客户端连接网络,新建类时需要传入ip地址与端口号,或者端口号。如:

Socket socket = new Socket("127.0.0.1",9999);

25.2)常用方法:需要write写入数据需要先获取输出流

socket.getOutputStream();   //获取输出流
socket.getInputStream();    //获取输入流

25.3)调用以上方法都try/catch异常

26、ServerSocket套接字类

26.1)用于服务端连接网络,新建类时需要端口号。如:

ServerSocket serverSocket = new ServerSocket(9999);

26.2)常用方法:serverSocket.accept();用于结束客户端信息,并返回一个Socket,需要try/catch异常

27、Scanner类

27.1)用于扫描输入文本的类,新建如:

Scanner scanner = new Scanner(System.in);

27.2)常用方法:

scanner.nextInt();    //获取下一个int类型数据
scanner.nextLine();   //获取下一行数据

28、Java中的GUI编程,即图形化编程

28.1)JFrame 类是图形化编程的一个容器

28.2)FlowLayout:流布局,BorderLayout:东西南北中边界布局,GridLayout:网格布局

28.3)继承JFrame 类,将布局传入Panel,将button、TextArea、TextField添加至Panel,Panel添加至当前界面

28.4)例子:

import java.awt.*;
import java.io.*;
public class Test extends Frame {
   public void createF(){
      FlowLayout flowLayout = new FlowLayout(FlowLayout.RIGHT,100,20);
      Panel panel = new Panel(flowLayout);    //中间容器
      Button button = new Button("按钮");//按钮
      Label label = new Label();              //标签
      TextArea textArea = new TextArea();     //文本框
      TextField textField = new TextField();  //单行文本框
      panel.add(label);
      panel.add(textField);
      panel.add(button);

      this.setTitle("窗口");               //窗口名称
      this.setSize(500,300);  //窗口大小
      this.setLocation(500,300);     //窗口位置
      this.setVisible(true);              //窗口可见
      this.add(panel);                    //添加panel到窗口
   }
   public static void main (String[] args){
      Test test = new Test();
      test.createF();
   }
}

29、Java链接MySQL数据库的步骤?

29.1)第一步:注册驱动(只做一次)

29.2)第二步:建立链接(Connection)

29.3)第三步:创建SQL语句(PreparedStatement)

29.4)第四步:执行SQL语句

29.5)第五步:处理执行结果(ResultSet)

29.6)第六步:释放资源

30、Java链接MySQL数据库具体实现?

30.1)新建表

create table student(
    student_id int(10),
    student_name varchar(10));

30.2)项目下新建lib包,包下导入mysql-connector-java-8.0.26.jar并加载到项目

30.3)resources包下新建jdbc.properties文件,如下:

url = jdbc:mysql://localhost:3306/test
use = root
pwd = password

30.4)新建Student类

package com.test.jdbc;
public class Student {
    private int student_id;
    private String student_name;
    public int getStudent_id() {
        return student_id;
    }
    public String getStudent_name() {
        return student_name;
    }
    public void setStudent_id(int student_id) {
        this.student_id = student_id;
    }
    public void setStudent_name(String student_name) {
        this.student_name = student_name;
    }
}

30.5)新建PropertiesUtil类,获取资源类

package com.test.jdbc;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class PropertiesUtil {
   private static PropertiesUtil propertiesUtil = null;
   private Properties properties = null;
   /* 单例模式创建配置类 */
   public static PropertiesUtil getPropertiesUtil(){
      if(null == propertiesUtil){
          propertiesUtil = new PropertiesUtil();
      }
      return propertiesUtil;
   }
   /* 通过构造方法获取到该类需要加载的资源 */
   private PropertiesUtil(){
      properties = new Properties();
      /* class写在方法中返回该类实体 */
      /* getClassLoader()加载类方法,所有类都有该方法 */
      /* getResourceAsStream("path") 获取加载类的资源,path:资源路径,返回输入流 */
      /* 将资源加载到类加载器里,并返回输入流 */
      InputStream inputStream = PropertiesUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
            try {
                 properties.load(inputStream);
            } catch (IOException e) {
                 e.printStackTrace();
            }
   }
   /* 获取类资源对应的值 */
   public String getValue(String key){
      return properties.getProperty(key);
   }
}

30.6)新建JdbcUtil类,关闭、链接数据库

package com.test.jdbc;
import java.sql.*;
public class JdbcUtil {
   private static JdbcUtil jdbcUtil = null;
   private JdbcUtil(){
   }
   public static JdbcUtil getJdbcUtil(){
       if(null == jdbcUtil){
          jdbcUtil = new JdbcUtil();
       }
       return jdbcUtil;
   }
   /* 链接数据库 */
   public Connection getConnection() throws SQLException {
       return DriverManager.getConnection(PropertiesUtil.getPropertiesUtil().getValue("jdbc.url"),
       PropertiesUtil.getPropertiesUtil().getValue("jdbc.use"),
       PropertiesUtil.getPropertiesUtil().getValue("jdbc.pwd"));
   }
   /* Connection类:链接数据库*/
   /* PreparedStatement类:链接数据库成功后,发送SQL语句 */
   /* ResultSet类:返回SQL语句的结果 */
   /* 关闭数据库 */
   public void closeConnection(ResultSet resultSet,PreparedStatement preparedStatement,Connection connection){
       try {
           if(resultSet != null){
                resultSet.close();
           }
       } catch (SQLException e) {
           e.printStackTrace();
       }finally {
           try {
               if(preparedStatement != null){
                   preparedStatement.close();
               }
           } catch (SQLException e) {
               e.printStackTrace();
           }finally {
               try {
                   if(connection != null){
                       connection.close();
                   }
               } catch (SQLException e) {
                       e.printStackTrace();
               }
           }
       }
   }
}

30.7)新建StudentDao类,操作数据库

package com.test.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class StudentDao {
    public static void main(String[] args) {
        StudentDao studentDao = new StudentDao();
        Student student = new Student();
        student.setStudent_id(15);
        student.setStudent_name("jim");
        studentDao.updateStudent(student);
    }
    static{
        try {
        /* forName("com.mysql.jdbc.Driver")要求JVM查找指定类,执行JVM的静态代码 */
        /* 第一步:注册驱动(只做一次) */
            Student.class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    public void selectStudent(int student_id){
        Connection connection = null ;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtil.getJdbcUtil().getConnection();
            StringBuffer stringBuffer = new StringBuffer(" select student_id,student_name from student where student_id = ? ");
            preparedStatement = connection.prepareStatement(stringBuffer.toString());
            preparedStatement.setInt(1,student_id);
            resultSet = preparedStatement.executeQuery();
            while(resultSet.next()){
                Student student = new Student();
                student.setStudent_name(resultSet.getString("student_name"));
                System.out.println("学生的姓名:"+student.getStudent_name());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.getJdbcUtil().closeConnection(resultSet,preparedStatement,connection);
        }
    }
    public int insertStudent(Student student){
        Connection connection = null ;
        PreparedStatement preparedStatement = null;
        int totalRows = 0;
        try {
            connection = JdbcUtil.getJdbcUtil().getConnection();
            StringBuffer stringBuffer = new StringBuffer(" insert into student(student_id,student_name) values(?,?) ");
            preparedStatement = connection.prepareStatement(stringBuffer.toString());
            preparedStatement.setInt(1,student.getStudent_id());
            preparedStatement.setString(2,student.getStudent_name());
            totalRows = preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.getJdbcUtil().closeConnection(null,preparedStatement,connection);
        }
        return totalRows;
    }
    public int deleteStudent(int student_id){
        Connection connection = null ;
        PreparedStatement preparedStatement = null;
        int totalRows = 0;
        try {
            connection = JdbcUtil.getJdbcUtil().getConnection();
            StringBuffer stringBuffer = new StringBuffer(" delete from student where student_id = ? ");
            preparedStatement = connection.prepareStatement(stringBuffer.toString());
            preparedStatement.setInt(1,student_id);
            totalRows = preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.getJdbcUtil().closeConnection(null,preparedStatement,connection);
        }
        return totalRows;
    }
    public int updateStudent(Student student){
        Connection connection = null ;
        PreparedStatement preparedStatement = null;
        int totalRows = 0;
        try {
            connection = JdbcUtil.getJdbcUtil().getConnection();
            StringBuffer stringBuffer = new StringBuffer(" update student set student_name= ? where student_id=? ");
            preparedStatement = connection.prepareStatement(stringBuffer.toString());
            preparedStatement.setString(1,student.getStudent_name());
            preparedStatement.setInt(2,student.getStudent_id());
            totalRows = preparedStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtil.getJdbcUtil().closeConnection(null,preparedStatement,connection);
        }
        return totalRows;
    }
}

31、ResultSet类,PreparedStatement类,Connection类,StringBuffer类?

31.1)ResultSet类:返回SQL语句的结果

31.1.1)新建ResultSet resultSet = null;
31.1.2)常用方法resultSet.close();    //关闭链接

31.2)PreparedStatement类:链接数据库成功后,发送SQL语句

31.2.1)新建PreparedStatement preparedStatement = null;

31.2.2)常用方法

preparedStatement.close();         //关闭链接
preparedStatement.setString();     //设置字符串
preparedStatement.setInt();        //设置int类型数据
preparedStatement.setDate();       //设置时间
preparedStatement.executeQuery();  //执行sql语句
preparedStatement.executeUpdate(); //更新sql语句

31.4)connection类:链接数据库

31.3.1)新建Connection connection = null ;

31.3.2)常用方法

connection.close();                   //关闭链接
connection.prepareStatement("test");  //传入字符串,返回一个prepareStatement

                             

31.5)ResultSet类,PreparedStatement类,Connection类方法需要try/catch异常

31.6)StringBuffer类,stringBuffer.toString();  //转换为字符串,并返回字符串

32、String与StringBuffer的区别与转换?

32.1)String与StringBuffer的区别

32.1.1String为不可变对象,不能修改其值。StringBuffer可变对象,新建StringBuffer sb = new StringBuffer();
32.1.2String需要重新创建对象赋值。StringBuffer通过append方法向其赋值stringBuffer.append(“abc”);
32.1.3StringStringBufferfinal类,不能被继承。

32.2)String与StringBuffer之间转换

StringBuffer sb = new StringBuffer(“abc”);
String s = sb.toString();

                 

33、Java中的反射?

33.1)概念:反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性

33.2)作用:如果我们使用了未完成定义的类,编译就会报错,Java地反射机制可以解决该问题

33.3)例子:

33.3.1)通过类名获取:
Student.class.forName("com.mysql.cj.jdbc.Driver");
33.3.2)通过对象获取: 
Student student = new Student(); 
student.getClass();
33.3.3)通过全类名获取:
String className=" com.test.Student";    
clazz = Class.forName(className)

34、Java中的泛型?

34.1)概念:泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数

34.2)作用:

34.2.1)因为数据类型的一致保证了数据类型安全

34.2.2)因为数据类型的一致清除了数据类型的强制转化,减少了出错的机会

34.2.3)所有的强制转换都是自动和隐式的,提高代码的重用率

34.3)例子:

Map<Integer,String> test = new HashMap<Integer,String> ();

35、Java的特性:继承,封装,多态,抽象

36、Java程序从源文件创建到程序运行要经过两大步骤?

36.1)源文件由编译器编译成字节码

36.2)字节码由java虚拟机解释运行                

37、Java设计模式

37.1)工厂模式:

37.1.1)概念:将对象创建和使用相分离,采用工厂模式,即应用程序将对象的创建及初始化交给工厂对象,spring架构中常用

37.1.2)例子:

XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("config.xml"));

37.2)单例模式:

37.2.1)概念:保证一个类仅有一个实例,并提供一个它的全局访问

37.2.2)例子:保证PropertiesUtil类构造的唯一

public class PropertiesUtil {
    private static PropertiesUtil propertiesUtil = null;
    private Properties properties = null;
    public static PropertiesUtil getPropertiesUtil(){
        if(null == propertiesUtil){
            propertiesUtil = new PropertiesUtil();
        }
        return propertiesUtil;
    }
}

38、Java垃圾回收机制

38.1)Java的内存分配与回收,全部由JVM垃圾回收进程自动完成

38.2)在运行时,Java的实例被存放在堆内存中,当一个对象不再被引用时就会从堆内存中移除,内存空间也会被回收

39、Java数据结构

39.1)存储结构:顺序存储结构和链式存储结构两种
39.2)数据结构:指具有一定逻辑关系的存储结构,并且封装了操作数据元素的集合
39.3)数据结构:线性表:数组:java中对应集合实现,如ArrayList
               链表:java中对应集合实现,如LinkedList
               栈与队列:栈:java中Stack栈类,实现了后进先出,Stack<Integer> st = new Stack<Integer>();
                        队列:java中Queue队列类,实现先进先出,Queue<String> queue = new LinkedList<String>();
               树:二叉搜索树
                   平衡二叉树
                   红黑树
               图:

40、Java中常见算法

40.1)分治法:把一个复杂问题分成两个或更多相同或相似的子问题,再把子问题分成更小的子问题,直到最后子问题可以简单的直接求解,原问题的解即是子问题解的合并
40.2)贪心算法:不从整体最优上加以考虑,仅是在某种意义上局部的最优解
40.3)动态规划算法:解决问题答案依赖当前的状态,随着状态的变化答案也随着变化,一个解决问题的答案就是在状态不断变化中产生的
40.4)回溯法:在搜索尝试过程中寻找问题解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径,满足约束条件的所有解
40.5)分支限界法:以“回溯法”一致,不同的是分支限界法:找出满足约束条件的一个解