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

news2024/10/6 10:42:04

一、网络编程

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, "张三");
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Boot Starter: 快速简明地创建Spring应用

Spring Boot Starter是Spring Boot的核心功能之一&#xff0c;它帮助开发人员快速简明地创建、配置和运行Spring应用。在本文中&#xff0c;我们将详细介绍Spring Boot Starter以及如何使用它创建一个Spring Boot应用。 文章目录 什么是Spring Boot Starter?为何使用Spring B…

jetson nano——编译一些包的网址导航,pyside2,qt(持续更新)

目录 1.PySide2下载地址2.tesserocr下载地址3.Qt下载地址4.OpenSSL官网5.latex编译器下载地址5.1MikTex5.2TeX Live 1.PySide2下载地址 https://download.qt.io/official_releases/QtForPython/pyside2/ 如下图&#xff1a; 2.tesserocr下载地址 https://github.com/simonflue…

【送书福利第五期】:ARM汇编与逆向工程

文章目录 &#x1f4d1;前言一、ARM汇编与逆向工程1.1 书封面1.2 内容概括1.3 目录 二、作者简介三、译者介绍&#x1f324;️、粉丝福利 &#x1f4d1;前言 与传统的CISC&#xff08;Complex Instruction Set Computer&#xff0c;复杂指令集计算机&#xff09;架构相比&#…

进入docker容器中安装软件失败解,国外源慢,时间不同步,执行命令权限不够等问题解决办法

进入docker容器中安装软件失败解&#xff0c;时间不同步, 国外源慢&#xff0c;执行命令权限不够 等问题解决办法 首先我进入docker容器中&#xff0c;为了安装一个软件&#xff0c;引出了很多报错问题&#xff0c;报错如下&#xff1a; 1、无法用 ifconfig 或者 ip addr 的方…

Ansible自动化运维Inventory与Ad-Hoc

前言 自动化运维是指利用自动化工具和技术来简化、自动化和优化IT基础设施的管理和运维过程&#xff0c;从而提高效率、降低成本&#xff0c;并减少人为错误。在当今复杂的IT环境中&#xff0c;自动化运维已经成为许多组织和企业提高生产力和保证系统稳定性的重要手段。Ansibl…

Kubernetes operator系列:kubebuilder 实战演练 之 开发多版本CronJob

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Kubernetes operator学习 系列文章&#xff0c;本节会在上一篇开发的Cronjob基础上&#xff0c;进行 多版本Operator 开发的实战 本文的所有代码&#xff0c;都存储于github代码库&#xff1a;https://github.c…

three.js 元素周期表,可鼠标控制

一些文章里的元素周期表,能显示,但控制器却无法使用,周期表没法旋转 后来发现是three.js版本问题, 旧版本在调试状态下是可以旋转的。新版本只要在正常页面打开状态下就能鼠标控制 <!DOCTYPE html> <html> <head> <meta charset="utf-8"&…

网盘聚合工具:统筹管理所有网盘资源 | 开源日报 No.203

alist-org/alist Stars: 35.6k License: AGPL-3.0 alist 是一个支持多存储的文件列表/WebDAV 程序&#xff0c;使用 Gin 和 Solidjs。 该项目的主要功能、关键特性、核心优势包括&#xff1a; 支持多种存储方式易于部署和开箱即用文件预览&#xff08;PDF、markdown、代码等&…

Jmeter文件上传不成功问题

前言 最近好忙呀&#xff0c;项目上线然后紧接着又客户培训了&#xff0c;由于项目有个模块全是走配置的&#xff0c;所以导致问题不断&#xff0c;近期要培训为了保障培训时客户同时操作的情况&#xff0c;所以把我从功能端抽出来做压测了&#xff0c;之前安排了2个同事写压测…

微调大型语言模型进行命名实体识别

大型语言模型的目标是理解和生成与人类语言类似的文本。它们经过大规模的训练&#xff0c;能够对输入的文本进行分析&#xff0c;并生成符合语法和语境的回复。这种模型可以用于各种任务&#xff0c;包括问答系统、对话机器人、文本生成、翻译等。 命名实体识别&#xff08;Na…

