知识点总结

1:面试题:

1)jvm是多线程的吗?   是多线程;至少有两条件线程

        1)main---"用户线程"

        2)垃圾回收线程,回收没有更多的引用对象,从而释放空间;如果没有垃圾回收线程,Java中不断的去new,不断的堆内存空间---->导致OOM(Out Of Memory:内存溢出)

2:创建线程的方式

创建线程的方式1:

1)自定义一个类 继承Thread类

2)重写Thread类的run方法

3)在main()用户线程中,创建当前线程了对象

4)启动线程--->start()不是run方法,run方法是一个普通方法,

线程的创建方式2:

1)自定义一个类,实现Runnable接口

2)重写Runnable接口的run方法

3)在用户线程main中去创建当前类对象--->"资源类"

4)创建Thread类对象,将3)资源类作为Thread类对象的参数进行传递

3:异常处理

throws:抛出

throw:抛出

区别:

1)书写位置的区别

        throws:用在方法声明上

        throw:用在方法体中

2)后面跟的类型不一样的

        throws后面跟的异常类名,可以多个,中间逗号隔开

        throw:后面只能一个异常对象,new XXException()

3)是否出现异常的时机

        throws:可能出现问题,可能性

        throw:执行某个逻辑代码,一定会出现这个异常!(肯定性)

4)处理异常:

        throws:抛出给调用者,谁调用这个方法(带有throws的方法),谁必须对这个已处理(throws/try...catch...)

        throw:异常的处理:交给方法体中逻辑判断,if(xxx){throw new XXException(...);}

4:校验多线程安全问题的标准 (解决方案)

1)检查程序是否是多线程环境 

2)是否存在共享数据 

3)是否存在多条语句对共享数据的操作

Java提供了同步代码块,解决上面3),使用同步代码块将多条语句对象共享数据的包起来

Java的同步机制synchronized(锁对象){ //锁对象可以是任意的Java类对象,每一个线程都是用"同一把锁"多条语句对共享数据的操作

5:静态代理:

最大特点:代理角色和真实角色必须实现同一个接口

代理角色:帮助真实角色完成一些事情

真实角色:专注于自己的事情

6:线程的状态

NEW,新建状态

RUNNABLE,运行状态

BLOCKED,线程阻塞状态

WAITTING,死死等待,

TIMED_WAITTING,超时等待

TERMINATED,线程终止/线程死亡

7:线程池

可以通过Executors工厂类(当前类构造方法私有化,对外提供静态方法--->简单工厂模式)提供一些创建线程池的功能

可以创建固定的可重用的线程数的线程池

8:创建线程池的方式

1.newCachedThreadPool

2.newFixedThreadPool

3.newSingleThreadExecutor

4:newScheduleThreadPool

5.newSingleThreadScheduledExecutor

9:ThreadPoolExecutor它的构造方法涉及的相关参数

1.corePoolSize是指线程池中长期存活的线程数.

2.maximumPoolSize线程池允许创建的最大线程数量

3.keepAliveTime空闲线程存活时间

4.TimeUnit:空闲线程存活时间的描述单位

5.BlockingQueue线程池存放任务的队列,用来存储线程池的所有待执行任务

6.ThreadFactory线程池创建线程时调用的工厂方法

7.RejectedExecutionHandler默认的拒绝策略

10:单例设计模式---属于创建型设计模式(创建对象)

概念:始终在内存中有且仅有一个当期类的实例!(有一个对象)

单例设计模式:

1)饿汉式:不会出现安全问题的单例设计模式

1)当前类是具体类

2)类一加载就创建当前类实例

3)构造私有化,对外隐藏,不能new实例

4)对外提供静态方法,返回值当前类本身

