Java两周半速成之路(第十六天)

一、网络编程

1.概述:

                 就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换

2.网络模型

 

3.网络参考模型图 

 

4.网络通信三要素

 

4.1IP地址 

InetAddress类的使用:

注意:通过API查看,此类没有构造方法,如果想要创建该类的对象,只能借助于其静态成员方法,因为其静态成员方法的返回值为InetAddress类的对象。

public static InetAddress getByName(String host)         

 确定主机名称的IP地址,传入的是ip地址,将ip地址封装成一个InetAddress对象

public String getHostName()                                            获取此IP地址的主机名

public String getHostAddress()                                        返回文本显示中的IP地址字符串

演示:

import java.net.InetAddress;

/*
    网络编程的三要素:ip地址 端口号 协议
 */
public class InetAddressDemo {
    public static void main(String[] args) throws Exception {
       // public static InetAddress getByName(String host) 确定主机名称的IP地址。
        //传入的是ip地址,将ip地址封装成一个InetAddress对象
        InetAddress inetAddress = InetAddress.getByName("192.168.1.13");
        System.out.println(inetAddress);     

        //public String getHostName()获取此IP地址的主机名。
        System.out.println(inetAddress.getHostName());

        //public String getHostAddress()返回文本显示中的IP地址字符串。
        System.out.println(inetAddress.getHostAddress());

    }
}

 

4.2端口号

 

4.3协议UDP和TCP 

 

4.4Socket 

 

 

4.5Socket机制图解

 5.UDP传输

 (1) UDP传输-发送端思路:

 

UDP传输-发送端代码演示:

package com.shujia.day18.udpdemo;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
    1:建立udp的socket服务
    2:将要发送的数据封装成数据包
    3:通过udp的socket服务,将数据包发送出
    4:关闭资源
    从键盘录入数据进行发送,如果输入的是886那么客户端就结束输入数据。

 */
public class SendDemo1 {
    public static void main(String[] args) throws Exception {
        //1:建立udp的socket服务
        //public DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。
        DatagramSocket ds = new DatagramSocket();

        //2:将要发送的数据封装成数据包 DatagramPacket
        //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
        //构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。
        //byte[] buf  要发送的数据的字节数组表现形式
        byte[] bytes = "我陈平安,唯有一剑,可搬山,倒海......".getBytes();
        //int length  要发送数据字节数组的长度
        int length = bytes.length;
        //InetAddress address  目标发送的ip地址的InetAddress形式对象
        InetAddress inetAddress = InetAddress.getByName("192.168.1.13");
        //int port 目标机器上应用程序的端口号
        int port = 12345;
        //创建数据包
        DatagramPacket dp = new DatagramPacket(bytes, length, inetAddress, port);

        //3:通过udp的socket服务,将数据包发送出
        //public void send(DatagramPacket p) 从此套接字发送数据报包。
        //将上面创建好的数据包进行发送
        ds.send(dp);

        //4:关闭资源
        ds.close();
    }
}

(2)UDP传输-接收端思路

UDP传输-接收端代码演示:

import java.lang.String;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

/*
    1:建立udp的socket服务.
    2:通过receive方法接收数据
    3:将收到的数据存储到数据包对象中
    4:通过数据包对象的功能来完成对接收到数据进行解析.
    5:可以对资源进行关闭

 */
public class ReceiveDemo1 {
    public static void main(String[] args) throws Exception {
        //public DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口。
        //创建Socket对象并绑定一个端口号
        DatagramSocket ds = new DatagramSocket(10086);

        //接收端需要创建一个空的数据包,接收过来的数据
        //DatagramPacket(byte[] buf, int length)
        //构造一个 DatagramPacket用于接收长度的数据包 length 。
        //byte[] buf 将来用于接收数据的字节数组
        byte[] bytes = new byte[1024];
        int length = bytes.length;       //int length  所准备的字节数组的长度
        DatagramPacket dp = new DatagramPacket(bytes, length);

        //2:通过receive方法接收数据
        //receive(DatagramPacket p)
        //程序走到这一步,会发生阻塞等待数据过来
        ds.receive(dp);//3:将收到的数据存储到数据包对象中

        //4:通过数据包对象的功能来完成对接收到数据进行解析.
        byte[] data = dp.getData(); // 用于解析数据包中接收到的数据
        int dataLength = dp.getLength(); // 获取真正接收到字节数组长度
        //将接收到的字节数组转字符串
        String info = new String(data, 0, dataLength);


        InetAddress inetAddress = dp.getAddress();
        String ip = inetAddress.getHostAddress();//获取发送段的ip地址
        String hostName = inetAddress.getHostName();//获取发送端的主机名
        System.out.println("===================================");
        System.out.println(hostName + " ip地址为:" + ip + ", 发来数据:" + info);
        System.out.println("===================================");

        //5:可以对资源进行关闭
        ds.close();
    }
}

