网络通信快速入门
🏡个人主页 :@ 守夜人st
🚀系列专栏:Java
…持续更新中敬请关注…
🙉博主简介:软件工程专业,在校学生,写博客是为了总结回顾一些所学知识点
目录
- 网络编程
- 实现网络编程的三要素:
- IP地址
- IP地址的分类:
- IP地址形式:
- IP常用命令
- 特殊IP地址:
- IP地址操作类-InetAddress
- 端口
- 协议
- UDP快速入门
- TCP快速入门
- TCP通信引入多线程
- TCP通信——线程池优化
- TCP通信实战案例——即时通信
- TCP通信实战案例——模拟B/S系统
网络编程
什么是网络编程?
- 网络编程可以让程序员与网络上的其他设备中的程序进行数据交互。
网络通信基本模式- 常见的通信模式有如下两种形式:Client-Server(CS)、Browser/Server(BS)
实现网络编程的三要素:
IP地址:设备在网络中的地址,是唯一的标识
端口:应用程序在设备中的唯一标识
协议:数据在网络中传输的规则,常见的协议有UDP协议和TCP协议。
IP地址
IP地址的分类:
IPv4:32位(4字节),采用点分十进制表示法(192.168.1.1)
IPv6:128位(16字节),采用冒分十六进制表示法(ABCD:EF01:2345:6789:ABCD:EF01:2345:6789)
IP地址形式:
公网地址和私有地址(局域网使用)。
192.168开头的就是常见的局域网地址,范围为192.168.0.0——192.168.255.255,专门为组织机构内部使用
IP常用命令
- Ipconfig:查看本机IP地址
- ping IP地址:检查网络是否连通
特殊IP地址:
- 本机IP:127.0.0.1或者localhost:称为回送地址也可称为本地回环地址,只会寻找当前所在本机
IP地址操作类-InetAddress
InetAddress表示Internet协议(IP)地址
| 名称 | 说明 |
|---|---|
| public static InetAddress getLocalHost() | 返回本主机的地址对象 |
| public static InetAddress getByName(String host) | 得到指定主机的IP地址对象,参数是域名或者IP地址 |
| public String getHostName() | 获取此IP地址的主机名 |
| public String getHostAddress() | 返回IP地址字符串 |
| public boolean isReachable(int timeout) | 在指定毫秒内连通该IP地址对应的主机,连通后返回ture |
package com.shouyeren.net_app;import java.net.InetAddress;public class InetAddressDemo01 {public static void main(String[] args) throws Exception {//获取本机IP地址对象InetAddress ip = InetAddress.getLocalHost();//得到指定主机的IP地址对象,参数是域名或者IP地址System.out.println(ip.getHostName());//获取此IP地址的主机名System.out.println(ip.getHostAddress());//获取域名的IP对象InetAddress ip1 = InetAddress.getByName("www.baidu.com");System.out.println(ip1.getHostName());System.out.println(ip1.getHostAddress());//获取公网IP对象InetAddress ip2 = InetAddress.getByName("112.80.248.76");System.out.println(ip2.getHostName());System.out.println(ip2.getHostAddress());//判断是否连通System.out.println(ip1.isReachable(5000));}
}
端口
端口号:标识正在计算机设备上运行的进程(程序),被规定为一个16位的二进制,范围是0——65535
端口类型
- 周知端口:0——1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)
- 注册端口:1024——49151,分配给用户进程或某些应用程序(如Tomcat占用8080,MySQL占用3306)
- 动态端口:49152——65535,之所以称为动态端口,是因为他一般不固定分配某种进程而是动态分配
- 注意:我们自己开发的程序选择注册端口,且一个设备中不能出现两个程序的端口号一样,否则会出错。
协议
- 连接和通信数据的规则被称为网络通信协议
网络通信协议有两套参考模型
- OSI参考模型:世界互联网协议标准,全球通信规范,由于此模型过于理想化,未能在英特网上进行广泛推行
- TCP/IP参考模型:事实上的国际标准
传输的两个常见协议
- TCP(Transmission Control Protocol):传输控制协议
- UDP(User Datagram Protocol):用户数据报协议
TCP协议的特点
- 使用TCP协议,必须双方先建立连接,它是一种面向连接的可靠通信协议
- 传输前,采用”三次握手“方式建立连接,所以是可靠的。
- 在连接中可进行大量数据量的传输。
- 连接、发送数据都需要确认,且传输完毕后,还需释放已建立的连接,通信效率较低
TCP协议通信场景
- 对信息安全要求较高的场景,例如:文件下载、金融等数据通信
UDP协议:
- UDP是一种无连接、不可靠的传输协议
- 将数据源IP、目的地IP和端口封装成数据包,不需要建立连接
- 每个数据包的大小限制在64KB内
- 发送不管对方是否准备好,接收方收到也不进行确认,故是不可靠的
- 可以广播发送,发送数据结束时无需释放资源,开销小,速度快
UDP快速入门
DatagramPacket:数据包对象
构造器 说明 public DatagramPacket(byte[] buf,int length,InetAddress address,int port) 创建发送端数据包对象 buf :要发送的内容,字节数组 ;length :发送内容的字节长度;address:接收端的IP地址对象;port:接收端的端口号 public DatagramPacket(byte[] buf,int length) 创建接受端的数据包对象
public class ClientDemo {public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket();System.out.println("===============客户端启动===============");Scanner sc = new Scanner(System.in);while (true) {System.out.println("请说:");String s = sc.nextLine();if ("exit".equals(s)){System.out.println("下线成功");socket.close();break;}byte[] buf = s.getBytes();DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(),8888);socket.send(packet);}}
}
public class ServerDemo {public static void main(String[] args) throws Exception {System.out.println("==============服务端启动===============");DatagramSocket socket = new DatagramSocket(8888);byte[] buf = new byte[1024*64];DatagramPacket packet = new DatagramPacket(buf, buf.length);while (true) {socket.receive(packet);int len = packet.getLength();String rs = new String(buf,0,len);System.out.println("收到了来自" + packet.getAddress() +" " + packet.getPort() + "的信息:" + rs);}}
}
TCP快速入门
TCP是一种面向连接,安全可靠的传输协议
传输前采用三次握手方式,点对点通信,是可靠的
在连接中可以进行大数据量的传输
package com.shouyeren.net_app.tcp;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;/*** 开发socket网络编程入门案例的服务端*/
public class ServerDemo {public static void main(String[] args) {try {System.out.println("===========服务端启动=============");//1.注册端口ServerSocket serverSocket = new ServerSocket(7777);//必须使用accept方法,等待接收客户端的socket连接请求Socket socket = serverSocket.accept();//从socket通信管道获得一个字节输入流InputStream in = socket.getInputStream();//把自己输入流包装成缓冲字符输入流BufferedReader buf = new BufferedReader(new InputStreamReader(in));//按照行读取消息String msg;while ((msg = buf.readLine()) != null){System.out.println(socket.getRemoteSocketAddress() + ":" + msg);}} catch (Exception e) {e.printStackTrace();}}
}
package com.shouyeren.net_app.tcp;import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;/*** 完成socket网络编程入门案例的客户端的开发*/
public class ClientDemo {public static void main(String[] args) {try {//1. 创建客户端的Socket对象,请求与服务端连接Socket socket = new Socket("127.0.0.1",7777);//2. 使用socket对象调用getOutputStream()方法得到字节输出流OutputStream os = socket.getOutputStream();//3. 把低级的字节输出流包装成打印流PrintStream printStream = new PrintStream(os);Scanner sc = new Scanner(System.in);while (true) {//4. 发送消息System.out.println("请说:");String msg = sc.nextLine();printStream.println(msg);printStream.flush();}} catch (Exception e) {e.printStackTrace();}}
}
TCP通信引入多线程
需求一个服务端能够同时接收多个客户端发送的消息
package com.shouyeren.net_app.tcp;import java.net.ServerSocket;
import java.net.Socket;/*** 开发socket网络编程入门案例的服务端*/
public class ServerDemo {public static void main(String[] args) {try {System.out.println("===========服务端启动=============");//1.注册端口ServerSocket serverSocket = new ServerSocket(7777);while (true) {//必须使用accept方法,等待接收客户端的socket连接请求Socket socket = serverSocket.accept();System.out.println(socket.getRemoteSocketAddress() + "连接成功!!!");//把新连接的Socket交给有个独立的线程处理并启动线程new ServerReaderThread(socket).start();}} catch (Exception e) {e.printStackTrace();}}
}
package com.shouyeren.net_app.tcp;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;public class ServerReaderThread extends Thread{private Socket socket;public ServerReaderThread(Socket socket){this.socket = socket;}@Overridepublic void run() {try {//从socket通信管道获得一个字节输入流InputStream in = socket.getInputStream();//把自己输入流包装成缓冲字符输入流BufferedReader buf = new BufferedReader(new InputStreamReader(in));//按照行读取消息String msg;while ((msg = buf.readLine()) != null){System.out.println(socket.getRemoteSocketAddress() + ":" + msg);}} catch (Exception e) {System.out.println(socket.getRemoteSocketAddress() + "下线了!!!");}}
}
TCP通信——线程池优化
完成socket通信,使用线程池完成优化
package com.shouyeren.net_app.socket_threadpool;import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;/*** 开发socket网络编程入门案例的服务端*/
public class ServerDemo {//使用静态变量记住一个线程池对象private static ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());public static void main(String[] args) {try {System.out.println("===========服务端启动=============");//1.注册端口ServerSocket serverSocket = new ServerSocket(7777);while (true) {//必须使用accept方法,等待接收客户端的socket连接请求Socket socket = serverSocket.accept();System.out.println(socket.getRemoteSocketAddress() + "连接成功!!!");pool.execute(new ServerReaderRunnable(socket));}} catch (Exception e) {e.printStackTrace();}}
}
package com.shouyeren.net_app.socket_threadpool;import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;public class ServerReaderRunnable implements Runnable{private Socket socket;public ServerReaderRunnable(Socket socket){this.socket = socket;}@Overridepublic void run() {try {//从socket通信管道获得一个字节输入流InputStream in = socket.getInputStream();//把自己输入流包装成缓冲字符输入流BufferedReader buf = new BufferedReader(new InputStreamReader(in));//按照行读取消息String msg;while ((msg = buf.readLine()) != null){System.out.println(socket.getRemoteSocketAddress() + ":" + msg);}} catch (Exception e) {System.out.println(socket.getRemoteSocketAddress() + "下线了!!!");}}
}
线程池优化的优势在哪里
- 服务端可以复用线程处理多个客户端,可以避免系统瘫痪
- 适合客户端通信时长较短的场景
TCP通信实战案例——即时通信
package com.shouyeren.net_app.tcp_sms;import java.io.*;
import java.net.Socket;
import java.util.Scanner;/*** 完成socket网络编程入门案例的客户端的开发*/
public class ClientDemo {public static void main(String[] args) {try {//1. 创建客户端的Socket对象,请求与服务端连接Socket socket = new Socket("127.0.0.1",8888);new ClientReaderThread(socket).start();//2. 使用socket对象调用getOutputStream()方法得到字节输出流OutputStream os = socket.getOutputStream();//3. 把低级的字节输出流包装成打印流PrintStream printStream = new PrintStream(os);Scanner sc = new Scanner(System.in);while (true) {//4. 发送消息System.out.println("请说:");String msg = sc.nextLine();printStream.println(msg);printStream.flush();}} catch (Exception e) {e.printStackTrace();}}
}
class ClientReaderThread extends Thread{private Socket socket;public ClientReaderThread(Socket socket){this.socket = socket;}@Overridepublic void run() {try {//从socket通信管道获得一个字节输入流InputStream in = socket.getInputStream();//把自己输入流包装成缓冲字符输入流BufferedReader buf = new BufferedReader(new InputStreamReader(in));//按照行读取消息String msg;while ((msg = buf.readLine()) != null) {System.out.println("收到消息 : " + msg);}} catch (Exception e) {System.out.println("服务端把你踢出去了!!!");}}}
package com.shouyeren.net_app.tcp_sms;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;/*** 开发socket网络编程入门案例的服务端*/
public class ServerDemo {//定义一个静态的List集合处在当前在线的Socketpublic static List<Socket> allOnlineSocket = new ArrayList<>();public static void main(String[] args) {try {System.out.println("===========服务端启动=============");//1.注册端口ServerSocket serverSocket = new ServerSocket(8888);while (true) {//必须使用accept方法,等待接收客户端的socket连接请求Socket socket = serverSocket.accept();System.out.println(socket.getRemoteSocketAddress() + "连接成功!!!");allOnlineSocket.add(socket);//把新连接的Socket交给有个独立的线程处理并启动线程new ServerReaderThread(socket).start();}} catch (Exception e) {e.printStackTrace();}}
}class ServerReaderThread extends Thread{private Socket socket;public ServerReaderThread(Socket socket){this.socket = socket;}@Overridepublic void run() {try {//从socket通信管道获得一个字节输入流InputStream in = socket.getInputStream();//把自己输入流包装成缓冲字符输入流BufferedReader buf = new BufferedReader(new InputStreamReader(in));//按照行读取消息String msg;while ((msg = buf.readLine()) != null) {System.out.println(socket.getRemoteSocketAddress()+" : " + msg);//把收到的消息转发给所有在线的客户端sendMsgToAll(msg);}} catch (Exception e) {System.out.println(socket.getRemoteSocketAddress() + "已下线!!!");ServerDemo.allOnlineSocket.remove(socket);}}private void sendMsgToAll(String msg) throws Exception {for (Socket socket : ServerDemo.allOnlineSocket) {PrintStream printStream = new PrintStream(socket.getOutputStream());printStream.println(msg);printStream.flush();}}}
TCP通信实战案例——模拟B/S系统
服务器必须给浏览器响应HTTP协议格式的数据,否则浏览器不识别。
package com.shouyeren.net_app.BS;import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;public class ServerDemo {public static void main(String[] args) {try {//1.注册端口ServerSocket serverSocket = new ServerSocket(8888);while (true) {//必须使用accept方法,等待接收客户端的socket连接请求Socket socket = serverSocket.accept();System.out.println(socket.getRemoteSocketAddress() + "连接成功!!!");//把新连接的Socket交给有个独立的线程处理并启动线程new ServerReaderThread(socket).start();}} catch (Exception e) {e.printStackTrace();}}
}class ServerReaderThread extends Thread{private Socket socket;public ServerReaderThread(Socket socket){this.socket = socket;}@Overridepublic void run() {try {PrintStream printStream = new PrintStream(socket.getOutputStream());//协议类型和版本 响应成功消息printStream.println("HTTP/1.1 200 OK");//响应的数据类型 文本/网页printStream.println("Content-Type:text/html;charset=UTF-8");//这里需要一个空行printStream.println();//响应数据正文printStream.println("<span style='color:red;font-size:90px'> 响应数据!!! </span>");printStream.close();} catch (Exception e) {e.printStackTrace();}}
}

相关文章:
网络通信快速入门
🏡个人主页 : 守夜人st 🚀系列专栏:Java …持续更新中敬请关注… 🙉博主简介:软件工程专业,在校学生,写博客是为了总结回顾一些所学知识点 目录网络编程实现网络编程的三要素&#x…...
【阅读文档】Vue.js 2.0 之教程文档
系列文章目录 提示:阅读本章之前,请先阅读目录 文章目录系列文章目录前言兼容性Devtools开发版和生产版安装Vue-cli编译器Vue.js 是什么最基本的Vuev-bind 指令split 和 reverse 搭配v-model 双向绑定vue-component 定义组件v-bindObject.freeze箭头函数…...
Docker【基本使用】
1:启动Docker1.1:操作systemctl start docker.service1.2:常见问题【第一步】启动docker,提示启动失败,查询运行状态systemctl start docker.service【第二步】查询docker运行状态,提示不支持SELinux【第三…...
算法leetcode|39. 组合总和(rust重拳出击)
文章目录39. 组合总和:样例 1:样例 2:样例 3:提示:分析:题解:rustgoccpythonjava39. 组合总和: 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找…...
JavaSE学习笔记总结day18
今日内容 零、 复习昨日 一、作业 二、进程与线程 三、创建线程 四、线程的API 五、线程状态 六、线程同步 零、 复习昨日 晨考 一、作业 见答案 二、进程与线程[了解] 一个进程就是一个应用程序,进程包含线程 一个进程至少包含一个线程,大部分都是有多条线程在执行任务(多线…...
HybridFusion: LiDAR和视觉交叉源点云融合
一、基本信息 研究方向: 大场景点云配准 HybridFusion: 它可以在户外大型场景中从不同视角记录交叉源密集点云。 团队链接:http://www.adv-ci.com 视频链接: https://www.bilibili.com/video/BV1vM41147yD/?spm_id_from333.337.sear…...
走进JVM
JVM的位置 在操作系统之上,可以想象成一个软件,Java程序都运行在上面 JVM结构图 JVM调优的位置 99%的调优在堆中,极少数在方法区中 很多第三方插件都是在执行引擎那块地方做出修改而来,比如Lombook在程序运行时动态生成get/s…...
C语言-基础了解-15-C函数指针与回调函数
C函数指针与回调函数 一、函数指针 函数指针是指向函数的指针变量。 通常我们说的指针变量是指向一个整型、字符型或数组等变量,而函数指针是指向函数。 函数指针可以像一般函数一样,用于调用函数、传递参数。 函数指针变量的声明: type…...
react和vue在响应式上的不同理解
vue和react的区别总是被提及,关于这个问题最近也有了自己的想法。我认为它们之间最大的区别是对于响应数据变化的实现方式不同。 vue实现响应的方法是,首先收集依赖这个数据的副作用(视图更新、计算属性等),当数据修改…...
多线程二 多线程了解与使用
文章目录synchronized 锁有两种synchronized异常捕获主线程和子线程volatile的作用notify是随机启动等待线程中的一个synchronized 锁有两种 类对象类的实例 第一种:锁类对象,有两种方式,如下: // 方法一:synchroni…...
嵌入式 Linux 的僵尸进程是什么?
目录 1、什么是僵尸进程? 2、僵尸进程的目的 3、怎么避免僵尸进程? 4、僵尸进程的处理方法 4.1 wait()连接 4.2 waitpid()函数 1、什么是僵尸进程? 首先内核会释放终止进程(调用了 exit …...
【刷题笔记】笔记一
1.自守数牛客链接解析:1.自守数的结尾肯定是 0,1,5,62.把数字转换为string类(方便比较)3.直接find在s2 里面 使用find查找另一个即可。#include <iostream> #include<string> using namespace …...
浏览器主页被hao123劫持的解决方案
大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。喜欢通过博客创作的方式对所学的知识进行总结与归纳,不仅形成深入且独到的理…...
华为OD机试题 - 热点网络统计(JavaScript)| 含代码编写思路
华为OD机试题 最近更新的博客使用说明本篇题解:热点网络统计题目输入输出描述示例一输入输出示例二输入输出Code解题思路华为OD其它语言版本最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华…...
IT项目经理的自我修养手册
在不断进步的时代,任何岗位职责都是一个责任、权力与义务的综合体,有多大的权力就应该承担多大的责任,有多大的权力和责任应该尽多大的义务,任何割裂开来的做法都会发生问题。那么作为IT项目经理的岗位职责,我大概列举…...
2023年软考中级电子商务设计师考什么?
首先,电子商务设计师属于软考中级,因此难度也不是特别大。但并不是说就完全没有难度,难度还是有的,像上午题一般把基本知识点掌握了,是没什么问题的,重点就在于下午题会比较难。 接下来我们来剖析一下考试…...
现在的00后太强了,几个问题差点给我问懵了
前言 我们公司刚入职一个00后小伙,今天在办公室交流了一下,他问我会不会自动化测试,我说懂一点,然后直接问了我几个自动化测试问题,差点直接给我问懵了! 问题如下: 我们在制定自动化测试实施…...
$3 : 水项目实战 - 水果库存系统
javase知识点复习: final关键字:http://t.csdn.cn/bvFgu 接口的定义,特性,实现,继承:http://t.csdn.cn/tbXl3 异常:http://t.csdn.cn/VlS0Z DAO的概念和角色(设计理念)&a…...
毕业设计 基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测
基于STM32单片机无线ZIGBEE智能大棚土壤湿度光照检测1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 STM32F103C8T6核心系统电路设计2.2 光敏采集电路设计2.3 温度采集电路设计3、部分代码展示3.1 读取DS18B20温度值3.2 定时器初始化1、项目简介 选题指导,…...
华为OD机试真题Java实现【相对开音节】真题+解题思路+代码(20222023)
相对开音节 题目 相对开音节构成的结构为辅音+元音(aeiou)+辅音(r除外)+e,常见的单词有bike、cake等。 给定一个字符串,以空格为分隔符,反转每个单词中的字母,若单词中包含如数字等其他非字母时不进行反转。 反转后计算其中含有相对开音节结构的子串个数(连续的子串…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