public class SinglePattern {
    public static void main(String[] args) throws IOException {

        //创建学生对象
        //Student s = new Student() ;
        //Student s2 = new Student() ;
        //System.out.println(s==s2) ;//false
        //Student.s= null ; //修改了静态实例变量,为了不让你修改,加入private
        Student s1 = Student.getStudent();
        Student s2 = Student.getStudent() ;
        System.out.println(s1 ==s2) ;

        System.out.println("---------------------------------");
        //创建Runtime实例:获取运行环境
        Runtime runtime = Runtime.getRuntime();
        //提供一些方法
        //availableProcessors()获取cpu处理器的数量
        System.out.println(runtime.availableProcessors());
        //exec(String dos指令)
        System.out.println(runtime.exec("calc"));
        System.out.println(runtime.exec("qq"));


    }
}
public class Student {
    //静态实例:Student一加载,就创建当前类实例
    private static Student s = new Student() ;

    //对外不能new
    private Student(){}

    //对外提供静态的方法,返回值是当前类本身
    public static Student getStudent(){
        return  s;
    }
}

2)懒汉式:(可能存在安全问题的一种单例模式)

1)当前类是个具体类

2)当前类构造方法私有化

3)当前类的成员位置:声明当前类的一个静态变量

4)对外提供静态方法,返回值是当前类本身:需要判断当前变量是否为null

public class SinglePatter2 {
    public static void main(String[] args) {

        //获取Theacer对象
        Teacher t1 = Teacher.getInstance();
        Teacher t2 = Teacher.getInstance();
        System.out.println(t1==t2);
    }
}
public class Teacher {

    //声明静态变量,t的类型Teacher
    private  static Teacher t ;
    //构造方法私有化:
    private Teacher(){}

    //对外提供静态方法,返回值是当期类本身
    //多个线程同时去访问这个方法,
    //线程1,线程2,线程3--导致出现线程安全问题
  
    public static synchronized Teacher getInstance(){//变成了静态的同步方法 :锁对象:类名.class
            if(t ==null){
                t = new Teacher() ;
            }
            return  t;
    }
}

11:使用字节输入流将当前项目下的"fis.txt"文件内容读取出来打印在控制台上