注意:先执行接收端代码在执行输出端代码~

效果演示:

(3)练习:

      从键盘录入数据进行发送,如果输入的是886那么发送端就结束输入数据

发送端:


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

/*
    1:建立udp的socket服务
    2:将要发送的数据封装成数据包
    3:通过udp的socket服务,将数据包发送出
    4:关闭资源
    从键盘录入数据进行发送,如果输入的是886那么客户端就结束输入数据。

 */
public class SendDemo1 {
    public static void main(String[] args) throws Exception{
        //1:建立udp的socket服务
        //public DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。
        DatagramSocket ds = new DatagramSocket();
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in);

        while (true){
            System.out.print("请输入要发送的数据: ");
            String info = sc.next();


            //2:将要发送的数据封装成数据包 DatagramPacket
            //DatagramPacket(byte[] buf, int length, InetAddress address, int port)
            //构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。
            //byte[] buf  要发送的数据的字节数组表现形式
            byte[] bytes = info.getBytes();
            //int length  要发送数据字节数组的长度
            int length = bytes.length;
            //InetAddress address  目标发送的ip地址的InetAddress形式对象
            InetAddress inetAddress = InetAddress.getByName("192.168.1.43");
            //int port 目标机器上应用程序的端口号
            int port = 12345;
            //创建数据包
            DatagramPacket datagramPacket = new DatagramPacket(bytes, length, inetAddress, port);

            //3:通过udp的socket服务,将数据包发送出
            //public void send(DatagramPacket p) 从此套接字发送数据报包。
            //将上面创建好的数据包进行发送
            ds.send(datagramPacket);

            if("886".equals(info)){
                break;
            }
        }

        //4:关闭资源
        ds.close();
    }
}

 

接收端:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    1:建立udp的socket服务.
    2:通过receive方法接收数据
    3:将收到的数据存储到数据包对象中
    4:通过数据包对象的功能来完成对接收到数据进行解析.
    5:可以对资源进行关闭

 */
public class ReceiveDemo1 {
    public static void main(String[] args) throws Exception {

        //public DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口。
        //创建Socket对象并绑定一个端口号
        DatagramSocket ds = new DatagramSocket(12345);

        //接收端需要创建一个空的数据包,接收过来的数据
        //DatagramPacket(byte[] buf, int length)
        //构造一个 DatagramPacket用于接收长度的数据包 length 。
        //byte[] buf 将来用于接收数据的字节数组
        byte[] bytes = new byte[1024];
        //int length  所准备的字节数组的长度
        int length = bytes.length;
        DatagramPacket dp = new DatagramPacket(bytes, length);


        while (true){
            //2:通过receive方法接收数据
            //receive(DatagramPacket p)
            //程序走到这一步,会发生阻塞等待数据过来
            ds.receive(dp); //3:将收到的数据存储到数据包对象中

            //4:通过数据包对象的功能来完成对接收到数据进行解析.
            byte[] data = dp.getData(); // 用于解析数据包中接收到的数据
            int dataLength = dp.getLength(); // 获取真正接收到字节数组长度
            //将接收到的字节数组转字符串
            String info = new String(data, 0, dataLength);

            InetAddress inetAddress = dp.getAddress();
            String ip = inetAddress.getHostAddress(); //获取发送段的ip地址
            String hostName = inetAddress.getHostName(); //获取发送端的主机名

            String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            System.out.println("================="+time+"=================");
            if("886".equals(info)){
                System.out.println("******"+hostName + " ip地址为:" + ip + "发送端停止发送了!!!!!!!******");
//                break;
            }else {
                System.out.println(hostName + " ip地址为:" + ip + ", 发来数据:" + info);
            }

        }

        //5:可以对资源进行关闭
//        ds.close();

    }
}

 

