【MicroPython】Picoweb加载静态资源错误

最近用ESP32做WEB界面,使用Picoweb做WEB服务,但是需要加载静态资源时出现错误 Traceback (most recent call last): File “/lib/picoweb/init.py”, line 206, in _handle File “/lib/picoweb/init.py”, line 291, in handle_static File “/lib/picoweb/init.py”, line 276, in sendfile File “/lib/pkg_resources.py”, line 16, in resource_stream AttributeError: ‘module’ object has no attribute 'path’ 几乎翻遍了百度没发现解决方法,看来这个组件很少有人用,只好到bing翻翻,终于在GITHUB上找到解决方案,特此记录一下,免得下次找不到了。 其实解决的方法也很简单,只要把 app = picoweb.WebApp(__name__) 改为 app = picoweb.WebApp(None) 就行了。

用Python画圣诞树

拿去给自己所思所念之人 import turtle as t # as就是取个别名,后续调用的t都是turtle from turtle import * import random as r import time n = 100.0 speed("fastest") # 定义速度 screensize(bg='black') # 定义背景颜色,可以自己换颜色 left(90) forward(3 * n) color("orange", "yellow") # 定义最上端星星的颜色,外圈是orange,内部是yellow begin_fill() left(126) for i in range(5): # 画五角星 forward(n / 5) right(144) # 五角星的角度 forward(n / 5) left(72) # 继续换角度 end_fill() right(126) def drawlight(): # 定义画彩灯的方法 if r.randint(0, 30) == 0: # 如果觉得彩灯太多,可以把取值范围加大一些,对应的灯就会少一些 color('tomato') # 定义第一种颜色 circle(6) # 定义彩灯大小 elif r.

2021-12-15 网工基础(十一) VLAN的基本原理、接口类型、Access、Trunk

VLAN基础 二 VLAN的基本原理 1 以太网二层接口类型 Access接口 交换机上常用来连接用户PC、服务器等终端设备的接口。Access接口所连接的这些设备的网卡往往只收发无标记帧。Access接口只能加入一个VLAN。 Trunk接口 Trunk接口允许多个VLAN的数据帧通过,这些数据帧通过802.1QTag实现区分。Trunk接口常用于交换机之间的互联,也用于连接路由器、防火墙等设备的子接口。 Hybrid接口(华为设备默认) Hybrid接口与Trunk接口类似,也允许多个VLAN的数据帧通过,这些数据帧通过802.1QTag实现区分。用户可以灵活指定Hybrid接口在发送某个(或某些)VLAN的数据帧时是否携带Tag。 同一VLAN下设备之间的互相通信称为二层透传。 2 Access接口的实现原理 实现原理描述:终端发送的数据帧(Untagged帧,指未被标记的数据帧)进入交换机的Access接口后,会被加上一个标记(tag),这个标记用于表示当前端口号的PVID的所属的VLAN号(VLAN ID),默认(default)情况下交换机所有端口都属于VLAN 1,被加上这个标记的数据只会向被允许这个VLAN号通过的端口去转发,如果它的VLAN ID与端口的PVID不同时,数据帧会被丢弃(即做到了隔离广播域的效果),而当这个数据帧到达它的目标端口号后,这个标记就会被剥离,避免将打了标记的数据包传给终端。 注:VLAN 1强制无法删除。 实验:观察交换机的 VLAN 和 VLAN活动状态 接上篇博文的中的实验---搭建简单VLAN2021-12-15 网工基础(十)TCP的三次握手、四次挥手、UDP协议、数据的封装和解封、VLAN基础_x629242的博客-CSDN博客 查看VLAN命令:display vlan <Huawei>display vlan The total number of vlans is : 3 -------------------------------------------------------------------------------- U: Up; D: Down; TG: Tagged; UT: Untagged; MP: Vlan-mapping; ST: Vlan-stacking; #: ProtocolTransparent-vlan; *: Management-vlan; -------------------------------------------------------------------------------- VID Type Ports -------------------------------------------------------------------------------- 1 common UT:GE0/0/5(D) GE0/0/6(D) GE0/0/7(D) GE0/0/8(D) GE0/0/9(D) GE0/0/10(D) GE0/0/11(D) GE0/0/12(D) GE0/0/13(D) GE0/0/14(D) GE0/0/15(D) GE0/0/16(D) GE0/0/17(D) GE0/0/18(D) GE0/0/19(D) GE0/0/20(D) GE0/0/21(D) GE0/0/22(D) GE0/0/23(D) GE0/0/24(D) 2 common UT:GE0/0/1(U) GE0/0/2(U) 3 common UT:GE0/0/3(U) GE0/0/4(U) VID Status Property MAC-LRN Statistics Description -------------------------------------------------------------------------------- 1 enable default enable disable VLAN 0001 2 enable default enable disable VLAN 0002 3 enable default enable disable VLAN 0003 查看端口VLAN活动状态命令:display port vlan active

