synchronized与volatile关键字
1.synchronized的特性
1.1互斥
synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized 中时, 其他线程如果也执行到 同一个对象 synchronized 就会阻塞等待.
进入 synchronized 修饰的代码块, 相当于 加锁
退出 synchronized 修饰的代码块, 相当于 解锁
synchronized用的锁是存在Java对象头里的。
可以粗略理解成, 每个对象在内存中存储的时候, 都存有一块内存表示当前的 "锁定" 状态(类似于厕 所的 "有人/无人").
如果当前是 "无人" 状态, 那么就可以使用, 使用时需要设为 "有人" 状态.
如果当前是 "有人" 状态, 那么其他人无法使用, 只能排队
理解 "阻塞等待".
针对每一把锁, 操作系统内部都维护了一个等待队列. 当这个锁被某个线程占有的时候, 其他线程尝试进行加锁, 就加不上了, 就会阻塞等待, 一直等到之前的线程解锁之后, 由操作系统唤醒一个新的线程, 再来获取到这个锁.
注意:
上一个线程解锁之后, 下一个线程并不是立即就能获取到锁. 而是要靠操作系统来 "唤醒". 这 也就是操作系统线程调度的一部分工作.
假设有 A B C 三个线程, 线程 A 先获取到锁, 然后 B 尝试获取锁, 然后 C 再尝试获取锁, 此时 B 和 C 都在阻塞队列中排队等待. 但是当 A 释放锁之后, 虽然 B 比 C 先来的, 但是 B 不一定就能获取到锁, 而是和 C 重新竞争, 并不遵守先来后到的规则.(非公平锁)
synchronized的底层是使用操作系统的mutex lock实现的.
1.2刷新内存
synchronized 的工作过程:
1. 获得互斥锁
2. 从主内存拷贝变量的最新副本到工作的内存
3. 执行代码
4. 将更改后的共享变量的值刷新到主内存
5. 释放互斥锁
所以sychronized也可以保证内存可见性
1.3可重入
synchronized 同步块对同一条线程来说是可重入的,不会出现自己把自己锁死的问题;
理解 "把自己锁死"
一个线程没有释放锁, 然后又尝试再次加锁.
按照之前对于锁的设定, 第二次加锁的时候, 就会阻塞等待. 直到第一次的锁被释放, 才能获取到第二个锁. 但是释放第一个锁也是由该线程来完成, 结果这个线程已经躺平了, 啥都不想干了, 也就无 法进行解锁操作. 这时候就会 死锁.
这样的锁称为不可重入锁
Java 中的 synchronized 是 可重入锁, 因此没有上面的问题.
代码示例
在下面的代码中, increase 和 increase2 两个方法都加了 synchronized, 此处的 synchronized 都是针对 this 当前对象加锁的.
在调用 increase2 的时候, 先加了一次锁, 执行到 increase 的时候, 又加了一次锁. (上个锁还没释放, 相当于连续加两次锁)
这个代码是完全没问题的. 因为 synchronized 是可重入锁
static class Counter {public int count = 0;synchronized void increase() {count++;}synchronized void increase2() {increase();}
}
在可重入锁的内部, 包含了 "线程持有者" 和 "计数器" 两个信息.
如果某个线程加锁的时候, 发现锁已经被人占用, 但是恰好占用的正是自己, 那么仍然可以继续获取到锁, 并让计数器自增.
解锁的时候计数器递减为0的时候, 才真正释放锁. (才能被别的线程获取到)
2.synchronized使用示例
synchronized 本质上要修改指定对象的 "对象头". 从使用角度来看, synchronized 也势必要搭配一个具体的对象来使用.
2.1直接修饰普通方法:
锁的SynchronizedDemo对象
public class SynchronizedDemo{public synchronized void method(){}
}
2.2修饰静态方法
锁的 SynchronizedDemo 类的对象
public class SynchronizedDemo{public synchronized static void method(){}
}
2.3修饰代码块
明确指定锁哪个对象
锁当前对象:
public class SynchronizedDemo{public synchronized void method(){synchronized(this){}}
}
锁类对象
public class SynchronizedDemo {public void method() {synchronized (SynchronizedDemo .class) {}}
}
我们要重点理解,synchronized锁的是什么,两个线程竞争同一把锁,才会产生阻塞等待
两个线程分别尝试获取两把不同的锁,不会产生竞争
3.Java 标准库中的线程安全类
Java 标准库中很多都是线程不安全的. 这些类可能会涉及到多线程修改共享数据, 又没有任何加锁措施.
ArrayList、LinkedList、HashMap、TreeMap、HashSet、TreeSet、StringBuilder
但是还有一些是线程安全的. 使用了一些锁机制来控制.
Vector (不推荐使用)、HashTable (不推荐使用)、 ConcurrentHashMap、 StringBuffer
StringBuffer 的核心方法都带有synchronized
还有的虽然没有加锁, 但是不涉及 "修改", 仍然是线程安全的(string)
4.volatile关键字
4.1volatile能保证内存可见性
volatile 修饰的变量, 能够保证 " 内存可见性".
代码在写入 volatile 修饰的变量的时候:
改变线程工作内存中volatile变量副本的值,将改变后的副本的值从工作内存刷新到主内存
代码在读取 volatile 修饰的变量的时候:
从主内存中读取volatile变量的最新值到线程的工作内存中,从工作内存中读取volatile变量的副本
前面我们讨论内存可见性时说了, 直接访问工作内存(实际是 CPU 的寄存器或者 CPU 的缓存), 速度非常快, 但是可能出现数据不一致的情况.
加上 volatile , 强制读写内存. 速度是慢了, 但是数据变的更准确了.
代码示例:
创建两个线程 t1 和 t2
t1 中包含一个循环, 这个循环以 flag == 0 为循环条件.、
t2 中从键盘读入一个整数, 并把这个整数赋值给 flag.
预期当用户输入非 0 的值的时候, t1 线程结束.
package thread;
import java.util.Scanner;
public class ThreadDemo9 {// 内存可见性private static int isQuit = 0;public static void main(String[] args) {Thread t1 = new Thread(() -> {while (isQuit == 0) {;//do nothing}System.out.println("t1 执行结束. ");});Thread t2 = new Thread(() -> {Scanner scanner = new Scanner(System.in);System.out.println("请输入 isQuit 的值: ");isQuit = scanner.nextInt();});t1.start();t2.start();}}
执行效果:当用户输入非0值时,t1线程循环不会结束!(显然与预期不符)
程序在编译运行的时候,Java编译器和jvm可能会对代码做出一些“优化”
编译器优化本质上是靠代码,智能的对你写的代码进行分析判断,进行调整,这个调整在大多数情况都是没问题的,但是在多线程环境下有可能会出现差错!
isQuit==0 本质上是两个指令
1.load(读内存)读内存操作,速度非常慢
2.jcmp(比较并跳转) 寄存器操作,速度非常快
此时,编译器就发现这个逻辑中代码要反复的快速读取同一个内存的值,并且这个内存的值读出来每次都相同,此时编译器把load操作优化掉了!后续都不再执行load,直接拿寄存器中的数据进行比较!
编译器没想到在另一个线程中把isQuit的值改了,这就是内存可见性问题!
volatile关键字可以弥补上述缺口,把volatile用来修饰一个变量之后,编译器就明白这个变量是“易变的”,就不会按照上述方式优化,就可以保证t1在循环过程中,始终都能读取内存中的数据
volatile本质上是保证变量的内存可见性(禁止该变量的读操作被优化到寄存器中)
如果给flag加上volatile
当用户输入非0值时,t1线程循环能够立即结束
4.2volatile不保证原子性
volatile 和 synchronized 有着本质的区别. synchronized 能够保证原子性, volatile 保证的是内存可见性
代码示例
这个是最初的演示线程安全的代码.
给 increase 方法去掉 synchronized
给 count 加上 volatile 关键字.
package thread;public class ThreadDemo8 {static class Counter {public volatile int count = 0;void increase() {count++;}}public static void main(String[] args) throws InterruptedException {final Counter counter = new Counter();Thread t1 = new Thread(() -> {for (int i = 0; i < 50000; i++) {counter.increase();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 50000; i++) {counter.increase();}});t1.start();t2.start();t1.join();t2.join();System.out.println(counter.count);}
}
最终 count 的值仍然无法保证是 100000
1.synchronized 也能保证内存可见性
synchronized 既能保证原子性, 也能保证内存可见性.
对上面的代码进行调整:
掉 flag 的 volatile
给 t1 的循环内部加上 synchronized, 并借助 counter 对象加锁.
package thread;
import java.util.Scanner;
public class ThreadDemo9 {// 内存可见性
// private volatile static int isQuit = 0;private static int isQuit = 0;public static void main(String[] args) {Thread t1 = new Thread(() -> {while (isQuit == 0) {synchronized (ThreadDemo9.class){;}}System.out.println("t1 执行结束. ");});Thread t2 = new Thread(() -> {Scanner scanner = new Scanner(System.in);System.out.println("请输入 isQuit 的值: ");isQuit = scanner.nextInt();});t1.start();t2.start();}}
相关文章:
synchronized与volatile关键字
1.synchronized的特性 1.1互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized 中时, 其他线程如果也执行到 同一个对象 synchronized 就会阻塞等待. 进入 synchronized 修饰的代码块, 相当于 加锁 退出 synchronized 修饰的代码块, 相当于 解锁 syn…...
Python基础之运算符操作
在Python中,运算符的作用就是用于执行各种的运算操作,常见的运算符有算数运算符、比较运算符、逻辑运算符、赋值运算符、成员运算符、身份运算符等。下面我们就来看看在Python中这些运算的详细操作。 算术运算符 算术运算符是用来执行一些基本的数学运…...
【busybox记录】【shell指令】uniq
目录 内容来源: 【GUN】【uniq】指令介绍 【busybox】【uniq】指令介绍 【linux】【uniq】指令介绍 使用示例: 去除重复行 - 默认输出 去除重复行 - 跳过第n段(空格隔开),比较n1以后的内容,去重 去…...
Nginx从入门到精通速成
文章目录 一. **Nginx** **的简介**1.1 什么是 **nginx**1.2 正向代理1.3 反向代理1.4 **负载均衡**1.5 动静分离 二. **Nginx** **的安装**三. **Nginx** **的常用的命令**四. **Nginx** **的配置文件**五. **Nginx** **配置实例**反向代理实例**1**5.1 实现效果5.2 准备工作5…...
Flutter笔记:Widgets Easier组件库(4)使用按钮组
Flutter笔记 Widgets Easier组件库(4):使用按钮组 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress…...
Docker常用命令 镜像库设置
Docker常用命令 & 镜像库设置 1. 镜像操作2. 容器操作3. 网络操作4. Docker Compose操作5. Docker volume操作6. Docker run介绍7. 镜像库设置 1. 镜像操作 列出本地所有的镜像 docker images从远程仓库拉取镜像到本地 docker pull <image_name>删除本地的指定镜像…...
无人零售,重塑购物新纪元
在这个快节奏的时代,科技的每一次跃进都在悄无声息地改变着我们的生活方式。而今,无人零售正以雷霆之势,颠覆传统购物模式,为我们带来前所未有的便捷与智能体验。想知道无人零售如何彻底改变我们的购物方式吗?跟随我&a…...
【图片格式转换】ICO、JPG、JPEG、PNG图片格式在线免费转换
ICO、JPG、JPEG、PNG图片格式转换 图片格式转换 https://orcc.online 支持ICO、JPG、JPEG、PNG等 主页 https://www.orcc.online 其他工具 pdf在线免费转word文档 https://orcc.online/pdf 时间戳转换 https://orcc.online/timestamp Base64 编码解码 https://orcc.onlin…...
通过自然语言处理执行特定任务的AI Agents;大模型控制NPC执行一系列的动作;个人化的电子邮件助手Panza
✨ 1: OpenAgents 通过自然语言处理执行特定任务的AI代理 OpenAgents是一个开放平台,旨在使语言代理(即通过自然语言处理执行特定任务的AI代理)的使用和托管变得更加便捷和实用。它特别适合于日常生活中对数据分析、工具插件获取和网络浏览…...
4.2 JavaScript语法
4.2.1 JavaScript大小写 在JavaScript中大小写是严格区分的,无论是变量、函数名称、运算符和其他语法都必须严格按照要求的大小写进行声明和使用。例如变量hello与变量HELLO会被认为是完全不同的内容。 4.2.2 JavaScript分号 很多编程语言(例如C、Java和…...
面试二十五、remove和earse的区别
vector中erase的作用是删除掉某个位置position或一段区域(begin, end)中的元素,减少其size,返回被删除元素下一个元素的位置。 vector中remove的作用是将范围内为val的值都remove到后面,返回新的_last值(非val部分的en…...
普乐蛙元宇宙VR体验馆设备集体亮相VR文旅景区展
普乐蛙全国巡展又双叒叕开始了! 这次来到的是“好客山东”↓↓ 山东2024休闲旅游产业展 4月25日至27日,2024休闲旅游产业展在临沂国际博览中心举办。本次展会以“潮购文旅好品,乐享时尚生活”为主题,汇聚全国文旅产业上下游500多家企业、上万…...
北京大学-知存科技存算一体联合实验室揭牌,开启知存科技产学研融合战略新升级
5月5日,“北京大学-知存科技存算一体技术联合实验室”在北京大学微纳电子大厦正式揭牌,北京大学集成电路学院院长蔡一茂、北京大学集成电路学院副院长鲁文高及学院相关负责人、知存科技创始人兼CEO王绍迪、知存科技首席科学家郭昕婕博士及企业研发相关负…...
项目总结(一)docker总结
目录 一、引言 二、docker ------>2.1、docker介绍 ------>2.2、与虚拟机的区别 ------>2.3、Docke基本概念 ------>2.4、Docker内部结构 ------>2.5、Windows上使用docker ------>2.6、Linux上使用Docker ------>2.7、Docker常用命令 ------&g…...
深圳比创达EMC|EMC一站式解决方案:助力电子产品电磁兼容性升级
在当今电子信息技术飞速发展的时代,电磁兼容性(EMC)问题日益凸显,成为制约电子产品性能和质量的关键因素。为了满足市场对EMC问题的迫切需求,EMC一站式解决方案应运而生,成为解决EMC问题的有效途径。 一、…...
万兆以太网MAC设计(11)完整UDP协议栈仿真
文章目录 前言一、模块接口二、IP模块与ARP模块之间的联系三、整体协议栈仿真总结: 前言 目前除了巨帧处理逻辑之外,所有的准备工作都已经结束了,先进行整体的功能验证。 一、模块接口 所有模块接口皆采用AXIS数据流的形式,其中…...
【牛客】【模板】差分
原题链接:登录—专业IT笔试面试备考平台_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 差分模板。 b[0]a[0]; b[1]a[1]-a[0]; b[2]a[2]-a[1]; ...... b[n-1]a[n-1]-a[n-2]; b[n]a[n]-a[n-1]; 差分标记:b[l]k,b…...
鸿蒙内核源码分析(中断管理篇) | 江湖从此不再怕中断
关于中断部分系列篇将用三篇详细说明整个过程. 中断概念篇 中断概念很多,比如中断控制器,中断源,中断向量,中断共享,中断处理程序等等.本篇做一次整理.先了解透概念才好理解中断过程.用海公公打比方说明白中断各个概念…...
php使用rabbitmq
这里使用的是 php-amqplib composer require php-amqplib/php-amqplib生产端send.php <?phprequire_once "./vendor/autoload.php";use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage;//交换机名称 $exc_name exchange.can…...
前端发起网络请求的几种常见方式(XMLHttpRequest、FetchApi、jQueryAjax、Axios)
摘要 前端发起网络请求的几种常见方式包括: XMLHttpRequest (XHR): 这是最传统和最常见的方式之一。它允许客户端与服务器进行异步通信。XHR API 提供了一个在后台发送 HTTP 请求和接收响应的机制,使得页面能够在不刷新的情况下更新部分内容…...
通过氧气退火增强β-Ga₂O₃二极管.中国科技大学和河北半导体研究所的研究人员在这一特定领域取得了最新重大进展
上图所示:(a)增加台面有助于提高β-Ga2O3肖特基势垒二极管的阻断电压(b)。 氧气退火和自对准台面终端使β-Ga2O3二极管进一步走向商业化。 虽然β-Ga2O3电力电子技术已经取得了长足的进步,但仍然存在挑战&…...
C语言猜数字游戏
用C语言实现猜数字游戏,电脑随机给出一个范围内的数字,用户在终端输入数字,去猜大小;对比数字,电脑给出提示偏大还是偏小;不断循环,直到正确 #include <stdio.h> #include <time.h>…...
笔记本连接不上远程桌面,笔记本无法连接远程桌面的可能原因及解决方法
在使用远程桌面功能时,笔记本无法成功连接的情况可能由多种原因引起。为了有效地解决这个问题,我们需要逐一排查这些可能的原因,并采取相应的解决措施。 首先,网络连接稳定性是远程桌面连接成功的关键。请确保笔记本和远程计算机之…...
Android 音视频播放器 Demo(一)—— 视频解码与渲染
本篇作为 Android 音视频实战系列的第二篇文章,主要介绍视频解码与渲染过程。本系列文章目录如下: Android 音视频基础知识 Android 音视频播放器 Demo(一)—— 视频解码与渲染 Android 音视频播放器 Demo(二ÿ…...
Flutter笔记:Widgets Easier组件库(3)使用按钮组件
Flutter笔记 Widgets Easier组件库(3):使用按钮组件 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddre…...
荷香堪筑梦,鸳鸯和月寻。(变相BFS搜索)
本题链接:登录—专业IT笔试面试备考平台_牛客网 题目: 样例: 输入 3 4 2 .... ***. ..a. 输出 yes 思路: 根据题意,这里 1 s 可以移动多次,我们将每次可以移动避开雪的的位置存储起来,判断当…...
智慧公厕建设,打造智慧城市基础设施新亮点
公共厕所是城市基础设施的重要组成部分,而智慧公厕的建设则是现代城市管理的创新之举。为了实现公厕的精细化管理和提供更便捷的服务,推进智慧公厕建设必须要实现技术融合、业务融合、数据融合的目标,跨越层级、地域、系统、部门和业务的限制…...
Kubernetes 教程:在 Containerd 容器中使用 GPU
原文链接:Kubernetes 教程:在 Containerd 容器中使用 GPU 云原生实验室本文介绍了如何在使用 Containerd 作为运行时的 Kubernetes 集群中使用 GPU 资源。https://fuckcloudnative.io/posts/add-nvidia-gpu-support-to-k8s-with-containerd/ 前两天闹得沸沸扬扬的事件不知道…...
LNMP部署wordpress
1.环境准备 总体架构介绍 序号类型名称外网地址内网地址软件02负载均衡服务器lb0110.0.0.5192.168.88.5nginx keepalived03负载均衡服务器lb0210.0.0.6192.168.88.6nginx keepalived04web服务器web0110.0.0.7192.168.88.7nginx05web服务器web0210.0.0.8192.168.88.8nginx06we…...
本地部署大模型ollama+docker+open WebUI/Lobe Chat
文章目录 大模型工具Ollama下载安装运行Spring Ai 代码测试加依赖配置写代码 ollama的web&Desktop搭建部署Open WebUI有两种方式Docker DesktopDocker部署Open WebUIDocker部署Lobe Chat可以配置OpenAI的key也可以配置ollama 大模型的选择 本篇基于windows环境下配置 大模型…...
qt学习篇---界面按键关联(信号和槽)
目录 1.qt基础 2.做一个界面 创建project UI界面设计 信号和槽 1.控件改名字 2.什么是信号和槽 3.怎么关联信号和槽 自动关联 手动关联 1.qt基础 qt可移植性强,不久会用到MCU。很有意义学习 2.做一个界面 创建project 不要中文路径 选择QWidget .pro文件…...
python Django 的内置权限系统或自定义模型来存储更复杂的角色和权限关系
在 Django 中,管理用户权限和角色通常涉及到使用 Django 的内置权限系统或自定义模型来存储更复杂的角色和权限关系。下面是一个基本的指南,说明如何在 Django 中为后台管理系统分配权限并将其保存在数据库中,同时结合 Vue.js 和 Element UI 作为前端框架。 后端(Django)…...
不上班,我靠这5份赚钱副业养活了自己
在这个快节奏的社会里,很多人都在为生活奔波忙碌。今天,就让我来跟大家分享一下我的“躺平”秘籍吧! 这一个月来,我没有上班,但好在有副业养活自己。有时候,我真的觉得有一份自己喜欢的自媒体副业挺好的。…...
强一致性的皇冠:分布式事务模型的至高法则揭秘
关注微信公众号 “程序员小胖” 每日技术干货,第一时间送达! 引言 分布式事务模型是分布式系统设计的核心,关键在于保证数据一致性和事务完整性,尤其强调强一致性。诸如2PC、3PC、Saga、TCC等模型与协议,应运而生以解…...
mac/windows下安装docker,minikube
1、安装docker Get Started | Docker 下载安装docker 就行 启动后,就可以正常操作docker了 使用docker -v 验证是否成功就行 2、安装minikube,是基于docker-desktop的 2.1、点击设置 2.2、选中安装,这个可能需要一点时间 这样安装后&…...
【爬虫】fake_useragent的使用、BeautifulSoup(find()和find_all())
1 fake_useragent 2 BeautifulSoup 3 Beautiful Soup库的find()和find_all() 1 fake_useragent fake_useragent是一个Python库,用于生成随机的用户代理字符串。 用户代理是在HTTP请求中发送给服务器的一种标识,它告诉服务器发送请求的客户端的类型、版本…...
ComfyUI中图像亮度/对比度/饱和度处理
用上面这个节点可以同时设置图片的亮度、对比度和饱和度。 【保姆级教程】一口气分享在ComfyUI中常用的30多种基本图像处理方式 更多好玩且实用AIGC工作流和节点 星球号:32767063 本期资料链接 往期学习资料 整理AI学习资料库...
基于FPGA的DDS波形发生器VHDL代码Quartus仿真
名称:基于FPGA的DDS波形发生器VHDL代码Quartus仿真(文末获取) 软件:Quartus 语言:VHDL 代码功能: DDS波形发生器VHDL 1、可以输出正弦波、方波、三角波 2、可以控制输出波形的频率 DDS波形发生器原理…...
C++语法|可调用对象与function类型
文章目录 引入function的使用function类型的典型应用function类型的原理实现代码优化可变参的函数对象 引入 还记得C语言中的函数指针数组吗? 我们通过函数指针数组实现一个,图书管理系统的界面: #include <stdio.h> void doShowAllB…...
Linux学习之路 -- 文件 -- 文件描述符
前面介绍了与文件相关的各种操作,其中的各个接口都离不开一个整数,那就是文件描述符,本文将介绍文件描述符的一些相关知识。 目录 <1>现象 <2>原理 文件fd的分配规则和利用规则实现重定向 <1>现象 我们可以先通过prin…...
JDK动态代理和Cglib动态代理区别
1.如果目标类实现了接口,将会使用JDK动态代理,否则会使用Cglib动态代理; 2.JDK代理使用自己的字节码生成工具生成代理对象,而Cglib会使用ASM字节码生成工具去生成; 3.JDK动态代理是通过反射的方式去实现代理对象的所有方法,通过…...
牛客 | 字符金字塔
请打印输出一个字符金字塔,字符金字塔的特征请参考样例 #include <stdio.h> #include <string.h> using namespace std; int main() {char c;scanf("%c", &c);for (int i 1; i < (c - 64); i)//第一个循环决定了有多少行{//c:67 第三…...
【计算机科学速成课】笔记三——操作系统
文章目录 18.操作系统问题引出——批处理设备驱动程序多任务处理虚拟内存内存保护Unix 18.操作系统 问题引出—— Computers in the 1940s and early 50s ran one program at a time. 1940,1950 年代的电脑,每次只能运行一个程序 A programmer would write one at…...
用js代码实现贪吃蛇小游戏
js已经学了大部分了,现在就利用我所学的js知识试试做贪吃蛇小游戏吧 以下部分相关图片以及思路笔记均出自渡一陈老师的视频 首先制作简单的静态页面,添加贪吃蛇移动的背景和相关图片,比如开始游戏等等 将各个功能均封装在函数中࿰…...
微信小程序+esp8266温湿度读取
本文主要使用微信小程序显示ESP8266读取的温湿度并通过微信小程序控制LED灯。小程序界面如下图所示 原理讲解 esp8266 通过mqtt发布消息,微信小程序通过mqtt 订阅消息,小程序订阅后,就可以实时收到esp8266 传输来的消息。 个人可免费注册五个微信小程序账号,在微信小程序官…...
软考中级-软件设计师(十)网络与信息安全基础知识
一、网络概述 1.1计算机网络的概念 计算机网络的发展:具有通信功能的单机系统->具有通信功能的多机系统->以共享资源为目的的计算机网络->以局域网及因特网为支撑环境的分布式计算机系统 计算机网络的功能:数据通信、资源共享、负载均衡、高…...
推荐一个好用的命令行工具ShellGPT
ShellGPT 配置安装常用功能聊天写命令并执行 高级功能函数调用角色管理 总结 这两天突然想到,现有的很多工具都在被大模型重构,比如诞生了像perplexity.ai 这种新交互形式的搜索引擎,就连wps也推出了AI服务,甚至都可以直接生成ppt…...
Prompt提示词教程 | 提示工程指南 | 提示词示例 入门篇
在上一节中,我们介绍并给出了如何赋能大语言模型的基本示例。如果还没看而且是刚入门的同学建议看下,有个基本概念。 Prompt提示词教程 | 提示工程指南 | 提示工程简介https://blog.csdn.net/HRG520JN/article/details/138523705在本节中,我…...
uniapp + uView动态表单校验
项目需求:动态循环表单,并实现动态表单校验 页面: <u--form label-position"top" :model"tmForm" ref"tmForm" label-width"0px" :rulesrules><div v-for"(element, index) in tmForm…...
【Linux】HTTPS
欢迎来到Cefler的博客😁 🕌博客主页:折纸花满衣 🏠个人专栏:Linux 目录 👉🏻HTTPS协议概念👉🏻加密为什么要进行加密 👉🏻常见的加密方式对称加密…...