6.TCP传输

 (1)TCP传输-客户端思路

TCP传输-客户端思路代码演示:


import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

/*
    1:建立客户端的Socket服务,并明确要连接的服务器。
    2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
    3:通过Socket对象的方法,可以获取这两个流
    4:通过流的对象可以对数据进行传输
    5:如果传输数据完毕,关闭资源

 */

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/*
    1:建立客户端的Socket服务,并明确要连接的服务器。
    2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
    3:通过Socket对象的方法,可以获取这两个流
    4:通过流的对象可以对数据进行传输
    5:如果传输数据完毕,关闭资源

 */
public class ClientDemo1 {
    public static void main(String[] args) throws Exception {
        //1:建立客户端的Socket服务,并明确要连接的服务器。
        //构造方法:要传输服务器目标的ip地址和端口号
        //Socket(InetAddress address, int port) 创建流套接字并将其连接到指定IP地址的指定端口号。
        //InetAddress address 服务器的ip地址的InetAddress表现形式
//        InetAddress inetAddress = InetAddress.getByName("192.168.1.43");
//        //int port 服务器程序所占用的端口号
//        int port = 10086;
//        Socket socket = new Socket(inetAddress, port);
        //Socket(String host, int port)
        //创建流套接字并将其连接到指定主机上的指定端口号。
        //该Socket对象如果成功创建,就说明已经与服务器建立连接成功!
        Socket socket = new Socket("192.168.1.13", 10086);
        System.out.println("与服务器段连接成功!" + socket);

        //3:通过Socket对象的方法,可以获取这两个流
        OutputStream outputStream = socket.getOutputStream();
        //4:通过流的对象可以对数据进行传输
        outputStream.write("真相只有一个".getBytes());
        //告诉服务器没有数据
        socket.shutdownOutput();


        //获取通道中的输入流对象
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int length = inputStream.read(bytes);
        String info = new String(bytes, 0, length);
        System.out.println("服务器给我的反馈是:" + info);

        //5:如果传输数据完毕,关闭资源
        socket.close();
    }
}

(2) TCP传输-服务器端思路

 TCP传输-服务器端思路代码演示:


import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/*
    1:建立服务器端的socket服务(ServerSocket),需要一个端口
    2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
    3:通过客户端的获取流对象的方法,读取数据或者写入数据
    4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的

 */
public class ServerDemo1 {
    public static void main(String[] args) throws Exception{
        //1:创建服务器段的Socket对象,
        //ServerSocket(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);

        //2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
        //程序运行到这一步的时候,发生阻塞,会监听客户端的连接
        //返回的Socket对象,实际上可以理解为是与某一个客户端的连接通道
        //将来可以使用Socket对象中的输入流获取客户端发送的信息,或者使用输出流向客户端发送反馈
        Socket socket = ss.accept();

        //获取通道中的输入流对象
        InputStream is = socket.getInputStream();
        InetAddress inetAddress = socket.getInetAddress();
        String hostName = inetAddress.getHostName();
        String hostAddress = inetAddress.getHostAddress();
        byte[] bytes = new byte[1024];
        int length = 0;
        while ((length = is.read(bytes))!=-1){
            String info = new String(bytes, 0, length);
            System.out.println(hostName + " ip地址为:" + hostAddress + ", 发来数据:" + info);
        }

        //获取通道中的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("服务器已收到! ".getBytes());

        socket.close();
        ss.close();
    }
}

 

(3)练习:

使用多台客户端与服务端建立联系,从键盘录入数据进行发送,如果输入的是886那么发送端就结束输入数据 (使用多线程)

客户端:

import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

/*
    1:建立客户端的Socket服务,并明确要连接的服务器。
    2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket流,Socket流中既有读取流,也有写入流.
    3:通过Socket对象的方法,可以获取这两个流
    4:通过流的对象可以对数据进行传输
    5:如果传输数据完毕,关闭资源

 */