public class FileInputStreamDemo {
    public static void main(String[] args)  {
           FileInputStream fis = null ;
        try {
            //创建文件字节输入流对象FileInputStream(String name)
             fis = new FileInputStream("fis.txt") ;
            //读取当前项目下的FileOutputStreamDemo3.java文件,把它内容打印控制台上
             fis = new FileInputStream("FileOutputStreamDemo3.java") ;

            
            int by = 0 ;
            while((by=fis.read())!=-1){
                //将字节数by---强转char字符
                System.out.print((char)by) ;
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

12:使用字节输入流和字节输出流,(分别两种方式进行读写复制操作)

将某个盘符下的c.txt文件中的内容复制到当前项目路径下的Copy.txt文件

public class Test2 {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        copy("c.txt", "D:\\课件\\day26\\day26\\code\\copy2");
        long end = System.currentTimeMillis();
        System.out.println("共耗时:" + (end - start) + "毫秒");
    }
    private static void copy(String srcFile, String destFile){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            byte[] bytes = new byte[1024];
            int len =0;
            while ((len=fis.read(bytes))!=-1){
                fos.write(bytes,0,len);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

13:方法递归:

方法本身调用方法的一种现象

前提条件:

1)定义一个方法

2)这个方法的逻辑是规律的

3)这个方法是有结束条件,否则---成了"死递归"

需求:
 *      求5的阶乘
 *      1)可以使用循环解决---求阶乘思想
 *              5!= 5*4!
 *                  --->
 public class DiGuiDemo {
    public static void main(String[] args) {
        //求5的阶乘
        //定义最终结果变量
        int jc = 1 ;
        for(int x = 1 ; x <= 5 ; x ++){
            jc *= x ;
        }
        System.out.println("5的阶乘是:"+jc);
        System.out.println("----------------------------------------------") ;
        System.out.println("5的阶乘是:"+getJc(5));
    }
    public static int getJc(int n){ //5
        if(n==1){
            return  1 ;
        }else {
                //5*getJc(4)
                //4*getJc(3)
               //3*getJc(2)
            //2*getJc(1)
            return  n * getJc(n-1) ;
        }
    }

  


}

14字符输入流---->Reader(抽象类)--->

具体的子类:字符转换输入流InputStreamReader --- 将字节输入流---->转换--->字符输入流

public InputStreamReader(InputStream in):使用平台默认字符集进行解码---读取数据

public InputStreamReader(InputStream in,String charsetName)

使用指定字符集解码---读取数据

public class InputStreamReaderDemo {
    public static void main(String[] args) throws Exception {
        //创建字符转换输入流对象

        //解码:gbk(中国编码表): 一个中文对应两个字节
      /*  InputStreamReader isr = new InputStreamReader(
                new FileInputStream("osw.txt"),"gbk") ;*/
        //public InputStreamReader(InputStream in)
        InputStreamReader isr = new InputStreamReader(
                new FileInputStream("osw.txt")) ;
        //读数据
        //一次读取一个字符
        int by = 0 ;//实际字符数
        while((by=isr.read())!=-1){
            //展示控制台上  读取的时候将文件内容的里面--->int类型----->转换成字符
            System.out.print((char)by);
        }

    }
}

15:字符流:字符输出流:Writer(抽象类)--->

具体的子类 OutputStreamWriter:字符转换输出流,"可以将字节输出流---转换---字符输出流"

构造方法:

public OutputStreamWriter(OutputStream out):使用平台默认字符集进行编码--输出数据

public OutputStreamWriter(OutputStream out,String charsetName):

使用指定的字符集进行编码---输出数据

public class OutputStreamWriterDemo {
    public static void main(String[] args) throws Exception {

        //创建一个字符转换输出流对象
        //utf-8:一个中文对应三个字节
       /* OutputStreamWriter osw = new OutputStreamWriter(
                new FileOutputStream("osw.txt"),"utf-8") ;*/

        OutputStreamWriter osw = new OutputStreamWriter(
                new FileOutputStream("osw.txt"));

        //写字符串
        osw.write("helloworld");
        osw.write("高圆圆");
        osw.write(97) ;//写入字符,传入参数int--->ASCII码表对应的字符值

        //释放资源
        osw.close();
    }
}

16:键盘录入

0)main方法里面:早期录入 String[] args

1)Scanner(InputStream in)---->Scanner sc = new Scanner(System.in) ;

2)new BufferedReader(new InputStreamReader(System.in))

public class Demo {
    public static void main(String[] args) throws IOException {

        //字符缓冲输入流需要--->包装字节输入流
       // InputStream inputStream = System.in ;
        //需要Reader字符流
        //Reader reader = new InputStreamReader(inputStream) ;//InputStreamReader(InputStream in)
        //创建字符缓冲输入流对象
      //  BufferedReader br = new BufferedReader(reader) ;

        //一步走
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        System.out.println("请您输入一个数据:");
        String line = br.readLine();
        //数字字符串--->
        int num = Integer.parseInt(line);
        System.out.println("您输入的内容是:"+num);
    }
}

17:网络三要素:

ip地址/端口号/协议

18:使用UDP协议发送数据

1)创建发送端的socket对象

2)创建"数据报包"--里面包括:数据内容,ip地址,端口号

3)使用发送端的Socket对象发送"数据报包"

4)释放资源

public class UdpSend {
    public static void main(String[] args) throws Exception {
        //1)创建发送端的socket对象 ---java.net.DatagramSocket:此类表示用于发送和接收数据报数据包的套接字
        //public DatagramSocket()throws SocketException
        DatagramSocket ds = new DatagramSocket() ;

        //public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
        byte[] bytes = "hello,udp我来了".getBytes() ;
        int length = bytes.length ;
        InetAddress inetAddress = InetAddress.getByName("10.35.165.17") ;
        int port = 6666 ;
        DatagramPacket dp = new DatagramPacket(bytes,length,inetAddress,port) ;

   
        ds.send(dp) ;

        //释放资源
        ds.close();
    }
}

19:Udp接收端

1)创建接收端的Socket对象