linux中软链接的使用方法

在 Linux 中的连结有两种,一种是类似 Windows 的快捷方式功能的档案,可以让你快速的链接到目标档案(或目彔); 另一种则是透过文件系统的 inode 连结来产生新的文档名,而不是产生新档案!这种称为实体链接 (hard link)。 Hard Link (实体链接, 硬式连结或实际连结),这种链接实际中用的比较少,这里先不讲,以后再讲。 Symbolic Link (符号链接,亦即是快捷方式)。 Symbolic link 就是在建立一个独立的文档,而这个文档会让数据的读取指向他 link 的那个文档! 1.创建软链接 [root@www ~]# ln [-sf] 来源文件 目标文件 选项与参数: -s :如果不加任何参数就进行连结,那就是 hard link,至亍 -s 就是 symbolic link -f :如果 目标文件 存在时,就主动的将目标文件直接移除后再建立! 例子: [root@www ~]# ln -s /etc/crontab crontab2 [root@www ~]# ll -i /etc/crontab /root/crontab2 1912701 -rw-r--r-- 2 root root 255 Jan 6 2007 /etc/crontab 654687 lrwxrwxrwx 1 root root 12 Oct 22 13:58 /root/crontab2 -> /etc/crontab

Python模块之Matplotlib模块学习笔记

目录 一、绘图基础知识 二、相关函数简介 三、绘图步骤 1、Figure 2、Axes 3、绘图属性设置 4、添加图表标题和坐标轴标题 5、图例说明 6、绘图的注释 7、区间上下限 8、绘图的填充 9、设置网格线 10、区间分段 11、布局 12、轴相关 四、基本绘图2D 1、线图 2、散点图 3、条形图 4、直方图 5、饼图 6、箱型图 7、气泡图 8、等高线(轮廓图) 9、制作组合图表 在Jupyter notebook中进行交互式绘图,需要执行一下语句% matplotlib notebook 一、绘图基础知识 二、相关函数简介 #导入matplotlib的pyplot模块 import matplotlib.pyplot as plt figure():创建一个新的绘图窗口。 figtext():为figure添加文字 axes():为当前figure添加一个坐标轴 plot():绘图函数 polar():绘制极坐标图 axis():获取或设置轴属性的边界方法(坐标的取值范围) clf : 清除当前figure窗口 cla : 清除当前axes窗口 close : 关闭当前figure窗口 subplot : 一个图中包含多个axes text(): 在轴上添加文字 title(): 设置当前axes标题 xlabel/ylabel:设置当前X轴或Y轴的标签 hist():绘制直方图 hist2d():绘制二维在直方图 hold :设置当前图窗状态;off或者on imread():读取一个图像,从图形文件中提取数组 legend():为当前axes放置标签 pie():绘制饼状图 scatter():做一个X和Y的散点图,其中X和Y是相同长度的序列对象 stackplot():绘制一个堆叠面积图 acorr():绘制X的自相关函数 annotate():用箭头在指定的数据点创建一个注释或一段文本 bar():绘制垂直条形图 barh():绘制横向条形图 barbs():绘制一个倒钩的二维场 三、绘图步骤 1、Figure 绘图之前,我们需要一个Figure对象,可以理解成我们需要一张画板才能开始绘图

亲测:华为老爷机安装谷歌框架