public class ClientDemo1 {
    public static void main(String[] args) throws Exception{
        //1:建立客户端的Socket服务,并明确要连接的服务器。
        //构造方法:要传输服务器目标的ip地址和端口号
        //Socket(InetAddress address, int port) 创建流套接字并将其连接到指定IP地址的指定端口号。
        //InetAddress address 服务器的ip地址的InetAddress表现形式
//        InetAddress inetAddress = InetAddress.getByName("192.168.1.13");
//        //int port 服务器程序所占用的端口号
//        int port = 10086;
//        Socket socket = new Socket(inetAddress, port);
        //Socket(String host, int port)
        //创建流套接字并将其连接到指定主机上的指定端口号。
        //该Socket对象如果成功创建,就说明已经与服务器建立连接成功!
        Socket socket = new Socket("192.168.1.13", 10086);
        System.out.println("与服务器段连接成功!" + socket);
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in);
        //3:通过Socket对象的方法,可以获取这两个流
        OutputStream outputStream = socket.getOutputStream();
        while (true){
            System.out.println("请输入要发送的数据: ");
            String info = sc.next();



            //4:通过流的对象可以对数据进行传输
            outputStream.write(info.getBytes());
            if("886".equals(info)){
                break;
            }
        }


        //5:如果传输数据完毕,关闭资源
        socket.close();
    }
}

 

服务端:


import java.io.InputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
    1:建立服务器端的socket服务(ServerSocket),需要一个端口
    2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信
    3:通过客户端的获取流对象的方法,读取数据或者写入数据
    4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的

 */
public class ServerDemo1 {
    public static void main(String[] args) throws Exception{
        //1:创建服务器段的Socket对象,
        //ServerSocket(int port) 创建绑定到指定端口的服务器套接字。
        ServerSocket ss = new ServerSocket(10086);

        //死循环监听客户端的连接,将每个客户端封装成一个线程运行
        while (true){
            Socket socket = ss.accept();
            new OneClient(socket).start();
        }
    }
}

class OneClient extends Thread{
    private Socket socket;
    private String hostName;
    private String hostAddress;
    OneClient(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            //获取通道中的输入流对象
            InputStream is = socket.getInputStream();
            InetAddress inetAddress = socket.getInetAddress();
            hostName = inetAddress.getHostName();
            hostAddress = inetAddress.getHostAddress();
            System.out.println("=====用户: "+hostName+"已上线!====");
            byte[] bytes = new byte[1024];
            int length = 0;
            while ((length = is.read(bytes))!=-1){
                String info = new String(bytes, 0, length);
                if("886".equals(info)){
                    System.out.println("=====用户: "+hostName+"已离线!====");
                }else {
                    String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
                    System.out.println(time);
                    System.out.println(hostName + " ip地址为:" + hostAddress + ", 发来数据:" + info);
                }

            }
        }catch (Exception e){
            System.out.println("--------------------------------------------");
            System.out.println(hostName + " ip地址为:" + hostAddress + "异常下线............");
            System.out.println("--------------------------------------------");
        }
    }
}

 

 二.类加载器

1.类的加载

 

2.类初始化时机 

 

3.类加载器概述

 

4.类加载器的作用 

 

 三.反射的基本使用

1.概述:

 

2.通过反射获取构造方法并使用

演示:


import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class Student {
    public int id;
    private int age;
    String name;

    public Student() {
    }

    Student(int age) {
        this.age = age;
    }

    private Student(String name) {
        this.name = name;
    }


    public void fun1() {
        System.out.println("这是公共的成员方法");
    }

    private void fun1(String name) {
        System.out.println("这是私有的成员方法" + name);
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

public class StudentDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //如何获取一个类对用的Class对象
        //1、在有对象的前提下,使用getClass()方法获取
        Student student = new Student();
        Class<? extends Student> studentClass1 = student.getClass();

        //2、没有对象,只有类,通过类的属性进行获取
        Class<Student> studentClass2 = Student.class;

        //3、最常用的方式,Class类中有一个静态方法
        //public static Class<?> forName(String className) 返回与给定字符串名称的类或接口相关联的类对象。
        Class<?> studentClass = Class.forName("com.shujia.day18.FanShe.Student");

        System.out.println("===============================================================================");

/*
一个类中有三种成员:
    1、成员变量 Field
    2、构造方法 Constructor
    3、成员方法 Method
*/
        //TODO:通过反射获取构造方法并使用
        //Class类中有一个getConstructor方法
        //public Constructor<T> getConstructor(Class<?>... parameterTypes)
        //返回一个Constructor对象,该对象反映Constructor对象表示的类的指定的公共类函数。
        Constructor<?> c1 = studentClass.getConstructor();        //表示获取Student类中的无参构造方法
        System.out.println(c1);


        //获取Student类中的有参构造方法
        //获取不是public修饰的构造方法
        //getDeclaredConstructor()     可以获取所有权限构造方法
        Constructor<?> c2 = studentClass.getDeclaredConstructor(int.class);
        System.out.println(c2);


        /*
        如何使用将获取到的构造方法来创建对象呢?
        Constructor中有一个newInstance方法:
        newInstance(Object... initargs)
        使用由此Constructor对象表示的构造函数,使用指定的初始化参数创建和初始化构造函数的声明类的新实例。
         */
        Object o1 = c1.newInstance();
        System.out.println(o1);        //Student{id=0, age=0, name='null'}

        Constructor<?> c3 = studentClass.getDeclaredConstructor(String.class);
        //c3的构造方法是被private修饰的所以无法直接访问,所以要使用暴力访问,绕过检测机制
        c3.setAccessible(true);       //暴力访问,绕过检测机制
        Object  o3 = c3.newInstance("小明");
        System.out.println(o3);
        


    }
}

 

 3.通过反射获取成员变量并使用

演示:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Arrays;

public class StudentDemo1 {
    public static void main(String[] args) throws Exception {
        Class<?> studentClass = Class.forName("com.shujia.day18.FanShe.Student");

        //TODO:通过反射获取成员变量并使用
        //Class类中的getField方法          根据属性的名字获取对应的被public修饰的成员变量的对象
        Field id = studentClass.getField("id");
        System.out.println(id);
        //getDeclaredField 获取所有权限的成员变量
        Field name = studentClass.getDeclaredField("name");
        System.out.println(name);


        //getFields获取类中所有的被public修饰的成员变量
        Field[] fields = studentClass.getFields();
        System.out.println(Arrays.toString(fields));

//        //使用获取到的成员变量
        Constructor<?> c1 = studentClass.getDeclaredConstructor();      //表示获取Student类中的无参构造方法
        Object o = c1.newInstance();
        System.out.println(o);           //Student{id=0, age=0, name='null'}

        //需求:给对象o中的成员变量name进行赋值
//        public void set(Object obj, Object value)
        //将指定对象参数上的此Field对象表示的字段设置为指定的新值。
        name.set(o, "小明");
        System.out.println(o);       //Student{id=0, age=0, name='小明'}
        //如果要访问被private修饰的成员变量,依旧是暴力访问
        id.setAccessible(true);
        id.set(o,1001);
        System.out.println(o);       //Student{id=18, age=0, name='小明'}

        Field age = studentClass.getDeclaredField("age");
        age.setAccessible(true);
        age.set(o,18);
        System.out.println(o);


    }
}

 

4.通过反射获取成员方法并使用 

演示:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

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

        //TODO:通过反射获取成员方法并使用
        //public Method getMethod(String name, Class<?>... parameterTypes)
        //获取类中被public所修饰的成员方法
        //根据方法的名字和参数类型获取
        Class<?> studentClass = Class.forName("com.shujia.day18.FanShe.Student");
        Method fun1 = studentClass.getMethod("fun1");
        System.out.println(fun1);

        //getDeclaredMethod获取任意一个成员方法,包括私有的
        Method fun11 = studentClass.getDeclaredMethod("fun1", String.class);
        System.out.println(fun11);
        System.out.println("==================================================");

        //getMethods可以获取类中及其直接父类中的所有被public修饰的成员方法
        Method[] methods = studentClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("==================================================");

        //getDeclaredMethods可以获取本类中的所有的成员方法,包括私有的
        Method[] declaredMethods = studentClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("========================================");

        //如何调用获取到的成员方法
        Constructor<?> c1 = studentClass.getConstructor();        //表示获取Student类中的无参构造方法
        Object o = c1.newInstance();
        //public Object invoke(Object obj, Object... args)
        //在具有指定参数的方法对象上调用此方法对象表示的基础方法
        fun1.invoke(o);
        //如果是调用私有的方法,则需要暴力访问
        fun11.setAccessible(true);
        fun11.invoke(o, "张三");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/461459.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

精读《精通 console.log》

