由浅到深认识Java语言(39):网络编程

该文章Github地址:https://github.com/AntonyCheng/java-notes

在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!

上一章:由浅到深认识Java语言(38):I/O流

45.网络编程

软件结构

**C/S结构:**全称为 Client/Server 结构,是指客户端和服务器结构,重点在于客户端开发,常见的程序有QQ,迅雷,百度网盘等软件,但是客户端开发并不适合于 Java ,而适合于 C/C++ ;

**B/S结构:**全称为 Browser/Server 结构,是指浏览器和服务器结构,重点在于服务器端开发,常见浏览器有 IE ,谷歌,火狐等,服务端开发才是适合用 Java 实现的;

两种架构各有优势,但是无论是哪种架构,都离不开网络的支持;

**网络编程:**就是在一定的协议下,实现两台计算机的通信的程序;

网络通信协议

TCP/IP协议参考模型

  • **网络通信协议:**通过计算机网络可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,这就好比在道路中行驶的汽车一定要遵守交通规则一样。在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换。

  • TCP/IP协议: 传输控制协议/因特网互联协议( Transmission Control Protocol/Internet Protocol),是Internet最基本、最广泛的协议。它定义了计算机如何连入因特网,以及数据如何在它们之间传输的标准。它的内部包含一系列的用于处理数据通信的协议,并采用了4层的分层模型,每一层都呼叫它的下一层所提供的协议来完成自己的需求。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图中,OSI参考模型:模型过于理想化,未能在因特网上进行广泛推广。

TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。

TCP/IP协议中的四层分别是应用层、传输层、网络层和链路层,每层分别负责不同的通信功能。

  • 链路层:链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、网线提供的驱动。
  • 网络层:网络层是整个TCP/IP协议的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。而IP协议是一种非常重要的协议。IP(internet protocal)又称为互联网协议。IP的责任就是把数据从源传送到目的地。它在源地址和目的地址之间传送一种称之为数据包的东西,它还提供对数据大小的重新组装功能,以适应不同网络对包大小的要求。
  • 传输层:主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议TCP(Transmission Control Protocol)协议,即传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。UDP(User Datagram Protocol,用户数据报协议):是一个无连接的传输层协议、提供面向事务的简单不可靠的信息传送服务。
  • 应用层:主要负责应用程序的协议,例如HTTP协议、FTP协议等。

而通常我们说的TCP/IP协议,其实是指TCP/IP协议族,因为该协议家族的两个最核心协议:TCP(传输控制协议)和IP(网际协议),为该家族中最早通过的标准,所以简称为TCP/IP协议。

TCP与UDP协议

我们所接触较多的是 TCP 协议,而 UDP 协议了解即可;

java.net 包中提供了两种常见的网络协议的支持:

  • UDP:用户数据报协议(User Datagram Protocol);

    • 面向无连接的,不可靠的且不安全的协议:UDP 是无连接通信协议,即在传输数据时,数据的发送端和接收端不建立逻辑链接,就是一台计算机向另一台计算机发送数据时不会确认接收端是否存在就会发出信息,同样接收端在收到数据时也不会向发送端反馈是否收到数据,==所以容易产生丢包(数据包丢失)的现象==;
    • **消耗资源小,通信效率高:**所以常用于音频,视频和普通数据(QQ,微信消息)的传输,即使丢失一两个数据包也不会对接收结果产生太大影响,但是Java 并不擅长这样的协议
    • **有大小限制:**UDP 协议会把数据限制在 64KB 之内,超出这个范围就不能发送了;
    • **数据报(Datagram):**网络传输的基本单位;
  • TCP:传输控制协议(Transmission Control Protocol);

    • **面向连接的,可靠协议:**通信双方必须建立逻辑链接才能传输数据,理论上此种数据传输是可靠无差错的,往往现实不然,它是基于字节流的传输层通信协议,可以连续传输大量的数据,类似于打电话或者是百度云盘的下载;

    • **握手和挥手:**当一台计算机与另一台计算机建立连接时,TCP 协议会采用“三次握手”方式让它们建立一个连接——用于发送和接收数据虚拟链路,当数据传输完毕后 TCP 协议会采用“四次挥手”的方式断开连接;

      • **三次握手:**TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠,但是会浪费网络资源,速度慢;

        • 第一次握手:客户端向服务器端发出连接请求,等待服务器确认;

          注意:服务器端永远不会向客户端主动发起连接请求;

        • 第二次握手:服务器端向客户端送回一个响应,通知客户端收到了连接请求;

        • 第三次握手:客户端再次向服务器端发出确认信息,确认连接;

      • **四次挥手:**TCP协议中,在发送数据结束后,释放连接时需要经过四次挥手;

        • 第一次挥手:客户端向服务器端提出结束连接,让服务器端做最后的准备工作,此时客户端处于半关闭状态,即不再向服务器端发送数据,但是可以接收数据;

        • 第二次挥手:服务器端收到释放连接的请求后,会将最后的数据发给客户端,并且告知上层应用进程不再接收数据;

        • 第三次挥手:服务器端发送完数据后,会给客户端发送一个释放连接的报文,那么客户端接收后就知道可以正式释放连接了;

        • 第四次挥手:客户端接收到服务器端最后的释放连接报文后,要回复一个彻底断开的报文,这样服务器端收到之后才会彻底释放连接;