基于深度学习的口罩人脸识别研究进展

MTCNN模型训练输入的所有图像都是正样本&#xff08;戴口罩的照片&#xff09;&#xff0c;没有负样本作为模型输入。在后续的识别任务模块中&#xff0c;导入MTCNN模型检测结果&#xff0c;对特征点进行编码比较进行识别。 基于MTCNN的口罩人脸识别框架可分为四个阶段&#xf…

Linux 时间系统调用

UNIX及LinuxQ的时间系统是由「新纪元时间」Epoch开始计算起。Epoch是指定为1970年1月1日凌晨零点零分零秒&#xff0c;格林威治时间。目前大部份的UNX系统都是用32位来记录时间&#xff0c;正值表示为1970以后&#xff0c;负值则表示1970年以前。 对于当前时间到Epoch 我们用两…

刷题日记——干碎那个BFS!(含国科大机试2021)

例题小引——迷宫问题 问题描述: 迷宫由n行m列的单元格组成(n&#xff0c;m都小于等于50&#xff09;&#xff0c;每个单元格要么是空地&#xff0c;要么是障碍物。 现请你找到一条从起点到终点的最短路径长度。 分析——&#xff08;迷宫问题BFS解法&#xff09; 使用BFS…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:GridRow)

栅格布局可以为布局提供规律性的结构&#xff0c;解决多尺寸多设备的动态布局问题&#xff0c;保证不同设备上各个模块的布局一致性。 栅格容器组件&#xff0c;仅可以和栅格子组件(GridCol)在栅格布局场景中使用。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本…

实战!wsl 与主机网络通信,在 wsl 中搭建服务器。学了计算机网络,但只能刷刷面试题?那也太无聊了!这篇文章可以让你检测你的计网知识!

前言&#xff08;碎碎念&#xff09;&#xff1a;每次发布文章时&#xff0c;我都是一个纠结的过程。因为我给自己写笔记时&#xff0c;只需要记录自己不清晰或者易忘的知识点就可以了&#xff0c;但一旦想要作为文章发布&#xff0c;那么我就得考虑到很多人是纯新手&#xff0…

1TGE120011R1111变频器全国发货质保一年

1TGE120011R1111 ABB ABB的1TGE120011R1111是一个属于其TGE系列的小型断路器&#xff08;也称为微型断路器或MCB&#xff09;。这个系列的断路器主要用于低压配电系统&#xff0c;为电路提供过载和短路保护。以下是这款断路器的一些特点&#xff1a; 紧凑设计&#xff1a;TGE系…

【数据库】数据库基本知识

1.数据库的四个基本概念 1.1 数据&#xff1a;描述事务的符号记录 1.2 数据库&#xff1a;概括的说&#xff0c;数据库数据具有永久存储、有组织的、可共享的大量数据的集合&#xff0c;数据库中的数据按一定的数据模型组织、描述和储存&#xff0c;具有较小的冗余度、较高的…

2、鸿蒙学习-申请调试证书和调试Profile文件

申请发布证书 发布证书由AGC颁发的、为HarmonyOS应用配置签名信息的数字证书&#xff0c;可保障软件代码完整性和发布者身份真实性。证书格式为.cer&#xff0c;包含公钥、证书指纹等信息。 说明 请确保您的开发者帐号已实名认证。每个帐号最多申请1个发布证书。 1、登录AppGa…

AI美图设计室试用,可以生成PPT,以及模特试衣

文章目录 美图设计室试用 美图设计室试用 美图设计室是美图秀秀的公司推出的AI图像处理工具&#xff0c;其功能涵盖图片编辑、抠图、海报设计、文生图等常用的AI功能。尽管很多功能需要开通会员使用&#xff0c;但一些免费功能的表现也还不错&#xff0c;值得一用。 美图设计…

【解读】NIST网络安全框架CSF 2.0

2014年&#xff0c;NIST&#xff08;美国国家标准与技术研究所&#xff0c;类似于中国的工信部&#xff09;首次发布了网络安全框架CSF&#xff08;Cybersecurity Framework)&#xff0c;十年后&#xff0c;在2024年2月26日发布了重大更新&#xff08;CSF 2.0&#xff09;&…