1 引言 本周精读的文章是 Mastering JS console.log like a Pro&#xff0c;一起来更全面的认识 console 吧&#xff01; 2 概述 & 精读 console 的功能主要在于控制台打印&#xff0c;它可以打印任何字符、对象、甚至 DOM 元素和系统信息&#xff0c;下面一一介绍。 c…

力扣-20. 有效的括号(回顾知识哈希表,栈)

给定一个只包括 ‘(’&#xff0c;‘)’&#xff0c;‘{’&#xff0c;‘}’&#xff0c;‘[’&#xff0c;‘]’ 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有…

QT中dumpcpp以及dumpdoc使用

qt中调用COM的方式方法有四种&#xff0c;参考解释在 Qt 中使用 ActiveX 控件和 COM (runebook.dev) 介绍dumpcpp的使用方法Qt - dumpcpp 工具 (ActiveQt) (runebook.dev)&#xff1a; 在安装好了的qt电脑上&#xff0c;通过powershell窗口来实现&#xff0c;powershell比cmd要…

C语言从入门到熟悉------第五阶段

结构体 结构体很重要&#xff0c;一定要掌握。但是在很多C语言书籍中结构体的内容讲得非常少&#xff0c;因为从结构体开始&#xff0c;后面介绍的内容已经超出C语言基础的范畴&#xff0c;属于C高级编程部分了。仅仅具备前面的知识是远远不够的&#xff0c;因为在实际编程中&…

#QT(定时轮播电子相册)

1.IDE&#xff1a;QTCreator 2.实验&#xff1a; &#xff08;1&#xff09;使用QOBJECT的TIMER &#xff08;2&#xff09;EVENT时间 &#xff08;3&#xff09;多定时器定时溢出判断 &#xff08;4&#xff09;QLABEL填充图片 3.记录 4.代码 widget.h #ifndef WIDGET_H…

AI - 决策树模型

&#x1f914;决策树算法 决策树的思想来源可以追溯到古希腊时期&#xff0c;当时的哲学家们就已经开始使用类似于决策树的图形来表示逻辑推理过程。然而&#xff0c;决策树作为一种科学的决策分析工具&#xff0c;其发展主要发生在20世纪。 在20世纪50年代&#xff0c;美国兰…

【消息队列开发】 测试MessageFileManager(对硬盘中的消息操作)类

文章目录 &#x1f343;前言&#x1f384;测试流程&#x1f334;准备工作&#x1f332;测试创建队列功能&#x1f333;测试统计文件的读写&#x1f38b;测试将相应消息放入文件中&#x1f38d;测试读文件里的消息到内存&#x1f340;测试删除消息&#x1f60e;测试垃圾回收⭕总…

AtomoVideo:AIGC赋能下的电商视频动效生成

✍&#x1f3fb; 本文作者&#xff1a;凌潼、依竹、桅桔、逾溪 1. 概述 当今电商领域&#xff0c;内容营销的形式正日趋多样化&#xff0c;视频内容以其生动鲜明的视觉体验和迅捷高效的信息传播能力&#xff0c;为商家创造了新的机遇。消费者对视频内容的偏好驱动了视频创意供给…

Yolo系列算法-理论部分-YOLOv3

0. 写在前面 YOLO系列博客&#xff0c;紧接上一篇Yolo系列算法-理论部分-YOLOv2-CSDN博客 1. YOLOv3-定型之作 2018年&#xff0c;Redmon团队推出YOLOv3的网络模型&#xff0c;将骨干网络&#xff08;backbone&#xff09;由darknet-19替换成darknet-53网络&#xff0c;加入特…

【Python循环2/5】for循环的复杂应用

目录 序言 导入1 累加 练习 导入2 计数器 练习 导入3 if判断 总结 序言 昨天&#xff0c;我们学习了 for 循环遍历列表、字典等数据的方式。今天我们会学习&#xff0c;for 循环与“累加” 、if 判断和“计数器”的结合运用。 导入1 在前面的学习中&#xff0c;我们学…

计算机网络——物理层(数据交换方式)

计算机网络——数据交换方式 提高数据交换方式的必要性电路交换电路交换原理电路交换的阶段建立阶段通信阶段和连接拆除阶段 电路交换的优缺点报文交换什么是报文报文交换的阶段报文交换的优缺点 分组交换分组交换的阶段分组交换的优缺点 数据交换方式的选择数据报方式数据报方…

VS Code上,QT基于cmake,qmake的构建方法(非常详细)

VS Code上,QT基于cmake&#xff0c;qmake的构建方法 1 前言2 QT基于cmake的构建方法2.1 VS Code关键插件安装2.2 系统环境变量配置2.3 VS Code中&#xff0c;环境变量配置2.4 Cmake新建一个新的Porject 3 QT基于qmake的构建方法 1 前言 最近&#xff0c;由于认证了github的学生…

尺寸小又薄的整流桥IBS

1. 整流桥功能介绍 整流桥在电子领域中扮演着至关重要的角色&#xff0c;为各种电子设备和电路提供了稳定的电源。整流桥的主要作用是将交流电信号转换为直流电信号。当交流电信号通过整流桥时&#xff0c;它会使得只有一个方向的电流能够通过&#xff0c;从而实现了将交流电信…

【数据结构练习题】栈——1.括号匹配 2.逆波兰表达式求值 3.出栈入栈次序匹配 4.最小栈

♥♥♥♥♥个人主页♥♥♥♥♥ ♥♥♥♥♥数据结构练习题总结专栏♥♥♥♥♥ 文件目录 前言1.括号匹配1.1问题描述1.2解题思路1.3画图解释1.4代码实现2.逆波兰表达式求值 2.1问题描述2.2解题思路2.3画图解释2.4代码解释3.出栈入栈次序匹配 3.1问题描述3.2思路分析3.3画图解释3.…

金融知识分享系列之:MACD指标精讲

金融知识分享系列之&#xff1a;MACD指标精讲 一、MACD指标二、指标原理三、MACD指标参考用法四、MACD计算步骤五、MACD分析要素六、根据快线DIF位置判断趋势七、金叉死叉作为多空信号八、快线位置交叉信号九、指标背离判断行情反转十、差离值的正负十一、差离值的变化十二、指…

KBP210-ASEMI新能源专用整流桥KBP210

编辑&#xff1a;ll KBP210-ASEMI新能源专用整流桥KBP210 型号&#xff1a;KBP210 品牌&#xff1a;ASEMI 封装&#xff1a;KBP-4 正向电流&#xff08;Id&#xff09;&#xff1a;2A 反向耐压&#xff08;VRRM&#xff09;&#xff1a;1000V 正向浪涌电流&#xff1a;6…

中整协与成都艺星联合主办的“面部馒化修复注射技术培训班”圆满落下帷幕

在追求医疗美容学科深度的道路上&#xff0c;Yestar成都艺星再次成为行业先锋&#xff0c;近日&#xff0c;由中整协与成都艺星整形美容医院联合主办的“面部馒化修复注射技术培训班”在Yestar成都艺星圆满落下帷幕。本次培训班以其严谨的学术精神和对临床治疗思路的深入解读&a…

在idea中配置tomcat服务器,部署一个项目(下载教程加链接)

第一步&#xff1a;把Tomcat下载好 ww​​​​​​​Apache Tomcat - Welcome! 链接如上&#xff1a;进去后在左边找到Tomcat8点击进去后 找到图下内容 第二步&#xff1a; 打开这个文件点击bin进去 会出现一个黑色框框&#xff0c;也就是服务器 完成后就可以在浏览器输入…

Redis 搭建主从集群

文章目录 1. 主从集群架构1.1 准备实例和配置1.2 启动1.3 开启主从关系1.4 测试 2. 主从同步原理2.1 全量同步2.2 增量同步repl_backlog原理 2.3 主从同步优化小结 单节点的 Redis 并发能力有限&#xff0c;要进一步提高 Redis 的并发能力&#xff0c;就需要搭建主从集群&#…

2024年无人直播是否已经成为新趋势,商家使用矩图AI无人直播月增长5万+

无论是 个体商户、企业经营者、电商从业者、想创业赚钱的朋友;也不管你是做餐饮还是非餐饮;亦或是抖音小时达外卖。这篇文章&#xff0c;请勿必看完&#xff0c;对你的业绩增长是有绝对的帮助。 无人直播的发展经历了几个时代&#xff0c;现在已经到了4.0的时代&#xff0c;更安…