2)创建一个"数据报包"在里面自定义缓冲区:将发送端是数据存储到缓冲区中(字节数组,长度:1024或者1024的整数倍)

3)使用2)接收容器(缓冲区),接收发送端的数据

4)解析接收容器中的实际内容

5)展示数据即可

6)释放接收端的资源

public class UdpReceive {
    public static void main(String[] args) throws Exception {
        //1)创建接收端的Socket对象
        //public DatagramSocket(int port)throws SocketException
        DatagramSocket ds = new DatagramSocket(6666) ;

        //public DatagramPacket(byte[] buf,int length)
        byte[] buffer = new byte[1024] ;
        DatagramPacket dp = new DatagramPacket(buffer,buffer.length) ;

        ds.receive(dp) ;

        //4)解析接收容器中的实际内容
        //public byte[] getData() :解析数据报包中DatagramPacket
        // 缓冲的实际的字节数组
        byte[] bytes = dp.getData();
        //public int getLength():解析数据报包中DatagramPacket中的实际字节数组长度
        int length = dp.getLength();

        //展示数据
        String message = new String(bytes,0,length) ;
        //谁发送的数据---获取ip地址字符串形式
        //数据报包DatagramPacket--->public InetAddress getAddress()
        //InetAddress:ip地址--->String getHostAddress()
        String ip = dp.getAddress().getHostAddress() ;
        System.out.println("data from is--->"+ip+",data is--->"+message) ;

        //释放资源
        ds.close();

    }
}

20:发送端不断键盘录入数据,接收端不断展示数据,在一个窗口中聊天!使用多线程的方式:开启两条线程,一条线程:发送端发送数据另一条线程:接收端不断接收数据,展示数据

public class ChatRoom {
    public static void main(String[] args) {
        try {
            //创建发送端Socket
            DatagramSocket sendDs = new DatagramSocket() ;
            //创建接收端的Socket
            DatagramSocket receiveDs = new DatagramSocket(10086) ;
            //创建发送端的线程所在的资源类对象
            SendTread st = new SendTread(sendDs) ;
            //创建接收端的线程所在资源类对象
            ReceiveThread rt  =  new ReceiveThread(receiveDs) ;

            //创建线程
            Thread t1 = new Thread(st) ;
            Thread t2 = new Thread(rt) ;

            //启动线程
            t1.start();
            t2.start();
         } catch (SocketException e) {
            e.printStackTrace();
        }
    }
}
 接收端的资源类
 */
public class ReceiveThread  implements Runnable{
    private DatagramSocket ds ;
    public ReceiveThread(DatagramSocket ds){
        this.ds = ds ;
    }
    @Override
    public void run() {
        try {
            //不断的展示数据
            while(true){
                //接收数据:接收容器
                byte[] buffer = new byte[1024] ;
                DatagramPacket dp = new DatagramPacket(buffer,buffer.length) ;
                //接收
                ds.receive(dp) ;

                //解析缓冲区(接收容器)的数据
                String message = new String(dp.getData(),0,dp.getLength()) ;
                //获取ip地址
                String ip = dp.getAddress().getHostAddress() ;
                System.out.println("data from --->"+ip+",content is--->"+message);

            }
        } catch (IOException e) {
            e.printStackTrace();

        }
        //接收端不需要释放资源,一直开启状态
    }
}
 发送端的资源类
 */
public class SendTread  implements Runnable{

    private DatagramSocket ds ;
    public SendTread(DatagramSocket ds){
        this.ds = ds ;
    }

    @Override
    public void run() {
        try {
            //键盘录入数据--->BufferedReader
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(System.in)) ;
            String line = null ;
            while((line=br.readLine())!=null){
                //数据报包:将数据发送接收端
                DatagramPacket dp = new DatagramPacket(
                        line.getBytes(),
                        line.getBytes().length,
                        InetAddress.getByName("10.35.165.17"),
                        10086) ;

                //发送数据
                ds.send(dp) ;

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            ds.close();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值