这两天我花了些时间瞎折腾了一番,好消息是:折腾成功。 在此记录下来,希望可以帮助有同样苦恼的老哥。 基本环境: 手机:华为Nova 2s。 目标:运行谷歌框架 这台华为的老爷机Nova 2s,因为工作原因需要给它装上谷歌框架,以及其他一大堆的谷歌全家桶。 鸿蒙 一开始手机运行的最新的鸿蒙系统,操作体验和各项功能还不错。于是网上找到了GMS安装器,点击一键安装后,提示重启。重启之后,重新进入谷歌安装器,还是同样的重启提示,这意味着,这款安装器可能不能在鸿蒙上顺利运行。最后的结果会是无限重启。 降级到9.1 使用华为手机助手的系统更新功能,将运行鸿蒙系统的手机接到电脑,然后可以降级到上一个旧版本,也就是EMUI 9.1。这个版本我之前测试过,肯定是无法安装谷歌框架的,所以完成降级之后,没有多想,继续降级到EMUI 9.0。 9.0也不大行 网上的说法是一般旧版本的9.0可以用来安装谷歌框架。我抱着极大的自信开始进行安装,测试过了各种谷歌框架安装器,例如上面说的GMS安装器,同样的也是提示重启,后面进入无线重启,也测试过其他的,例如HiGoPlay安装器和GO谷歌安装器。其中,HiGoPlay安装器可以顺利完成谷歌三件套(Google服务框架,Google Play服务,Google Play App),但是当我启动Google Play时,点击登录按钮时没有任何反应。看来这个版本还是有问题。 继续降级到8.0 9.0的安装失败,对我的自信心来了一次很大的打击。一个晚上过去,我决定继续降级。 继续使用华为手机助手,降级至上一个版本8.0。降级过程没有太大的问题,谢天谢地。 运行8.0的系统后,手机的各项功能基本正常。然后首先尝试GMS安装器,这次也是提示重启。我乖乖地照做,重启之后,再次进入安装器,这次终于提示框架安装成功,心中的激动像滔滔流水一般,把我乐的。 然后后面的过程就比较简单了,直接使用其他安装器把剩下的几个套件给安装上,主要是Google Play得有。 有了Google Play,基本就可以轻松无压力地安装其他全家桶了。 总结 经过这次折腾,我感受到了谷歌强大的生态系统控制力。全家桶还真不是盖的。 对于老外来说,有两样东西他们从一出生就躲不过:税,谷歌。 我推测鸿蒙和9.0/9.1安装不成功的原因,可能是系统更新之后,某部分组件和谷歌框架不再兼容。还好旧版本的8.0给力,我要给华为手机助手的开发团队颁发一朵小红花,没有你们,我可没法降级到8.0。(不是高级黑,是真感恩) 这又使我想起了我最近一直更新的拓扑梅尔智慧办公平台(Topomel Box),目前我依旧十分小心的引入各个第三方开源组件,因为我知道,引入的组件越多,各组件之间的调用关系将越复杂,就容易出现你所不容易发现的兼容性问题。 开源它好是好,但是我还犯着各位猿友的通病呢:这轮子我还得自己来。

【解题笔记】二维数组

1.统计有序矩阵中的负数 给你一个 m * n 的矩阵 grid,矩阵中的元素无论是按行还是按列,都以非递增顺序排列。 。请你统计并返回 grid 中 负数 的数目。 int countNegatives(int** grid, int gridSize, int* gridColSize){ int r = gridSize; int c = gridColSize[0]; int cnt = 0; for(int i = 0; i < r; i++){ for(int j = 0; j < c; j++){ if(grid[i][j] < 0){ cnt++; } } } return cnt; } //统计数组中的非负数, //grid 是二维数组,grieSize 是二维数组的第一维有多少个,gridColSize 是二维数组中每个第一维内有多少个 //*和[]等价的 //若数字小于0,则计数器加1;穷举完所有 2.矩阵对角线元素的和 给你一个正方形矩阵 mat,请你返回矩阵对角线元素的和。请你返回在矩阵主对角线上的元素和副对角线上且不在主对角线上元素的和 int diagonalSum(int** mat, int matSize, int* matColSize){ int r = matSize; int c = matColSize; int sum = 0, i = 0; for(i = 0; i < r; i++){ sum += mat[i][i]; } for(i = 0; i < r; i++){ if(r - 1 - i !