网络编程三要素

协议

**协议:**计算机网络通信必须遵守的规则,详情请看上节介绍;

IP地址

IP地址:指互联网协议地址(Internet Protocol Address),俗称IP。IP地址用来给一个网络中的计算机设备做唯一的编号。假如我们把“个人电脑”比作“一台电话”的话,那么“IP地址”就相当于“电话号码”;

IP地址分类方式一:

  • IPv4:是一个32位的二进制数,通常被分为4个字节,表示成a.b.c.d 的形式,例如192.168.65.100 。其中a、b、c、d都是0~255之间的十进制整数,那么最多可以表示42亿个;

  • IPv6:由于互联网的蓬勃发展,IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张;

    为了扩大地址空间,拟通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组,分成8组十六进制数,表示成ABCD:EF01:2345:6789:ABCD:EF01:2345:6789,号称可以为全世界的每一粒沙子编上一个网址,这样就解决了网络地址资源数量不够的问题;

IP地址分类方式二:

公网地址(万维网使用)和 私有地址(局域网使用)。192.168.开头的就是私有址址,范围即为192.168.0.0–192.168.255.255,专门为组织机构内部使用;

常用命令:

  • 查看本机IP地址,在控制台输入:
ipconfig

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 检查网络是否连通,在控制台输入:
ping 空格 IP地址
ping 192.168.80.1

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特殊的IP地址:

  • 本地回环地址(hostAddress):127.0.0.1
  • 主机名(hostName):localhost

域名:

因为IP地址数字不便于记忆,因此出现了域名,域名容易记忆,当在连接网络时输入一个主机的域名后,域名服务器(DNS)负责将域名转化成IP地址,这样才能和主机建立连接。 ------- 域名解析;

端口号

网络的通信,本质上是两个进程(应用程序)的通信。每台计算机都有很多的进程,那么在网络通信时,如何区分这些进程呢?

如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的进程(应用程序)了;

  • 端口号:用两个字节表示的整数,它的取值范围是0~65535
    • 公认端口:0~1023。被预先定义的服务通信占用,如:HTTP(80),FTP(21),Telnet(23);
    • 注册端口:1024~49151。分配给用户进程或应用程序。如:Tomcat(8080),MySQL(3306),Oracle(1521);
    • 动态/ 私有端口:49152~65535;

如果端口号被另外一个服务或应用所占用,会导致当前程序启动失败;

利用 协议+IP地址+端口号 三元组合,就可以标识网络中的进程: IP 192.168.1.100:8080 ,那么进程间的通信就可以利用这个标识与其它进程进行交互;

InetAddress类

InetAddress 类获取本机 IP 地址对象;

