IO/NIO交互模拟及渐进式实现
IO
IO Server
public class SocketServer {public static void main(String[] args) {//server编号和client编号对应,优缺点注释在server端//server1();//server2();server3();}/*** server1的缺点:* 1、accept()方法阻塞了线程,要等客户端连接后才能继续处理(一个客户端连接,对应一个服务端处理线程)* 2、当客户端与服务端完成一次交互后,程序就结束了* 3、流关闭代码比较臃肿、BufferedWriter的内容需要在末尾加'\n'* 4、交互的内容写死,不可以通过控制台输入* 5、端口号固定、ip固定、readLine读取一行等等*/public static void server1() {ServerSocket serverSocket = null;BufferedReader bufferedReader = null;BufferedWriter bufferedWriter = null;try {serverSocket = new ServerSocket(8999);//阻塞至客户端连接成功Socket socket = serverSocket.accept();bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//readLine会阻塞String s = bufferedReader.readLine();System.out.println("服务端接收到客户端的消息:" + s);bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));bufferedWriter.write("服务端发送消息给客户端\n");bufferedWriter.flush();} catch (IOException e) {throw new RuntimeException(e);} finally {//各个try catch 必须分开写,聚合成一个会导致一个流关闭异常,无法进入其他流的关闭流程if(serverSocket != null) {try {serverSocket.close();} catch (IOException e) {throw new RuntimeException(e);}}if(bufferedWriter != null) {try {bufferedWriter.close();} catch (IOException e) {throw new RuntimeException(e);}}//只需要关闭外层的缓冲区,其close方法内部关闭了了传入的流//如果不关闭,只是等待jvm兜底finally,会在不确定的时间内对资源造成占用(如果是文件读写会对文件描述符fd的占用)if (bufferedReader != null) {try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}}/*** server2优点:* 1、服务端和客户端可以任意次交互,可以连续发送消息* 2、优化了流关闭的写法** server2的缺点:* 1、accept()方法阻塞了线程,要等客户端连接后才能继续处理(一个客户端连接,对应一个服务端处理线程)* 2、cpu空转* 3、ip固定等等* 4、一个服务端只能和一个客户端交互*/public static void server2() {System.out.println("请输入端口号,并等待客户端连接...");try (BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));ServerSocket serverSocket = new ServerSocket(Integer.valueOf(consoleReader.readLine()));Socket socket = serverSocket.accept();BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));){System.out.println("客户端已连接,开始和客户端交互...");//这个循环保证可以连续发送或者接收多条消息while (true) {if (bufferedReader.ready()) {System.out.println("收到客户端的消息:" + bufferedReader.readLine());}if (consoleReader.ready()) {printWriter.println(consoleReader.readLine());printWriter.flush();}}//只能发一次接收一次
// while (true) {
// System.out.println("收到客户端的消息:" + bufferedReader.readLine());
//
// printWriter.println(consoleReader.readLine());
// printWriter.flush();
// }} catch (IOException e) {throw new RuntimeException(e);}}/*** server3优点:* 一个服务端可以和一个客户端交互* 加上了线程池** server3的缺点:* 1、accept()方法阻塞了线程,要等客户端连接后才能继续处理(一个客户端连接,对应一个服务端处理线程)* 2、cpu空转* 3、ip固定等等* 4、如果开启多个客户端,因System.in被服务端共享,所以服务端发送消息后,客户端会随机接收其中个别消息*/public static void server3() {ThreadPoolExecutor pool = new ThreadPoolExecutor(0, Runtime.getRuntime().availableProcessors() * 2,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());System.out.println("请输入端口号,并等待客户端连接...");try (BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));ServerSocket serverSocket = new ServerSocket(Integer.valueOf(consoleReader.readLine()));){//这个循环保证多个客户端连接while (true) {Thread.sleep(1000);Socket socket = serverSocket.accept();System.out.println("客户端已连接,开始和客户端交互...");pool.submit(new Thread(()->{try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));) {while (true) {Thread.sleep(1000);if(bufferedReader.ready()) {System.out.println("收到客户端"+ Thread.currentThread() +"的消息:" + bufferedReader.readLine());}if (consoleReader.ready()) {printWriter.println(consoleReader.readLine());printWriter.flush();}}} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {if(socket != null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}}}));}} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
IO Client
public class SocketClient {public static void main(String[] args) {//client1();//client2();client3();}public static void client1() {Socket socket = null;BufferedReader bufferedReader = null;BufferedWriter bufferedWriter = null;try {socket = new Socket("127.0.0.1", 8999);bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));//换行符必不可少,不然服务端readLine()无法判断一行已经写完bufferedWriter.write("客户端发送消息给服务端\n");bufferedWriter.flush();bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));String s = bufferedReader.readLine();System.out.println("客户端接收到服务端的消息:" + s);} catch (IOException e) {throw new RuntimeException(e);} finally {if(socket != null) {try {socket.close();} catch (IOException e) {throw new RuntimeException(e);}}if(bufferedWriter != null) {try {bufferedWriter.close();} catch (IOException e) {throw new RuntimeException(e);}}if (bufferedReader != null) {try {bufferedReader.close();} catch (IOException e) {throw new RuntimeException(e);}}}}public static void client2() {System.out.println("请输入端口号:");try (BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));Socket socket = new Socket("127.0.0.1", Integer.valueOf(consoleReader.readLine()));PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));){System.out.println("连接成功,开始和服务端交互");//可以连续发送或者接收多条消息while (true) {Thread.sleep(1000);if (bufferedReader.ready()) {System.out.println("收到服务端的消息:" + bufferedReader.readLine());}if (consoleReader.ready()) {printWriter.println(consoleReader.readLine());printWriter.flush();}}//只能发一次接收一次
// while (true) {
// printWriter.println(consoleReader.readLine());
// printWriter.flush();
//
// System.out.println("收到服务端的消息:" + bufferedReader.readLine());
// }} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}public static void client3() {System.out.println("请输入端口号:");try (BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));Socket socket = new Socket("127.0.0.1", Integer.valueOf(consoleReader.readLine()));PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));){System.out.println("连接成功,开始和服务端交互");//可以连续发送或者接收多条消息while (true) {if (bufferedReader.ready()) {System.out.println("收到服务端的消息:" + bufferedReader.readLine());}if (consoleReader.ready()) {printWriter.println(consoleReader.readLine());printWriter.flush();}}} catch (IOException e) {throw new RuntimeException(e);}}
}
NIO
NIO Server
public class SocketServer {public static void main(String[] args) {//server1();//server2();//server3();//server4();server5();}/*** 优点:NIO非阻塞方式,连接不会阻塞、读写不会阻塞* 缺点:* 1、当客户端与服务端完成一次交互后,程序就结束了* 2、交互的内容写死,不可以通过控制台输入* 3、cpu空转* 4、未使用selector多路复用器,其编程其实还是类似与BIO形式(服务端还是每个线程对应一个客户端)*/private static void server1() {try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();){serverSocketChannel.socket().bind(new InetSocketAddress(9999));serverSocketChannel.configureBlocking(false);//accept设置了非阻塞,因此需要放置在循环中使用,否则程序直接结束了while (true) {Thread.sleep(1000);SocketChannel socketChannel = serverSocketChannel.accept();if(socketChannel != null) {System.out.println("客户端已连接,开始和客户端交互...");socketChannel.configureBlocking(false);ByteBuffer readBuffer = ByteBuffer.allocate(1024);socketChannel.read(readBuffer);readBuffer.clear();System.out.println("接收到客户端消息: " + new String(readBuffer.array(), "utf-8").trim());ByteBuffer writeBuffer = ByteBuffer.wrap("发送消息给客户端".getBytes());socketChannel.write(writeBuffer);}}} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}/*** 改良:* 1、支持客户端和服务端一对一交互,多发* 缺点:* 1、不支持一个客户端对多个服务端* 2、如果开启多个客户端,因System.in被服务端共享,所以服务端发送消息后,客户端会随机接收其中个别消息* 3、cpu空转* 4、未使用selector多路复用器,其编程其实还是类似与BIO形式(服务端还是每个线程对应一个客户端)*/private static void server2() {try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));){serverSocketChannel.socket().bind(new InetSocketAddress(9999));serverSocketChannel.configureBlocking(false);//accept设置了非阻塞,因此需要放置在循环中使用,否则程序直接结束了while (true) {Thread.sleep(1000);SocketChannel socketChannel = serverSocketChannel.accept();if(socketChannel != null) {System.out.println("客户端已连接,开始和客户端交互...");socketChannel.configureBlocking(false);ByteBuffer readBuffer = ByteBuffer.allocate(1024);while (true) {if(socketChannel.read(readBuffer) > 0) {System.out.println("接收到客户端消息: " + new String(readBuffer.array(), "utf-8").trim());readBuffer.clear();}if (consoleReader.ready()) {ByteBuffer writeBuffer = ByteBuffer.wrap(consoleReader.readLine().getBytes());socketChannel.write(writeBuffer);writeBuffer.clear();}Thread.sleep(1000);}}}} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}/*** 改良:* 1、支持一个客户端对多个服务端* 缺点:* 1、cpu空转* 2、未使用selector多路复用器,其编程其实还是类似与BIO形式(服务端还是每个线程对应一个客户端)*/private static void server3() {try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));) {serverSocketChannel.socket().bind(new InetSocketAddress(9999));serverSocketChannel.configureBlocking(false);List<SocketChannel> socketChannels = new ArrayList<>();//accept设置了非阻塞,因此需要放置在循环中使用,否则程序直接结束了while (true) {Thread.sleep(1000);boolean ready = consoleReader.ready();byte[] bytes = null;if (ready) {bytes = consoleReader.readLine().getBytes();}//调用一次accept再次使用会变成成null,除非有新的客户端连接SocketChannel socketChannel = serverSocketChannel.accept();if (socketChannel != null) {socketChannels.add(socketChannel);socketChannel.configureBlocking(false);System.out.println("客户端已连接,开始和客户端交互...");}for (SocketChannel channel : socketChannels) {ByteBuffer readBuffer = ByteBuffer.allocate(1024);if (channel.read(readBuffer) > 0) {System.out.println("接收到客户端消息: " + new String(readBuffer.array(), "utf-8").trim());readBuffer.clear();}if (ready) {ByteBuffer writeBuffer = ByteBuffer.wrap(bytes);channel.write(writeBuffer);writeBuffer.clear();}}}} catch (IOException e) {throw new RuntimeException(e);} catch (InterruptedException e) {throw new RuntimeException(e);}}/*** 改良:* 1、支持一个客户端对多个服务端 (服务端发送消息,客户端都能收到,所有客户端发送消息服务端都能收到)* 2、相对与server3多线程方式,服务端只需要启动一个主线程即可与所有客户端交互,* 缺点:* 1、cpu空转* 2、未使用selector多路复用器,其编程其实还是类似与BIO形式(服务端还是每个线程对应一个客户端)*/static final List<SocketChannel> socketChannels4 = new CopyOnWriteArrayList<>();private static void server4() {try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));) {serverSocketChannel.socket().bind(new InetSocketAddress(9999));serverSocketChannel.configureBlocking(false);//accept设置了非阻塞,因此需要放置在循环中使用,否则程序直接结束了while (true) {SocketChannel socketChannel = serverSocketChannel.accept();if (socketChannel != null) {System.out.println("客户端已连接,开始和客户端交互...");socketChannel.configureBlocking(false);socketChannels4.add(socketChannel);}Iterator<SocketChannel> iterator = socketChannels4.iterator();boolean ready = consoleReader.ready();byte[] writeBytes = null;if (ready) {writeBytes = consoleReader.readLine().getBytes();}while (iterator.hasNext()) {ByteBuffer readBuffer = ByteBuffer.allocate(1024);SocketChannel channel = iterator.next();if (channel.read(readBuffer) > 0) {System.out.println("接收到客户端消息: " + new String(readBuffer.array(), "utf-8").trim());readBuffer.clear();}if (ready) {ByteBuffer writeBuffer = ByteBuffer.wrap(writeBytes);channel.write(writeBuffer);writeBuffer.clear();}}Thread.sleep(1000);}} catch (IOException | InterruptedException e) {throw new RuntimeException(e);}}/*** 改良:* 1、支持一个客户端对多个服务端 (服务端发送消息,客户端都能收到,所有客户端发送消息服务端都能收到)* 2、相对与server3多线程方式,服务端只需要启动一个主线程即可与所有客户端交互,* 缺点:* 1、cpu空转* 2、未使用selector多路复用器,其编程其实还是类似与BIO形式(服务端还是每个线程对应一个客户端)*/private static void server5() {try (ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();Selector selector = Selector.open();BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));) {serverSocketChannel.socket().bind(new InetSocketAddress(9999));serverSocketChannel.configureBlocking(false);//将serverSocketChannel注册到selector, 并监听accept事件serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);List<SocketChannel> socketChannels = new ArrayList<>();while (true) {//非阻塞selector.select(1000);Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();if(selectionKey.isAcceptable()) {SocketChannel socketChannel = serverSocketChannel.accept();System.out.println("客户端已连接,开始和客户端交互...");socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);socketChannels.add(socketChannel);} else if(selectionKey.isReadable()) {SocketChannel socketChannel = (SocketChannel)selectionKey.channel();ByteBuffer readBuffer = ByteBuffer.allocate(1024);if (socketChannel.read(readBuffer) > 0) {System.out.println("接收到客户端消息: " + new String(readBuffer.array(), "utf-8").trim());readBuffer.clear();}}iterator.remove();}if(consoleReader.ready()) {byte[] bytes = consoleReader.readLine().getBytes();for (SocketChannel socketChannel : socketChannels) {ByteBuffer writeBuffer = ByteBuffer.wrap(bytes);socketChannel.write(writeBuffer);writeBuffer.clear();}}}} catch (IOException e) {throw new RuntimeException(e);}}}
NIO Client
public class SocketClient {public static void main(String[] args) {//client1();//client2_3_4();client5();}private static void client1() {try (SocketChannel socketChannel = SocketChannel.open();){socketChannel.configureBlocking(false);socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));while (!socketChannel.finishConnect()) {Thread.sleep(1000);System.out.println("正在连接客户端...");}ByteBuffer writeBuffer = ByteBuffer.wrap("向服务端发送消息".getBytes());socketChannel.write(writeBuffer);writeBuffer.clear();ByteBuffer readBuffer = ByteBuffer.allocate(1024);while (true) {if(socketChannel.read(readBuffer) > 0) {System.out.println("接收到服务端消息: " + new String(readBuffer.array(), "utf-8").trim());readBuffer.clear();break;}Thread.sleep(1000);}} catch (IOException | InterruptedException e) {throw new RuntimeException(e);}}private static void client2_3_4() {try (SocketChannel socketChannel = SocketChannel.open();BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));){socketChannel.configureBlocking(false);socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));while (!socketChannel.finishConnect()) {Thread.sleep(1000);System.out.println("正在连接客户端...");}ByteBuffer readBuffer = ByteBuffer.allocate(1024);while (true) {if(socketChannel.read(readBuffer) > 0) {System.out.println("接收到服务端消息: " + new String(readBuffer.array(), "utf-8").trim());readBuffer.clear();}if (consoleReader.ready()) {ByteBuffer writeBuffer = ByteBuffer.wrap(consoleReader.readLine().getBytes());socketChannel.write(writeBuffer);writeBuffer.clear();}Thread.sleep(1000);}} catch (IOException | InterruptedException e) {throw new RuntimeException(e);}}private static void client5() {try (SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9999));Selector selector = Selector.open();BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));){socketChannel.configureBlocking(false);socketChannel.register(selector, SelectionKey.OP_READ);while (true) {selector.select(1000);Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();if (selectionKey.isReadable()) {SocketChannel channel = (SocketChannel) selectionKey.channel();ByteBuffer readBuffer = ByteBuffer.allocate(1024);if(channel.read(readBuffer) > 0) {System.out.println("接收到服务端消息: " + new String(readBuffer.array(), "utf-8").trim());readBuffer.clear();}}iterator.remove();}if (consoleReader.ready()){ByteBuffer writeBuffer = ByteBuffer.wrap(consoleReader.readLine().getBytes());socketChannel.write(writeBuffer);writeBuffer.clear();}}} catch (IOException e) {throw new RuntimeException(e);}}}
相关文章:
IO/NIO交互模拟及渐进式实现
IO IO Server public class SocketServer {public static void main(String[] args) {//server编号和client编号对应,优缺点注释在server端//server1();//server2();server3();}/*** server1的缺点:* 1、accept()方法阻塞了线程,要等客户端…...
springboot+html实现密码重置功能
目录 登录注册: 前端: chnangePssword.html 后端: controller: Mapper层: 逻辑: 登录注册: https://blog.csdn.net/m0_67930426/article/details/133849132 前端: 通过点击忘记密码跳转…...
LeetCode 2525. 根据规则将箱子分类【模拟】1301
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
atcoder [Road of the King] 题解(DP好题)
题面 简要题意:有一个 n n n 个点的图,目前一条边都没有。有一个人在 1 1 1 号点要进行 m m m 次移动, 终点不必是 1 1 1 号点。加入第 i i i 次的从 u u u 移动到了 v v v, 那么 u u u 到 v v v 之间出现一条有向边。问…...
CImageList 图像列表
一、CImageList类Create函数参数解析 BOOL Create(int cx,int cy,UINT nFlags,int nInitial,int nGrow ); 1.1) cx,cy:图片的实际像素宽与高; nFlags:创建图像列表的类型,包括4/8/16/24/32/位色; nFlags确定建立图…...
【OpenGL】四、坐标系统和摄像机
坐标转换 文章目录 坐标转换坐标系统的转换局部空间(Local Space)->世界空间(World Space)世界空间(World Space)->观察空间(View Space/View Space)裁剪空间(Clip Space)MVP矩阵 坐标系统的转换 了解坐标系统和空间变换之前需要先了解…...
使用vcpkg管理依赖第三库
文章目录 使用vcpkg管理依赖第三库vcpkg安装vcpkg经典模式使用从仓库列表搜索依赖项从某个基线版本的列表中查询某个依赖项信息安装依赖库 vcpkg清单模式的使用vcpkg清单模式的使用例子说明 使用vcpkg管理依赖第三库 vcpkg 有两种操作模式:经典模式和清单模式。 在…...
Android渲染一个列表的过程,并提供动态改变样式
1、index.xml 布局文件,我省略了其他代码,我们需要recyclerview保证在规定范围内,如果列表元素过多可以滑动 <LinearLayoutandroid:layout_width"match_parent"android:layout_height"match_parent"android:layout_…...
Leetcode—260.只出现一次的数字III【中等】
2023每日刷题(三) Leetcode—260.只出现一次的数字III 借助lowbit的解题思想 参考的灵茶山艾府大神的题解 实现代码 /*** Note: The returned array must be malloced, assume caller calls free().*/ int* singleNumber(int* nums, int numsSize, in…...
Mysql 约束,基本查询,复合查询与函数
文章目录 约束空属性约束默认值约束zerofill主键约束自增长约束唯一键约束外键约束 查询select的执行顺序单表查询排序 updatedelete整张表的拷贝复合语句group by分组查询 函数日期函数字符串函数数学函数其他函数 复合查询合并查询union 约束 空属性约束 两个值:…...
web前端基础CSS------美化页面“footer”部分
一,实验代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>关于我们</title><style type"text/css">#footer{margin: 10px 0px;background: #f5f5f5;border: top 1px solid #eee ;}#f…...
在中国,技术到底有多有用?
🙌秋名山码民的主页 😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 获取源码,添加WX 目录 前言1.…...
《动手学深度学习 Pytorch版》 9.2 长短期记忆网络(LSTM)
解决隐变量模型长期信息保存和短期输入缺失问题的最早方法之一是长短期存储器(long short-term memory,LSTM)。它与门控循环单元有许多一样的属性。长短期记忆网络的设计比门控循环单元稍微复杂一些,却比门控循环单元早诞生了近 2…...
计算机操作系统-第十一天
目录 1、进程的状态 创建态与就绪态 运行态 终止态 新建态 结束态 进程状态的转换 进程的组织方式 链接方式(常见) 索引方式(少见) 本节思维导图 1、进程的状态 创建态与就绪态 1、进程正在被创建时,处于…...
Flutter视图原理之StatefulWidget,InheritedWidget
目录 StatefulElement1. 构造函数2. build3. _firstBuild3. didChangeDependencies4. setState InheritedElement1. Element类2. _updateInheritance3. InheritedWidget数据向下传递3.1 dependOnInheritedWidgetOfExactType 4. InheritedWidget的状态绑定4.1. ProxyElement 在f…...
观察者模式-对象间的联动
有个商城小程序,用户希望当有新品上市的时候能通知他们。这样用户就可以不要时刻盯着小程序了。在这个场景中,用户向小程序订阅了一个服务——发送新品短信。小程序在有新品上线时负责向订阅客户发出这个消息。 这就是发布-订阅模式,也称观察…...
Webpack十大缺点:当过度工程化遇上简单的静态页面
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...
新手指南|如何快速参与Moonbeam Ignite
Moonbeam Ignite是社区熟悉的有奖链上交互活动,将有300万枚GLMR作为生态激励注入Moonbeam生态系统,体验MoonbeamMoonbeam生态的应用即可获取相应Token奖励。Beamex/Beamswap、Moonwell和Gamma作为首批参与Moonbeam Ignite的三家项目方,将在活…...
VR航天科普主题公园模拟太空舱体验馆vr航天模拟体验设备
VR航天航空体验馆巡展是一项非常受欢迎的展览活动,可以让公众在现场体验到航天飞行的乐趣。 普乐蛙VR展览组织者会设计一个航天航空主题的VR体验馆,并在馆内设置各种航天航空相关的展示内容,如太空舱、火箭发射、星际航行等。 其次࿰…...
Spring Boot OAuth 2.0整合详解
目录 一、Spring Boot 2.x 示例 1、初始化设置 2、设置重定向URI 3、配置 application.yml 4、启动应用程序 二、Spring Boot 2.x 属性映射 二、CommonOAuth2Provider 三、配置自定义提供者(Provider)属性 四、覆盖 Spring Boot 2.x 的自动配置…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