idea2020版本maven子模块pom.xml没有parent标签

本例父项目没有从模板创建,子项目从模板创建 问题截图: ** 解决办法 ** 如下图,自行添加parent标签。注意标签内的gav标签都是父项目的内容。在parent标签外再加一个artifactId标签,里面内容为子模块的。 其实在idea刚创建子模块的时候,是有parent标签的,以下为截图。但是,在子模块创建完成后,parent会消失。 原因 经尝试,从模板创建的maven项目会没有parent标签。不从模板创建的maven项目有parent标签。

C语言单链表的头插法与尾插法

简单介绍一下本人自我总结的单链表头插法与尾插法 #前言:这是本人新手时学习单链表头插与尾插的总结,可能有些地方描述得不太好,如有错误,烦请大家指出,谢谢! 单链表头插法: 头插则是将新节点链接到链表的头结点的后面,即不断的在头节点和第一个节点之间插入新节点,每插入一个新节点,新节点就变为第一个节点,(可理解为插队)以此循环。 // (生成的链表结点次序与输入的顺序相反) 头插法模型图如下: 具体操作代码如下 : Struct Node{ Char data; Struct Node *next; } 先创建链表 struct Node *head = (struct Node *)malloc(sizeof(struct Node)); head -> next = NULL; 在新结点没有插入之前是<1>过程,即 head->next = first; first ->next = NULL; 在新结点插入后是<2>过程,即 P->next = head->next; head->next = P; PS:这里介绍一下“电子量产工具”项目视频里韦东山老师所用的头插法。 static PDispOpr g_DispDevs = NULL; // g_DispDevs是链表头(火车头),所谓链表就是一个指针,一开始它是空的 void RegisterDisplay(PDispOpr ptDispOpr) { /* 韦老师的写法,我对此的理解是:先建立一个头指针g_DispDevs(火车头), * 首先先明确一点g_DispDevs = NULL,就是说火车头没有连任何车厢,现在假设我有一个LCD相关的结构体要加到这个链表(火车),火车头连接第一节车厢。 * 过程: * 1.先确定你要添加的那节车厢的去向 * (就是你要添加的那节车厢要连去哪里,要是单链表,那最后一节车厢的去向是NULL) * 2.

JSON与String之间互转

一,String转json 这个JSON.parse()与eval()都可以实现,但是它们是有区别的, JSON.parse对json字符串要求比eval()更为严格,key名称(例如name)全部必须有双引号。 而eval必须用括号将json字符串括起来才能成功转换,key名称(例如name)有无双引号都可以成功转化。 二,JSON转String,用【 JSON.stringify() 】 json的key名称(例如name)有无双引号都可以成功用JSON.stringify()实现转化,但是注意我们最好还是将双引号写上(或者要求后端在返回数据的时候为key名称加上双引号)。 *当然JSON.stringify()还可以用于数据过滤,第二个参数是函数,而第三个参数用于json数据结果的代码缩进。 <script> var jewave = {"name":"bobo","like":["singsong","run"]}; function filter(key,value){ switch(key){ case "like": return value.join(','); default: return value; } } JSON.stringify(jewave,filter,4) /*执行结果,数组成员被第二个参数【函数】拼接成一个单独的字符串*/ "{ "name": "bobo", "like": "singsong,run" }" <script> *toJSON函数也可以过滤JSON数据,注意是js内置的函数【toJSON】不能写错。 var book = {"name":"π","editor":"赵六",toJSON:function () {return this.name} }; var jsonText = JSON.stringify(book); console.log(jsonText) //"π"

2021.12.13 决心成为TA的第1天