package top.sharehome.Demo;import java.net.InetAddress;public class Demo {public static void main(String[] args) throws Exception {/*** 以下是该类获取自己计算机的ip地址和主机名*/InetAddress inetAddress = InetAddress.getLocalHost();String ip = inetAddress.getHostAddress();String hostName = inetAddress.getHostName();System.out.println("inetAddress = " + inetAddress);System.out.println("ip = " + ip);System.out.println("hostName = " + hostName);System.out.println("===================================");/*** 以下是该类获取远程计算机的ip地址和主机名*/InetAddress inetAddress1 = InetAddress.getByName("byName");String ip1 = inetAddress1.getHostAddress();String hostName1 = inetAddress1.getHostName();System.out.println("inetAddress1 = " + inetAddress1);System.out.println("ip1 = " + ip1);System.out.println("hostName1 = " + hostName1);}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

报错是因为这个远程计算机的主机名是不存在的!

TCP:Socket和ServerSocket

通信的两端都要有Socket(也可以叫“套接字”),是两台机器间通信的端点。网络通信其实就是Socket间的通信。Socket可以分为:

  • 流套接字(stream socket):使用TCP提供可依赖的字节流服务
    • ServerSocket:此类实现TCP服务器套接字。服务器套接字等待请求通过网络传入。
    • Socket:此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
  • 数据报套接字(datagram socket):使用UDP提供“尽力而为”的数据报服务
    • DatagramSocket:此类表示用来发送和接收UDP数据报包的套接字。

图示如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图示示例如下:

服务器端:

package top.sharehome.Demo;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;/*** 下面实现了一个服务器端*/
public class ICPServer {public static void main(String[] args) {ServerSocket serverSocket = null;InputStream inputStream = null;OutputStream outputStream = null;try {//使用serverSocket建立服务器端,并设置端口serverSocket = new ServerSocket(8888);//使用serverSocket类中的accept()方法获取接收端,即客户端的对象Socket accept = serverSocket.accept();//使用accept.getInputStream()方法创建输入流并从客户端获取内容inputStream = accept.getInputStream();byte[] arr = new byte[1024];int flag = inputStream.read(arr);System.out.println(new String(arr, 0, flag));System.out.println("accept = " + accept);//accept.getOutputStream()方法撞见一个输出流并向客户端输出内容outputStream = accept.getOutputStream();outputStream.write("thank".getBytes());} catch (IOException e) {e.printStackTrace();} finally {try {if (serverSocket != null) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}try {if (inputStream != null) {inputStream.close();}} catch (IOException e) {e.printStackTrace();}try {if (outputStream != null) {outputStream.close();}} catch (IOException e) {e.printStackTrace();}}}
}

客户端:

package top.sharehome.Demo;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;/*** 下面实现了一个客户端*/
public class ICPclient {public static void main(String[] args) {Socket socket = null;OutputStream outputStream = null;InputStream inputStream = null;try {//使用Socket建立客户端,并指定ip地址和端口socket = new Socket("127.0.0.1", 8888);//调用socket.getOutputStream()方法获取输出流并向服务器端输出内容outputStream = socket.getOutputStream();outputStream.write("Hello".getBytes());//调用socket.getInputStream()方法获取输入流并从服务器端输入内容inputStream = socket.getInputStream();byte[] arr = new byte[1024];int flag = inputStream.read(arr);System.out.println(new String(arr, 0, flag));System.out.println("socket = " + socket);} catch (IOException e) {e.printStackTrace();} finally {try {if (socket != null) {socket.close();}} catch (IOException e) {e.printStackTrace();}try {if (outputStream != null) {outputStream.close();}} catch (IOException e) {e.printStackTrace();}try {if (inputStream != null) {inputStream.close();}} catch (IOException e) {e.printStackTrace();}}}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上传服务器死循环问题

在 I/O 流的学习中,我们结识到了通过循环来快速写入和读取的方法,但是这个循环放在客户端和服务器端之间就会出现很严重的问题,以 客户端通过基础流读取客户端文件数据然后向服务器写入数据,服务器端读取客户端数据后再通过基础流向服务器端文件里 为例:

//客户端相关操作代码:
byte[] bytes = new byte[1024];
int flag = 0;
while ((flag = fileInputStream.read(bytes)) != -1) {outputStream.write(bytes, 0, flag);
}
inputStream = socket.getInputStream();
flag = inputStream.read(bytes);
//服务器端相关操作代码:
byte[] bytes = new byte[1024];
int flag = 0;
while ((flag = inputStream.read(bytes)) != -1) {fileOutputStream.write(bytes, 0, flag);
}

当客户端读取数据到客户端文件末尾处时会返回 -1,然后结束掉客户端的循环,但是由于 read() 方法的阻塞性,服务器端中的 read() 方法会一直等待着客户端继续写入数据,但是此时的客户端并不会再向服务器端传输数据,所以导致了服务器没办法完成该次相应,从而使客户端中的 read() 也进入了阻塞状态,进而进入一种双终端之间的死循环;

解决办法:

再写入完毕之后使用 Socket 类中的 shutdownOutput() 方法手动关闭写入通道,并且告诉对方自己已经写入完毕;

//客户端相关操作代码:
byte[] bytes = new byte[1024];
int flag = 0;
while ((flag = fileInputStream.read(bytes)) != -1) {outputStream.write(bytes, 0, flag);
}
socket.shutdownOutput();  //手动关闭写入通道
inputStream = socket.getInputStream();
flag = inputStream.read(bytes);
//服务器端相关操作代码:
byte[] bytes = new byte[1024];
int flag = 0;
while ((flag = inputStream.read(bytes)) != -1) {fileOutputStream.write(bytes, 0, flag);
}

文件名重复问题

向服务器上传内容就类似于复制粘贴,如果粘贴时的文件名和粘贴路径中的文件有所重复,那么原来的文件就会被覆盖掉,这样的话向服务器上传文件始终只能是一个文件,所以我们要自定义一些文件名,最常见的就是 System.currentTimeMillis() 获取得到毫秒值再加上是 new Random().nextInt() 随机数;

示例如下:

//客户端相关代码:
fileInputStream = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\ImgClient\\1.jpg");  //由客户端读取客户端文件;
//服务器端相关代码:
fileOutputStream = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\ImgServer\\" + System.currentTimeMillis() + new Random().nextInt(999999999) +".jpg");  //由服务器端接收客户端的数据并且将数据打包重命名为System.currentTimeMillis() + new Random().nextInt(999999999).jpg

图片上传案例

示例图片如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

客户端代码:

package top.sharehome.Demo;import java.io.*;
import java.net.Socket;public class ICPclient {public static void main(String[] args) {/*** 我们需要创建四个流* 1.连接服务器* 2.字节流将图片引入* 3.链接对象的字节输出流,将图片写入服务器* 4.读取服务器返回的上传成功的消息*/FileInputStream fileInputStream = null;OutputStream outputStream = null;Socket socket = null;InputStream inputStream = null;try {socket = new Socket("127.0.0.1", 8888);fileInputStream = new FileInputStream("d:\\大学课程学习文档\\java\\Practice\\ImgClient\\1.jpg");outputStream = socket.getOutputStream();byte[] bytes = new byte[1024];int flag = 0;while ((flag = fileInputStream.read(bytes)) != -1) {outputStream.write(bytes, 0, flag);}socket.shutdownOutput();inputStream = socket.getInputStream();flag = inputStream.read(bytes);System.out.println("socket = " + socket);System.out.println(new String(bytes, 0, flag));} catch (IOException e) {e.printStackTrace();} finally {try {if (fileInputStream != null) {fileInputStream.close();}} catch (IOException e) {e.printStackTrace();}try {if (socket != null) {socket.close();}} catch (IOException e) {e.printStackTrace();}}}
}

服务器端代码:

package top.sharehome.Demo;import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;public class ICPServer {public static void main(String[] args) {/*** 我们需要建立三个流* 1.和客户端建立连接* 2.接收客户端传来的数据* 3.返回上传成功的信息*/ServerSocket serverSocket = null;FileOutputStream fileOutputStream = null;InputStream inputStream = null;OutputStream outputStream = null;Socket client = null;try {serverSocket = new ServerSocket(8888);client = serverSocket.accept();fileOutputStream = new FileOutputStream("d:\\大学课程学习文档\\java\\Practice\\ImgServer\\" + System.currentTimeMillis() + new Random().nextInt(999999999) +".jpg");inputStream = client.getInputStream();byte[] bytes = new byte[1024];int flag = 0;while ((flag = inputStream.read(bytes)) != -1) {fileOutputStream.write(bytes, 0, flag);}System.out.println("client = " + client);outputStream = client.getOutputStream();outputStream.write("上传图片成功!".getBytes());} catch (IOException e) {e.printStackTrace();} finally {try {if (serverSocket != null) {serverSocket.close();}} catch (IOException e) {e.printStackTrace();}try {if (fileOutputStream != null) {fileOutputStream.close();}} catch (IOException e) {e.printStackTrace();}try {if (client != null) {client.close();}} catch (IOException e) {e.printStackTrace();}}}
}

打印效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

UDP:DatagramSocket

基于UDP协议的网络编程仍然需要在通信实例的两端各建立一个Socket,但这两个Socket之间并没有虚拟链路,这两个Socket只是发送、接收数据报的对象,Java提供了DatagramSocket对象作为基于UDP协议的Socket,使用DatagramPacket代表DatagramSocket发送、接收的数据报;

DatagramSocket 类的常用方法:

  • public DatagramSocket(int port)创建数据报套接字并将其绑定到本地主机上的指定端口。套接字将被绑定到通配符地址,IP 地址由内核来选择;
  • public DatagramSocket(int port,InetAddress laddr)创建数据报套接字,将其绑定到指定的本地地址。本地端口必须在 0 到 65535 之间(包括两者)。如果 IP 地址为 0.0.0.0,套接字将被绑定到通配符地址,IP 地址由内核选择;
  • public void close()关闭此数据报套接字;
  • public void send(DatagramPacket p)从此套接字发送数据报包。DatagramPacket 包含的信息指示:将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号;
  • public void receive(DatagramPacket p)从此套接字接收数据报包。当此方法返回时,DatagramPacket 的缓冲区填充了接收的数据。数据报包也包含发送方的 IP 地址和发送方机器上的端口号。 此方法在接收到数据报前一直阻塞。数据报包对象的 length 字段包含所接收信息的长度。如果信息比包的长度长,该信息将被截短;

DatagramPacket类的常用方法:

  • public DatagramPacket(byte[] buf,int length) 构造 DatagramPacket,用来接收长度为 length 的数据包。 length 参数必须小于等于 buf.length;
  • public DatagramPacket(byte[] buf,int length,InetAddress address,int port)构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。length 参数必须小于等于 buf.length;
  • public int getLength()返回将要发送或接收到的数据的长度;

示例代码

发送端:

package top.sharehome.Demo;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.ArrayList;public class Send {public static void main(String[] args)throws Exception {
//		1、建立发送端的DatagramSocketDatagramSocket ds = new DatagramSocket();//要发送的数据ArrayList<String> all = new ArrayList<String>();all.add("hello java");all.add("hello C");all.add("hello php");all.add("hello python");//接收方的IP地址InetAddress ip = InetAddress.getByName("127.0.0.1");//接收方的监听端口号int port = 9999;//发送多个数据报for (int i = 0; i < all.size(); i++) {
//			2、建立数据包DatagramPacketbyte[] data = all.get(i).getBytes();DatagramPacket dp = new DatagramPacket(data, data.length, ip, port);
//			3、调用Socket的发送方法ds.send(dp);}//		4、关闭Socketds.close();}
}

接收端:

package top.sharehome.Demo;import java.net.DatagramPacket;
import java.net.DatagramSocket;public class Receive {public static void main(String[] args) throws Exception {
//		1、建立接收端的DatagramSocket,需要指定本端的监听端口号DatagramSocket ds = new DatagramSocket(9999);//一直监听数据while(true){//		2、建立数据包DatagramPacketbyte[] buffer = new byte[1024*64];DatagramPacket dp = new DatagramPacket(buffer , buffer.length);//		3、调用Socket的接收方法ds.receive(dp);//4、拆封数据String str = new String(buffer,0,dp.getLength());System.out.println(str);}}
}

下一章:由浅到深认识Java语言(40):枚举

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OceanBase中NOT EXISTS是否需要被改写

作者简介 张瑞远&#xff0c;曾经从事银行、证券数仓设计、开发、优化类工作&#xff0c;现主要从事电信级IT系统及数据库的规划设计、架构设计、运维实施、运维服务、故障处理、性能优化等工作。 持有Orale OCM,MySQL OCP及国产代表数据库认证。 获得的专业技能与认证包括 Oce…

通知中心架构:打造高效沟通平台,提升信息传递效率

随着信息技术的快速发展&#xff0c;通知中心架构作为一种关键的沟通工具&#xff0c;正逐渐成为各类应用和系统中必不可少的组成部分。本文将深入探讨通知中心架构的意义、设计原则以及在实际场景中的应用。 ### 什么是通知中心架构&#xff1f; 通知中心架构是指通过集中管…

前端学习<二>CSS基础——06-CSS盒模型详解

盒子模型 前言 盒子模型&#xff0c;英文即box model。无论是div、span、还是a都是盒子。 但是&#xff0c;图片、表单元素一律看作是文本&#xff0c;它们并不是盒子。这个很好理解&#xff0c;比如说&#xff0c;一张图片里并不能放东西&#xff0c;它自己就是自己的内容。…

【vue3学习笔记(二)】(第141-143节)初识setup;ref函数_处理基本类型;ref函数_处理对象类型

尚硅谷Vue2.0Vue3.0全套教程丨vuejs从入门到精通 本篇内容对应课程第141-143节 课程 P141节 《初识setup》笔记 1、setup是所有组合式API“表演的舞台”&#xff0c;组件中所用到的所有数据、方法、监视数据、生命周期钩子等都需要配置在setup中。 2、setup的两种返回值&…

JAVA的控制语句

控制语句 分为顺序、选择和循环 顺序结构 先执行a&#xff0c;再执行b 条件判断结构 如果......则....... 循环结构 如果.....则重复执行 条件判断结构&#xff08;选择结构&#xff09; if单分支结构 语法结构&#xff1a; if(布尔表达式){ 语句块 } 注&#xff…

【Java程序员福音】国外Java 程序员开发常用的工具(全)

Java是一门开源语言&#xff0c;所以可以选择的开发环境很多&#xff0c;你适合哪一个呢&#xff1f;整理了一些Java程序员开发常用的工具&#xff0c;需要的同学可以收藏。 1、免费开源Eclipse Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环…

安静:内向性格的竞争力 - 三余书屋 3ysw.net

精读文稿 这期我们介绍的这本书叫做《安静》&#xff0c;副标题是《内向性格的竞争力》。本书共有267页&#xff0c;我会用大约25分钟的时间为你讲述书中的精髓。内向性格具备什么样的竞争力&#xff1f;内向性格的人在人际交往和日常生活中似乎总是吃亏&#xff0c;因为他们不…

汉化必备工具 Poedit Pro 翻译编辑器

特色功能 简单易用的界面&#xff1a; Poedit的界面简洁直观&#xff0c;没有复杂的选项和设置。它专注于提供最基本的翻译编辑功能&#xff0c;使得用户能够快速上手并高效完成翻译工作。多种文件格式支持&#xff1a; Poedit支持多种常见的翻译文件格式&#xff0c;包括Gett…

JAVA WEB 能够实现整个文件夹的上传下载吗?

导入项目&#xff1a; 导入到Eclipse&#xff1a;导入项目 导入到IDEA&#xff1a;导入项目 springboot统一配置&#xff1a;springboot-配置 下载示例&#xff1a; https://gitee.com/xproer/up6-jsp-eclipse/tree/6.5.40/ 工程 NOSQL NOSQL示例不需要任何配置&#xff0c;可…

Jenkins升级中的小问题

文章目录 使用固定版本安装根据jenkins页面下载war包升级jenkins重启jenkins报错问题解决 K8s部署过程中的一些小问题 ##### Jenkins版本小插曲 ​ 在Jenkins环境进行插件安装时全部清一色飘红&#xff0c;发现是因为Jenkins版本过低导致&#xff0c;报错的位置可以找到更新je…

vue纯前端过滤嵌套数据,通过关键字搜索过滤嵌套数据

1.过滤效果&#xff1a; 2. cardList 数据源&#xff1a; [ { "id": 4, "createTime": "2024-03-28 02:47:18", "updateTime": "2024-03-28 02:47:18", "uniqueId": "…

python实战之基础篇(一)

1. 注释 # coding utf-8 # 该注释放到文件第一行, 这个注释告诉python解释器该文件的编码集是UTF-82. 导入语句有三种形式 import <模块名> from <模块名> import <代码元素> from <模块名> import <代码元素> as <代码元素别名>3. 获取…