本人男,20岁,就读于某高校数字媒体技术专业。现在是大二第一学期最后一个月的某个傍晚,正在为不知道有什么用处的电路实验报告而苦恼着。 TA,即游戏开发团队中“技术美术”这一职位的英文缩写。当初填报数技专业的初衷便是动画/游戏制作,某游戏公司制作的三渲二动画短片让没能如愿从艺的我重燃了做动画的欲望。后来发觉数艺才是更合适做动画的专业,没有美术基础的我最大的希望还是做游戏。 大一由学长介绍了解到了TA这个职位,感觉算是数技的对口职业了。但周围人普遍不甚关心未来规划,专业里很多人都是瞎报或者调剂的,加上各种杂难课程压力,自己也就懈怠了。如今了解到TA是个一般人难以胜任的高阶职位,需要学习的东西是普通程序或美术的很多倍。 大二一个学期有用的也就数据结构一门课,学的也不深。剩下可能值得一提的就是因为入了手办坑而下定决心好好钻研3D建模,争取自己做手办,进而重拾了“成为一名TA”这样的目标吧。 没什么美术基础,数位板倒是有一个。平时偶尔画点二次元小破画,各种画师的图倒也存了一万多张,但从没系统学习过素描、人体这些。编程也只会c和c++,且只是写过一些实例之类的东西,没写过能称得上“项目”的体量。 目前被各种考试席卷,计划是寒假学伯里曼。编程也要继续精进,但目前还不知道接下来该学哪一部分,先把c++的类和对象熟练掌握吧。鉴于买手办把钱花光了,电脑最早得下学期开学才能买,学引擎、建模实操这些东西大概还得再拖。。。 2021.12.13 决心成为TA的第1天。但愿现在开始还来得及吧。

Vue实现底部导航栏切换页面及图片

前言 刚进新公司,有幸接触到从前后端不分离到前后端分离的一个过程,最开始对vue不太熟悉,下班自学一周就开始做了,可能会有很多问题,若有写不好的地方大佬们可以提出。 一、实现效果 需求:vue底部导航点击切换图标 效果: 二、大概思路图 三、代码实现 index.js(vuex) import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { // 目录标识(感觉不应该使用 localStorage,应该使用sessionStorage) DirectoryIdentifier: localStorage.getItem('DirectoryIdentifier') ? localStorage.getItem('DirectoryIdentifier') : '' }, mutations: { // 保存目录标识 saveDirectoryIdentifier (state, directoryIdentifier) { localStorage.setItem('DirectoryIdentifier', directoryIdentifier) state.DirectoryIdentifier = directoryIdentifier } } }) export default store login.vue methods: { login () { if (this.loginForm.username === '' || this.loginForm.tmpPassword === '') { this.showPopup('账号或密码不能为空') } else { api.

Log4j 漏洞修复检测 附检测工具

作者:SRE运维博客 博客地址:https://www.cnsre.cn/ 文章地址:https://www.cnsre.cn/posts/211213210004/ 相关话题:https://www.cnsre.cn/tags/Log4j/ 近日的Log4j2,可是非常的火啊,我也是加班加点把补丁给打上了次安心。Apache Log4j2存在远程代码执行漏洞,经验证,该漏洞允许攻击者在目标服务器上执行任意代码,可导致服务器被黑客控制。由于Apache Log4j 2应用较为广泛,建议使用该组件的用户尽快采取安全措施。 影响范围 漏洞影响版本: 2.0 <= Apache Log4j 2 <= log4j-2.15.0-rc1 漏洞描述 Apache Log4j 2是一个基于Java的日志记录工具,是对 Log4j 的升级。近日安恒信息应急响应中心监测到Apache Log4j 2存在远程代码执行漏洞,攻击者可通过构造恶意请求利用该漏洞实现在目标服务器上执行任意代码。 漏洞修复 由于Log4j2 作为日志记录基础第三方库,被大量Java框架及应用使用,只要用到 Log4j2 进行日志输出且日志内容能被攻击者部分可控,即可能会受到漏洞攻击影响。因此,该漏洞也同时影响全球大量通用应用及组件,例如 : Apache Struts2、Apache Solr、Apache Druid、Apache Flink、Apache Flume、Apache Dubbo、Apache Kafka、Spring-boot-starter-log4j2、ElasticSearch、Redis、Logstash等 建议及时检查并升级所有使用了 Log4j 组件的系统或应用。 紧急: 目前漏洞POC已被公开,官方已发布安全版本,建议使用该组件的用户尽快采取安全措施。 临时性缓解措施: 1、在 jvm 参数中添加 -Dlog4j2.formatMsgNoLookups=true 2、系统环境变量中将LOG4J_FORMAT_MSG_NO_LOOKUPS 设置为 true 3、创建 log4j2.component.properties 文件,文件中增加配置 log4j2.formatMsgNoLookups=true 4、若相关用户暂时无法进行升级操作,也可通过禁止Log4j中SocketServer类所启用的socket端对公网开放来进行防护 5、禁止安装log4j的服务器访问外网,并在边界对dnslog相关域名访问进行检测。部分公共dnslog平台如下 ceye.io dnslog.link dnslog.cn dnslog.io tu4.org awvsscan119.autoverify.cn burpcollaborator.net s0x.cn 彻底修复漏洞: 建议您在升级前做好数据备份工作,避免出现意外 研发代码修复:升级到官方提供的 log4j-2.

【算法零基础100讲题解】第三讲 矩阵——基于Python语言

文章目录 写在前面题目解析1.最富有客户的资产总量(1672)2.二进制矩阵中的特殊位置(1582)3.翻转图像(832)4.旋转图像(48)5.转置矩阵(867)6.将一维数组转变成二维数组(2022)7.判断矩阵经轮转后是否一致(1886)8.二维网格迁移(1260) 写在后面 写在前面 今天是周六,题目是关于一些矩阵以及矩阵的操作的; 矩阵的定义在线性代数课本中有; 除此之外,今天的题目会涉及到矩阵的一些其他操作;矩阵的水平翻转、垂直翻转、矩阵的顺时针、逆时针旋转、矩阵的转置。 题目解析 1.最富有客户的资产总量(1672) class Solution: def maximumWealth(self,accounts:List[List[int]])->int: sum_1=0 n=len(accounts) max_sum=sum(accounts[0][:]) for i in range(n): for j in range(len(accounts[i])): sum_1+=accounts[i][j] if sum_1>max_sum: max_sum=sum_1 sum_1=0 return max_sum 这道题目就依次遍历求出了相应的和,与给定的最大值作比较最后确定最大值循环结束后输出即可。 2.二进制矩阵中的特殊位置(1582) class Solution: def numSpecial(self,mat:List[List[int]])->int: cnt=0 rows=len(mat) for row in range(rows): if sum(mat[row])!=1: continue col=mat[row].index(1) if sum(mat[j][col] for j in range(rows) if j!=row)==0: cnt+=1 return cnt 首先理解什么是特殊位置,即某个元素的行和列只有一个1,其余都为0的位置就是题目中的特殊位置; 1)定义一个计数器,得到了这个矩阵的行数; 2)对行进行循环遍历,首先判断每行的元素的和是否为1,若为1就继续循环里的内容,否则就下一次循环(不为1也就说明这个位置不会是特殊位置); 3)之后利用index方法返回了当前行中1所在的列,对当前列中其他的元素求和判断其是否为0;若是则计数器加1;否则就下一次循环,最后循环结束后返回计数器即可。 3.翻转图像(832) class Solution: def flipAndInvertImage(self,image:List[List[int]])->List[List[int]]: row=len(image) col=len(image[0]) res_1=[] for i in range(row): res_1.

torchvision详细介绍

前言 深度学习道路漫漫,唯有不断总结,脚踏实地才能造就一番就成,也不断勉励自己,不要放弃,相信自己可以的!!!共勉!!! torchvision简介 torchvision是pytorch的一个图形库,它服务于PyTorch深度学习框架的,主要用来构建计算机视觉模型。以下是torchvision的构成: torchvision.datasets: 一些加载数据的函数及常用的数据集接口;torchvision.models: 包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;torchvision.utils: 其他的一些有用的方法。 torchvision.transforms torchvision.transforms主要是用于常见的一些图形变换。 torchvision.transforms.Compose()类。这个类的主要作用是串联多个图片变换的操作。这个类的构造很简单: # 图像预处理步骤 transform = transforms.Compose([ transforms.Resize(96), # 缩放到 96 * 96 大小 transforms.ToTensor(), # 转化为Tensor transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 归一化 ]) torchvision.datasets torchvision.datasets 是用来进行数据加载的,PyTorch团队在这个包中帮我们提前处理好了很多很多图片数据集。 MNISTCOCO Captions Detection LSUN ImageFolder Imagenet-12 CIFAR STL10 SVHN PhotoTour … # Image processing img_transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)), ]) # MNIST dataset mnist = datasets.MNIST( root='./data/', train=True, transform=img_transform, download=True) # Data loader dataloader = torch.

用Vue3写个气泡对话框组件

Vue3 气泡对话框组件,使用 TypeScript 枚举限定类型,样式用到了 TailwindCSS 组件代码 <template> <div class="mt-5 mb-5 p-2 bg-white border-solid border-gray-300 border-l border-t border-r border-b border-light-blue-500 rounded-md relative"> <div :class="{ 'w-2.5 h-2.5 border-gray-300 bg-white transform absolute': true, 'border-l border-t rotate-45 -top-1.5 left-4': placement === 'top-start', 'border-l border-t rotate-45 -top-1.5 inset-x-2/4 -translate-x-1.5': placement === 'top', 'border-l border-t rotate-45 -top-1.5 right-4': placement === 'top-end', 'border-l border-t -rotate-45 top-4 -left-1.5': placement === 'left-start', 'border-l border-t -rotate-45 inset-y-2/4 -left-1.5 -translate-y-1.5': placement === 'left', 'border-l border-t -rotate-45 bottom-4 -left-1.

静态代理与JDK动态代理

文章目录 概述定义与结构 静态代理软件设计原则动态代理JDK动态代理的一个简单例子JDK动态代理源码分析 总结 概述 代理模式是一种常用的设计模式,在AOP、RPC等诸多框架中均有它的身影。 根据代理类的创建时机和创建方式的不同,可以将其分为静态代理和动态代理两种形式:在程序运行前就已经存在的编译好的代理类是为静态代理,在程序运行期间根据需要动态创建代理类及其实例来完成具体的功能是为动态代理。 代理模式的目的就是为真实业务对象提供一个代理对象以控制对真实业务对象的访问,代理对象的作用有: 代理对象存在的价值主要用于拦截对真实业务对象的访问;代理对象具有和目标对象(真实业务对象)实现共同的接口或继承于同一个类;代理对象是对目标对象的增强,以便对消息进行预处理和后处理。 定义与结构 为其他对象提供一种代理以控制对这个对象的访问。 代理模式主要包含三个角色,即抽象主题角色(Subject)、委托类角色(被代理角色,Proxied)以及代理类角色(Proxy),如上图所示: 抽象主题角色:可以是接口,也可以是抽象类;委托类角色:真实主题角色,业务逻辑的具体执行者;代理类角色:内部含有对真实对象RealSubject的引用,负责对真实主题角色的调用,并在真实主题角色处理前后做预处理和后处理。 静态代理 静态代理是代理模式的实现方式之一,是相对于动态代理而言的。所谓静态代理是指,在程序运行前,由程序员创建或特定工具自动生成源代码并对其编译生成.class文件。 静态代理的实现只需要三步: 首先,定义业务接口;其次,实现业务接口;然后,定义代理类并实现业务接口;最后便可通过客户端进行调用。 //抽象主题角色 public interface HelloService { String hello(String name); String hi(String msg); } //委托类角色 public class HelloServiceImpl implements HelloService { @Override public String hello(String name) { return "hello," + name; } @Override public String hi(String msg) { return "hi,"+msg; } } //代理类角色 public class HelloServiceProxy implements HelloService{ private HelloService helloService; public HelloServiceProxy(HelloService helloService) { this.

uniapp实战电影预告项目

项目介绍 这是一个基于uniapp开发的3端应用(微信小程序、H5、安卓APP),有 首页、搜索、我的 3大模块,充分应用了官方的各种布局组件和API,非常适合有Vue、小程序项目经验并且想上手uniapp的同学。 项目截图: 版本号介绍: 小功能增加或者小bug修复会将版本号的第三位增加1 例如:0.0.1 变成 0.0.2 模块的变动,迭代会在第二位数字增加1 大功能增加,迭代会在第一位数字增加1 项目地址:GitHub - C4az6/movie_trailer_project: 一个基于uniapp的预告片应用 记得Star哦!