目录
一、信息与信息技术概述
1、信息的定义
2、信息的基本特征
3、信息的分类
二、信息技术的发展及应用
1、信息技术的含义
2、信息技术的发展
三、数制与信息编码
1、数制的基本概念
2、不同进制之间的转换
3、计算机中字符的编码
四、信息的传递和获取
1、信息的传递
2、信息的获取
五、信息活动的法规
一、信息与信息技术概述 1、信息的定义 信息就是通过语言、文字、图形、图像、声音等传播的内容。
信息不等于消息,信息是消息的内核,消息是信息的外壳。
信息不是某种信号,也不等同于知识。
数据(字母、数字符号、语言、图形/图像)是信息的载体。
2、信息的基本特征 >时效性、价值性:
信息不能直接提供物质需要,却能满足人民精神生活的需要;从而促进物质、能量的生产和使用。信息的价值也具有相对性。
信息的时效性会随着时间的推移而变化,必须与价值性联系在一起。
>共享性
信息资源可以共享;信息共享不会丢失、改变;信息可以被一次、多次、同时利用。
信息不能独立存在,需要衣服于一定的载体;同一个信息可以依附于不同的媒体;
>真伪性
人们接收到的信息,并非所有都是对事物的真实反映。
其他特征,比如:客观性、无限性、可度量、可识别、可转换、可存储、可处理、可增值、可再生、可传递、可压缩等。
3、信息的分类 (1)按照信息的加工顺序可分为:一次信息、二次信息和三次信息。
(2)按信息的应用领域可分为:管理信息、社会信息、军事信息、文教信息、经济信息和科技信息等。
(3)按信息的反映形式可以分为:数字信息、图像信息和声音信息等。
二、信息技术的发展及应用 1、信息技术的含义 信息技术是指能扩展人的信息器官的功能,完成信息的获取、传递、加工、再生和使用等功能的一类技术。
信息技术的“四基元”包括:感测技术、通信技术、计算机和智能技术以及控制技术。
感测技术:感觉器官功能的延长;
通信技术:传导神经网络功能的延长;
计算机和智能技术:思维器官功能的延长
控制技术:效应器官功能的延长;
信息技术“四基元”和谐有机地合作,共同完成扩展人的智力功能的任务;
2、信息技术的发展 以每一次信息技术革命为标志,信息技术的发展分为5个阶段:
(1)第一次信息技术革命:语言的使用;
(2)第二次信息技术革命:文字的创造;
信息的存储首次超越了时间和地域的限制。
(3)第三次信息技术革命:印刷的发明;
为知识的积累和传播提供了更为可靠的保证;
(4)第四次信息技术革命:电报、电话、广播和电话的发明和普及应用;
(5)第五次信息技术革命:电子计算机的普及应用及计算机与现代通信技术的有机结合;
将人类社会推到了数字化时代。
三、数制与信息编码 1、数制的基本概念 数制也称为计数制,用一组固定的符号和同意的规则来表示数值的方法。常用的数制都采用进位计数制。
进位计数制涉及:数码、基数和位权三个基本概念。
常用的进位计数制有:十进制、二进制、八进制、十六进制;
2、不同进制之间的转换 (1)非十进制--->十进制
方法:按位权展开,并逐项相加
(2)十进制--->非十进制
方法:整数部分(辗转相除)小数部分(辗转相乘)
(3)二进制<--->八进制/十六进制
方法:每3位或4位分组。
二进制->八进制:“3位合1法”;
二进制->十六进制:"4位合1法";
1. lock vs synchronized 关于锁的概念不明白的可以参考这篇文章
要求
掌握 lock 与 synchronized 的区别理解 ReentrantLock 的公平、非公平锁理解 ReentrantLock 中的条件变量 三个层面
不同点
语法层面 synchronized 是关键字,源码在 jvm 中,用 c++ 语言实现Lock 是接口,源码由 jdk 提供,用 java 语言实现使用 synchronized 时,退出同步代码块锁会自动释放,而使用 Lock 时,需要手动调用 unlock 方法释放锁 功能层面 二者均属于悲观锁、都具备下面3个基本的功能 互斥(多个线程争夺同一个锁,但是只有一个线程可以成功。其余的线程则陷入等待)同步(多个线程可以同时运行,但是如果其中的某个线程需要其他线程的结果,则该线程会一直等待其他线程返回结果才继续运行)锁重入(已经获得锁的线程,可以重复的去被锁住的资源加上多次锁) Lock 提供了许多 synchronized 不具备的功能,例如获取等待状态(可以获取哪些线程被阻塞了)、公平锁、可打断、可超时、多条件变量Lock 有适合不同场景的实现,如 ReentrantLock, ReentrantReadWriteLock 性能层面 在没有竞争时,synchronized 做了很多优化,如偏向锁、轻量级锁,性能不赖在竞争激烈时,Lock 的实现通常会提供更好的性能 公平锁
公平锁的公平体现 已经处在阻塞队列中的线程(不考虑超时)始终都是公平的,先进先出公平锁是指未处于阻塞队列中的线程来争抢锁,如果队列不为空,则老实到队尾等待非公平锁是指未处于阻塞队列中的线程来争抢锁,与队列头唤醒的线程去竞争,谁抢到算谁的 公平锁会降低吞吐量,一般不用 条件变量
ReentrantLock 中的条件变量功能类似于普通 synchronized 的 wait,notify,用在当线程获得锁后,发现条件不满足时,临时等待的链表结构与 synchronized 的等待集合不同之处在于,ReentrantLock 中的条件变量可以有多个,可以实现更精细的等待、唤醒控制。 2. volatile 要求
掌握线程安全要考虑的三个问题掌握 volatile 能解决哪些问题 2.1 掌握线程安全要考虑的三个问题(原子性、可见性、有序性) 原子性
一、傅里叶变换的物理意义
从纯粹的数学意义上看,傅里叶变换是将-一个图像函数转换为一系列周期函数来处理的;从物理效果看,傅里叶变换是将图像从空间域转换到频率域,其逆变换是将图像从频率域转换到空间域。即傅里叶变换的物理意义是将图像的灰度分布函数变换为图像的频率分布函数,傅里叶逆变换是将图像的频率分布函数变换为灰度分布函数。实际上对图像进行二维傅里叶变换得到频谱图就是图像梯度的分布图,傅里叶频谱图上看到的明暗不一的亮点,实际上图像上某一点 与邻域点差异的强弱,即梯度的大小,即该点的频率大小。如果频谱图中暗的点数更多,则实际图像是比较柔和的;反之,如果频谱图中亮的点数多,则实际图像是比较尖锐的,边界分明且边界两边像素差异较大。
二、傅里叶变换的定义及性质
1、傅里叶变换的定义
傅里叶变换是在以时间为自变量的“信号”与频率为自变量的“频谱”函数之间的某域研究中较复杂的问题在频域中变得简单起来,从而简化其分析过程;另一方面使信号与系统的物理本质在频域中能更好地被揭示出来。当自变量“时间”或“频率”为连续形式和离散形式的不同组合时,就可以形成各种不同的傅里叶变换对,即“信号”与“频谱”的对应关系。傅里叶变换包含连续傅里叶变换、离散傅里叶变换、快速傅里叶变换和短时傅里叶变换等,在数字图像处理中使用的是二维离散傅里叶变换。
2、二维离散傅里叶变换性质
三、傅里叶变换的matlab实现
在MATLAB软件中,通过函数fft()进行一维离散傅里叶变换,通过函数ifft()进行一维离散傅立叶反变换。
在MATLAB中,通过函数fft2()进行二维离散傅里叶变换,通过函数ifft2()进行二维离散傅里叶反变换。函数fft()和fft2()的关系为fft2(X)=fft(fft(X).‘).’。
在MATLAB软件中,通过函数ifft2()进行二维快速傅立叶反变换,该函数和函数fft2()互为反函数。
通过fft2得到的频谱坐标原点位于左上角,函数fftshift()将变换后的坐标原点移到频谱窗口中央,坐标原点是低频,向外是高频。函数fftshift()能够进行傅里叶平移,函数ifftshift()能够进行傅里叶反平移。简单理解,ifftshift就是撤消fftshift的结果。
1、矩阵和图像的二维离散傅里叶变换
% 矩阵的二维离散傅里叶变换(变换后得到的矩阵和原矩阵大小相等) I1=ones(4) I2=[2 2 2 2;1 1 1 1;3 3 0 0;0 0 0 0] J1=fft2(I1) J2=fft2(I2) % 图像的二维离散傅里叶变换 I=imread('cameraman.tif'); J=fft2(I); K=abs(J/256);% 计算频率(频谱图即频率分布图) subplot(121),imshow(I); title('原始图像'); subplot(122),imshow(uint8(K));% 显示频谱图(通过fft2得到的频谱图中,坐标原点在窗口的左上角,窗口的四角分布低频部分) title('灰度图像的频谱图'); 命令行结果:
I1 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 I2 = 2 2 2 2 1 1 1 1 3 3 0 0 0 0 0 0 J1 = 16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 J2 = 18.
1.什么是XML XML 指可扩展标记语言(Extensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输,存储数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
2.XML 与 HTML 的主要差异 XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:
XML 被设计为存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
3.XML的优势 每种语言的产生都能完成某些特定的功能,XML作为一种标记语言也不例外。XML最大的优势在于它能对各种编程语言编写的数据进行管理,使得在任何平台下都能通过解析器来读取XML数据。
4.XML语法 一个XML文件分为如下几部分内容:
文档声明
元素 标签
属性
注释 5.文档声明 在编写XML文档时,需要先使用文档声明,声明XML文档的类型。
最简单的声明语法:
<?xml version="1.0" ?>
用encoding属性说明文档的字符编码:
<?xml version="1.0" encoding="GB2312" ?>
6.创建 XML 文档 元素
元素是XML文档内容的基本单元。语法上,一个元素包括一个起始标记,一个结束标记以及标记之间的数据内容。
例如:<出版社>电子工业出版社</出版社>
元素中还可以嵌套别的元素。在XML文档中,仅有一个根元素,可以有多个子元素,允许出现空元素。
7.XML 命名规则 XML 命名规则
XML 元素必须遵循以下命名规则:
名称可以含字母、数字以及其他的字符
名称不能以数字或者标点符号开始
名称不能以字符 “xml”(或者 XML、Xml)开始
名称不能包含空格
首先,要把所有文件(包括.cpp,.h,.fs,.vs)都放到当前文档目录下,不能放在各个src文件夹里,不然会加载着色器错误,可能跟路径有关。
在learnopengl-cn的6.1章纹理映射中,网站原本的源码并不好,会出现filesystem.h的相关错误,而filesystem.h的作用仅仅是用来加载图片文件(例如container.jpg),并没有其他的作用。
打开filesystem.h后,发现有一行
#include "root_directory.h" // This is a configuration file generated by CMake. 这说明有个root_directory.h文件需要我们自己去编译,但是在OPENGL学习中,我们并不必使用filesystem.h来读取文件.
解决方法:
注释掉 filesystem.h 所在行,并在 stbi_load() 函数中将 getPath 函数替换为目标文件的目录,并把读取图片container.jpg的路径设置为自己的绝对路径:
//修改后的代码,使用绝对路径 unsigned char *data = stbi_load("D:/Template/glfwtemplate/glfwtemplate/container.jpg", &width, &height, &nrChannels, 0); //原本的代码: //unsigned char *data = stbi_load(FileSystem::getPath("resources/textures/container.jpg").c_str(), &width, &height, &nrChannels, 0); 此外,还可以将VS平台换成VS 16 2019可以解决此问题。
(但是2019会将顶点着色器和片段着色器里的空格识别为整数文本,很头疼。)
或许可以下载存储库的新副本。解压到对应目录/文件夹中,然后不要更改或重命名该目录/文件夹,运行 cmake 并构建。但我没试了。
除此之外,首先在VS2013中搭建opengl环境,配置VS2013中各个库的信息,在这里记录一下备查。
C++命令行:
/GS /analyze- /W3 /Zc:wchar_t /I"D:\Template\glfwtemplate\glfwtemplate\glm" /I"D:\Template\glfwtemplate\glfwtemplate\LearnOpenGL\includes\learnopengl" /I"D:\Template\glfwtemplate\glfwtemplate\stb-master" /ZI /Gm /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"
老macbook升级新版本(Big sur、Monterey) 一、前期须知以及准备1.摘要2.设备3.升级方法3.前期准备 二、引导U盘的搭建1.下载安装程序2.U盘格式问题3.下载系统镜像并写入U盘 三、系统安装结束语 一、前期须知以及准备 1.摘要 对于老版本的macbook一系列的设备已经不提供支持了,正如我的macbookpro9.2(a1278 2012款)停留在了10.13,word等软件已经不可使用了,在网上搜索时看见了一位博主的文章,成功的升级到了10.15(10.13升级10.15),很多软件已经可以成功使用了,但是我有些贪心,想体验体验新系统,所以有了这个文章,目前已经实现的是通过10.15升级11(Big sur)或12(Monterey)都是可行的。隔空投送、蓝牙、无线网等功能无问题。
如果你的系统低于10.15,这里建议使用两块U盘(不低于16G),一块U盘用于10.15的安装,一块用于后面的12.4的安装,因为不知为何,可能是机器老或是镜像太大等原因,引导U盘的制作是需要很长时间的,所以两块U盘能节省不少时间。
本文只能为大家尽可能避免一些我在升级系统时所踩的坑,不保证能解决所有问题,比如我在安装好系统后没有出现驱动丢失等情况,对于更老一点的macbook,不建议刷太新的哦,可以自己尝试。
这里说几句题外话,可能会触碰很多奸商的蛋糕,这台电脑是在海鲜市场买的,在搜索macbook时可以看到很多2000左右的设备,其中很大一部分在设备信息写着2019、2021款设备,看着是新款,但拿到手后发现特别卡,恭喜你中奖了,是老设备改的版本号。好一点的就是将设备升级后卖高价的人,在这里提醒大家购买设备时擦亮眼睛,少踩坑。
2.设备 由于已经升级完了,是从10.15直接升级的12.4,各项功能完美,一点问题没有,适用于办公、看视频、写代码等不过于吃配置的操作,macbookpro是金属机身,所以散热也还不错,给大家看一下更新后的版本以及配置,本教程就是使用升级12.4后的设备写的。
后面会给出支持的版本,2012款升级后使用感觉还好,对于更早的版本我没有设备,没有体验过流畅度,但是网上总体评价感觉略卡,大家可以使用此方法升级11系统体验一下。
为了使用新系统能稍微舒服点,并且我这款可以更换内存条,所以对硬件进行了小小的升级,在硬盘方面建议使用固态硬盘做系统盘,网上有人用机械升级失败了。
硬件备注硬盘固态120g,光驱位改机械硬盘500g。固态,机械其他电脑剩的,光驱位淘宝,拼多多几块钱就能买,我这个拼多多5.7买的内存条双2g加到了双4g,共8g,两根大概不到100元cpu3代i5的,cpu焊死了,不能升级 升级方法很简单,后盖10颗螺丝,拧下来打开后盖就能换了,注意先断电操作(电池排扣断开),动作轻一些,硬盘位的sata是根排线,别弄断了。
3.升级方法 本次使用的就是oc(Opencore)引导的方法,了解过黑苹果的同志不难看出,其实本次升级就是使用黑苹果方法升级macbook,但是此方法会更加简单,因为平常刷黑苹果时常常需要看硬件,驱动等因素是否有大神做出了相关支持,常常会出现找不到引导、声卡驱动导致没有声音、网卡没驱动、花屏的问题,而macbook是白苹果,硬件以及驱动大部分都是支持的,所以升级起来更为简单,功能支持更完整,并且这么想,我用黑苹果升级白苹果,功能完整的话,哈哈约等于白苹果。
所使用的方法就在此链接(https://dortania.github.io/OpenCore-Legacy-Patcher/MODELS.html)中,各位可以看到是否oc引导的方法是否支持自己的设备,具体方法在里面有所描述,各位可以直接看官网的方法,嫌麻烦可以继续看我的文章,但是关于设备的支持一定要去官网看一下,下图就是设备支持的界面。
3.前期准备 准备备注macbook一定要是支持的设备,usb口是好的,已经升级到了10.15U盘至少16G的,系统就十几G,32g更好,不要使用垃圾颗粒U盘会慢的怀疑人生 二、引导U盘的搭建 对于老设备升级的最难点就是引导U盘的创建,U盘做好后,其实装系统只是需要等一会的事情。
1.下载安装程序 引导U盘的创建使用Opencore Legacy Patcher软件(Opencore Legacy Patcher)找一个版本进行下载,我下载的就是最新版本的OpenCore-Patcher,此软件的优点就是镜像下载与写入、引导的写入可以一并完成,不会出先因为系统镜像版本与EFI引导不对应的情况,导致在安装选择磁盘时提示此更新不能在此设备上的错误。 使用这个软件就可以制作好U盘,是不是觉着很简单。
(1)下载好后双击压缩包,软件会解压出来
(2)双击软件打开软件,如果提示软件对系统有损害,需要在系统偏好设置–>安全与隐私–>通用中允许打开此设备(位置在允许从一下位置下载的App)。
(3)软件打开后就进入了此界面
2.U盘格式问题 (1)现在来插入U盘(记得一定要把数据先备份出去),U盘如果插上不显示的话,是因为你可能是ntfs等mac读不出来的格式,在软件中打开系统自带的磁盘工具,软件具体位置可能并不一致,找一找肯定是有的,
(2)右击U盘,点击抹掉
(3)选择Mac OS扩展(日志式)点击抹掉,这时就能发现U盘可以显示了。
3.下载系统镜像并写入U盘 此软件已经集成了系统镜像下载写入U盘,并自动添加引导的功能,非常的人性化,操作如下:
(1)点击Create macos installer
(2)点击Download macOs Installer,这时他会搜索你可用的镜像包,再点击show older installers可以查看全部的镜像包,选择自己想要安装的版本(我2012款a1278安装的12.4的21F79版本)。
(3)点击选择的版本会自动进行下载,这时只需等待到100%,等待的时间取决于你的网速。
(4)下载完自动检查解压,进度条满了会让输入一次用户密码,接下来会将其安装在Applications中
(5)安装好后点击Flash Installer
(6)点击 install macos,这里就是选择你刚刚下载好的镜像,并将其装入U盘
(7)选择自己刚刚格式化好的空白U盘
(8)再次输入用户密码,软件会将镜像中的文件自动放入U盘(本教程所需要最多的时间就是软件自动操作的时间)
(9)这里点击install OpenCore to disk,将opencore放入磁盘,这一步很重要,因为在安装好系统后,引导还在U盘上,其可以自动在升级后的系统上安装opencore,进入新系统后还要使用Opencore将引导放在系统磁盘。
(10)点击install to disk(11)这里选择磁盘,选择U盘
(12)选择引导分区,直接点就行
(13)建立好引导后提示重新启动,点击reboot
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.8.11/tailwind.min.css" integrity="sha512-KO1h5ynYuqsFuEicc7DmOQc+S9m2xiCKYlC3zcZCSEw0RGDsxcMnppRaMZnb0DdzTDPaW22ID/gAGCZ9i+RT/w==" crossorigin="anonymous" /> <link rel="stylesheet" href="style.css" /> <title>Password Strength Backround</title> </head> <body> <div class="background" id="background"></div> <div class="bg-white rounded p-10 text-center shadow-md"> <h1 class="text-3xl">Image Password Strength</h1> <p class="text-sm text-gray-700">Change the password to see the effect</p> <div class="my-4 text-left"> <label for="email" class="text-gray-900">Email:</label> <input type="text" class="border block w-full p-2 mt-2 rounded" id="email" placeholder="Enter Email" /> </div> <div class="
Redis的缓存问题(三)缓存穿透、缓存雪崩、缓存击穿
缓存穿透
什么是缓存穿透?
解决方案(2种)
(1)缓存空对象
(2)布隆过滤
综上所述
代码实现
思路图解
运行测试
扩展
缓存雪崩
什么是缓存雪崩?
解决方案(4种)
(1)给不同的Key的TTL添加随机值(推荐)
(2)利用Redis集群提高服务的可用性
(3)给缓存业务添加降级限流策略
(4)给业务添加多级缓存 缓存击穿
什么是缓存击穿?
解决方案(2种)
(1)互斥锁
(2)逻辑过期
互斥锁与逻辑过期的对比分析
具体实现
(1)关于互斥锁的实现
需求描述
代码实现
(2)逻辑过期的实现
需求描述
代码实现
完整代码
Redis的缓存问题(三)缓存穿透、缓存雪崩、缓存击穿 缓存穿透 什么是缓存穿透? 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。
解决方案(2种) (1)缓存空对象 简单的来说,就是请求之后,发现数据不存在,就将null值打入Redis中。
优点:
实现简单,维护方便 缺点:
额外的内存消耗可能造成短期的不一致 分析:
当请求第一次来时,数据库中没有该数据,数据库向Redis写入一个null;此时正好数据库中被插入了该数据,又有一个请求来访问,但是刚刚向Redis中插入的null来没有过期,就出现了不一致(该请求从Redis拿到的结果就是null,而数据库中其实是有实际数据的)
当然我们也有许多的解决办法,例如:将TTL的时间设置的足够短;每次向数据库新增数据的时候主动将其插入缓存中去覆盖那个null。
(2)布隆过滤 在客户端与Redis之间加了一个布隆过滤器,对于请求进行过滤。 布隆过滤器的大致的原理:布隆过滤器中存放二进制位。数据库的数据通过hash算法计算其hash值并存放到布隆过滤器中,之后判断数据是否存在的时候,就是判断该hash值是0还是1。
但是这个玩意是一种概率上的统计,当其判断不存在的时候就一定是不存在;当其判断存在的时候就不一定存在。所以有一定的穿透风险!!!
优点:
内存占用较少,没有多余key 缺点:
实现复杂存在误判可能 综上所述 我们可以两种方案一起用,这样子最为保险。据统计使用布隆过滤器一般可以避免90%的无效请求。但是黑马程序员这里的视频是使用方案一(缓存空对象)。
代码实现 思路图解 显然我们在这里只要做两件事:
当查询数据在数据库中不存在时,将空值写入 redis 判断缓存是否命中后,再加一个判断是否为空值 @Override public Result queryById(Long id) { // 从redis查询商铺缓存 String key = CACHE_SHOP_KEY + id; String shopJson = stringRedisTemplate.
我们在数据处理的时候,有时需要统计数组中某个元素的个数,如果写个循环就太麻烦了,numpy中有相应的函数进行统计。
1 np.sum() 进行统计 np.sum() 有个特性,当数组为[True,False]时会累加True的个数
所以当我们需要计算数组array中值value的个数时,使用语句:np.sum(data == value) 即可
当我们需要计算数组array中大于值value的个数时,使用语句:np.sum(data > value) 即可
实例1 统计等于某元素的个数: import numpy as np data=np.array([[1,2,3],[0,1,2],[3,4,5]]) print("查看数组中各位置是否为1 \n",data == 1) n = np.sum(data == 1) print("数组中1的个数",n) 输出结果:
查看数组中各位置是否为1 [[ True False False] [False True False] [False False False]] 数组中1的个数 2 实例2 统计满足条件的元素的个数 import numpy as np data=np.array([[1,2,3],[0,1,2],[3,4,5]]) n = np.sum(data > 1) print("数组中元素大于1的个数为",n) 结果
数组中元素大于1的个数为 6 参考文献 python 统计数组中某个元素的个数
使用numpy中fill函数将数组某一行所有值修改为特定值 array_col.fill(value):将数组的第col列的值全部修改为value array_col: 你要修改的列 value:你要修改为的值 1. 预备知识 – 数组列/行的获取,以二维数组为例 获取第i行: array[i] 获取第j列: array[:,j] 注:行列皆为从第0行开始 import numpy as np array = np.arange(0,20).reshape(4,5) print("数组值为",array) print("第2行:",array[2]) print("第3列",array[:,3]) 输出结果:
数组值为 [[ 0 1 2 3 4] [ 5 6 7 8 9] [10 11 12 13 14] [15 16 17 18 19]] 第2行: [10 11 12 13 14] 第3列 [ 3 8 13 18] 2 修改行列值 import numpy as np array = np.arange(0,20).reshape(4,5) # 修改第2行的值全为0 array[2].
首先回顾一下CBAM注意力机制:
在CBAM中,通道的注意力使用的是:首先对特征图分别进行一个全局MaxPool和AvgPool操作,再将得到的特征图进行一个共享的感知机,生成两个特征向量,对两个特征向量进行相加,然后进行一个sigmod操作。这样得到了一个通道域的注意力权重。
个人感觉就是将特征图沿着通道找出一个特征点(如上图中,全局MaxPool操作就是将一个特征图H*W*C暴力转换为一个1*1*C的,即在一个H*W的矩阵中找一个最大值作为其中1*1的值,一共找通道数C个)
我们再回顾一下BAM:
BAM的目的就只有一个:对原特征进行重构。依靠权重进行调整。网络图如下:
对于输入特征图F有
M即为一系列操作,对F进行M操作后,得到一个特征图权重系数矩阵是H*W*C维的。这与输入F的维度相符,因此可以最后的步骤为:对F和M(F)进行按元素相乘,再将F与之相加形成残差块。
BAM是一个混合域的注意力机制。因此它有两个分支,Channel branch和Spatial branch
对于Channel branch而言,它对于输入特征图F的操作为:
其中MLP可视为全连接层
全连接层的计算如下:对于输入向量X,每个神经元输出计算向量X的逻辑斯特回归,再经过一个激活函数:如rule,sigmod·增加网络的非线性。
这也就是说BAM的通道注意力部位的计算步骤是这样的:对于一个输入F,首先进行一个全局平均池化,再过两个全连接层,第一个层的神经元个数为c / r,其中r是一个超参数,用于调节网络神经元个数(起到一个降参的作用)。
对于Spatial branch:先进行降维打击,即经过一个1*1的卷积,然后经过两个3*3的空洞卷积,再通过1*1的卷积,得到:
其中
这个过程中1*1的卷积的作用在于升/降维。从最后的输入M可以看出,这是将一个H*W*C的特征图把通道的维度将为1,这样每个像素点代表了原来C个通道像素点的信息。因为得到的是一个H*W的平面,因此称为空间域的注意力机制。
需要注意的是:这里最开始的降维处理跟Channel branch中的bottle neck一样都为c/r
在最后需要将通道和空间这两个部分的权重进行一个组合。也即Combine branch。
BAM中的组合操作是将通道和空域的权重矩阵进行相加,首先要进行维度的统一。毕竟通道权重矩阵的维度是1*1*C而空域的权重矩阵系数是H*W*1,调整的方式也很简单,最后都是调成维度维H*W*C,通道的权重是将每个通道中都扩展为H*W,每个面(H*W)中的值都是当初那个唯一的值。空域的权重扩展是将面进行复制,复制C个。这样两者都成为了H*W*C。
在最后需要元素相乘并于F相加形成残差快。
而CBAM与BAM的不同在于:通道域使用一个全局平均一个全局最大池化,然后共用一个MLP,
在空间域上BAM使用的是3*3的空洞卷积,通过1*1的卷积进行降维,而CBAM用了一个固定的7*7的卷积,或者为固定的3*3,并且是对一个拼接的矩阵进行操作,维度为H*W*2。
二者的不同还在于,BAM是一个并行的结构,而CBAM采用了一个串行的结构。
另外,BAM的作者表明BAM再Bottle neck处更加有效,而CBAM则是插在卷积块之中更有效。
毕竟CBAM全称(Convolutional Block Attention Module)而BAM全称(Bottleneck Attention Module)
在 Windows 10 环境 Docker Desktop V4.11.1 版本中为 Kubernetes 开通 30000 以下端口的使用
# 参考: # https://cloud.tencent.com/developer/ask/sof/1518474 # https://stackoverflow.com/questions/64758012/location-of-kubernetes-config-directory-with-docker-desktop-on-windows # 当 Kubernetes 使用 NodePort 方式对外提供服务的时候, Kubernetes 默认使用 30000-32767 端口 # 如果需要使用 80, 443, 3306 等端口,会给出如下错误提示: # provided port is not in the valid range. The range of valid ports is 30000-32767 # 如果需要使用 30000 以下端口 需要执行如下操作: # 运行一个特权docker容器 docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh # 编辑 kube-apiserver 配置文件 vi /etc/kubernetes/manifests/kube-apiserver.
第五篇 Service Service,即Android服务,是Android四大组件之一,是一种程序后台运行的方案,用于不需要用户交互,长期运行的任务场景。可用以做一些耗时或者监听操作。
概述 Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务的组件(Activity)已销毁也不受影响。 此外,组件可以绑定到服务,以与之进行交互,甚至是执行进程间通信 (IPC)。 例如,服务可以处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序交互,而所有这一切均可在后台进行。
在AndroidManifest中的配置 对于Service 我们可以在AndroidManifest进行如下的一些配置:
<service android:enabled=["true" | "false"] //是否能够启用 android:exported=["true" | "false"] //是否暴露三方调用 android:icon="drawable resource" //Service图标 未设置默认为应用图标 android:isolatedProcess=["true" | "false"] //进程孤立 android:label="string resource" //Service名称 android:name="string" //对应Service类名 android:permission="string" //权限声明 android:process="string" > //给Service指定运行的进程 未设置默认为应用主进程 . . . </service> 配置含义:
android:enabled:是否可以被系统实例化,默认为 true因为父标签 也有 enable 属性,所以必须两个都为默认值true 的情况下服务才会被激活,否则不会激活。android:exported:代表是否能被其他应用隐式调用,其默认值是由service中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。为false的情况下,即使有intent-filter匹配,也无法打开,即无法被其他应用隐式调用。android:icon :Service图标 可在系统设置中查看 默认应用iconandroid:isolatedProcess :设置 true 意味着,服务会在一个特殊的进程下运行,这个进程与系统其他进程分开且没有自己的权限。与其通信的唯一途径是通过服务的API(bind and start)。android:label:Service名称 默认Service Name名称android:name:对应Service类名,即Service在工程中位置+名称android:permission:调用此Service需要的权限,可自定义权限增加Service安全。如没设置,此Service就没权限要求。android:process:是否需要在单独的进程中运行,当设置为android:process=”:remote”时,代表Service在单独的进程中运行。注意“:”很重要,它的意思是指要在当前进程名称前面附加上当前的包名,所以“remote”和”:remote”不是同一个意思,前者的进程名称为:remote,而后者的进程名称为:App-packageName:remote。 Service的两种状态 启动状态
当应用组件(如 Activity)通过调用 startService() 启动服务时,服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响,除非手动调用才能停止服务, 已启动的服务通常是执行单一操作,而且不会将结果返回给调用方。
文章目录 (硅谷课堂项目)Java开发笔记5:讲师管理模块前端一、设置路由定义1、修改路由2、创建vue组件3、form.vue4、list.vue 二、讲师分页列表1、定义api2、初始化vue组件3、定义data4、定义methods5、表格渲染6、分页组件7、顶部查询表单 三、讲师删除1、定义api2、定义methods 四、讲师新增1、定义api2、初始化组件3、实现新增功能 五、讲师修改-数据回显1、定义api2、组件中调用api3、页面渲染前调用fetchDataById 六、讲师修改-更新1、定义api2、组件中调用api3、完善saveOrUpdate方法 七、讲师批量删除1、定义api2、初始化组件3、实现功能 (硅谷课堂项目)Java开发笔记5:讲师管理模块前端 一、设置路由定义 1、修改路由 修改 src/router/index.js 文件,重新定义constantRouterMap
**注意:**每个路由的name不能相同
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) /* Layout */ import Layout from '@/layout' export const constantRoutes = [ { path: '/login', component: () => import('@/views/login/index'), hidden: true }, { path: '/404', component: () => import('@/views/404'), hidden: true }, { path: '/', component: Layout, redirect: '/dashboard', children: [{ path: 'dashboard', name: 'Dashboard', component: () => import('@/views/dashboard/index'), meta: { title: 'Dashboard', icon: 'dashboard' } }] }, { path: '/vod', component: Layout, redirect: '/vod/teacher/list', name: 'vod', meta: { title: '讲师管理', icon: 'el-icon-s-help' }, children: [ { path: 'teacher/list', name: 'TeacherList', component: () => import('@/views/vod/teacher/list'), meta: { title: '讲师列表', icon: 'table' } }, { path: 'teacher/create', name: 'TeacherCreate', component: () => import('@/views/vod/teacher/form'), meta: { title: '添加讲师', icon: 'tree' } }, { path: 'teacher/edit/:id', name: 'TeacherEdit', component: () => import('@/views/vod/teacher/form'), meta: { title: '编辑讲师' }, hidden: true } ] }, // 404 page must be placed at the end !
一、图像复原与图像增强的区别
图像增强的目的是消除噪声,显现那些被模糊了的细节或简单地突出一幅图像中读者感兴趣的特征,不考虑图像质量下降的原因。图像复原是利用退化现象的某种先验知识,建立退化现象的数学模型,再根据模型进行反向的推演运算,以恢复原来的景物图像。因此图像复原可以理解为图像降质过程的反向过程。建立图像复原的反向过程的数学模型是图像复原的主要任务。
二、逆滤波复原
1、基本原理
f(x,y)表示输入图像,即理想的、没有退化的图像,g(x,y) 是退化后观察得到的图像,n(x,y)为加性噪声。通过傅立叶变换到频域后为:
图像复原的目的是给定G(u,v)和退化函数H(u,v),以及关于加性噪声的相关知识,得到原图像F(u,v)的估计图像F’(u,v),使该图像尽可能地逼近原图像F(u,v)。用于复原一幅图像的最简单的方法是构造如下的公式:
然后通过F’(u,v)的傅立叶反变换得到图像的估计值,称为逆滤波。逆滤波是一种非约束复原方法。非约束复原是指在已知退化图像G(u,v)的情况下,根据对退化模型H(u,v)和噪声N(u,v)的一些知识,做出对原图像的估计F’(u,v),使得某种事先确定的误差准则为最小。在得到误差最小的解的过程中,没有任何约束条件。对于直接逆滤波,由于存在噪声的影响,退化图像的估计公式为:
在进行逆滤波时,如果某个区域H(u,v)为0或非常小,而N(u,v)不为0且不是很小,则上式中的第2项往往比第1项大得多,从而使噪声放大,产生较大的误差。为了避免H(u,v)的值太小,可以在逆滤波时加一些限制,只在原点附近的有限邻域内进行复原,称为伪逆滤波。
2、matlab实现
% 通过逆滤波器对图像进行复原 close all; clear all; clc; I=imread('cameraman.tif'); I=im2double(I); % 构造高斯低通滤波器 s=fftshift(fft2(im2double(I))); [a,b]=size(s); D0=100; % 将高斯低通滤波器的截止频率D0设置为100 a0=round(a/2); b0=round(b/2); H=zeros(a,b); for i=1:a for j=1:b distance=sqrt((i-a0)^2+(j-b0)^2); % 根据高斯低通滤波器公式H(u,v)=e^-[D^2(u,v)/2*D0^2] H(i,j)=exp(-(distance^2)/(2*(D0^2))); % exp表示以e为底的指数函数 end end N=0.01*ones(a,b); % 本例中a=b=256,此处亦有a=size(I,1),b=size(I,2) N=imnoise(N,'gaussian',0,0.001); % 添加高斯噪声 J=fftfilter(I,H)+N; % 调用频域滤波函数并加入噪声 figure; subplot(121),imshow(I); title('原始图像'); subplot(122),imshow(J,[]); % 显示退化图像(采用高斯低通滤波器对图像进行退化,并添加均值为0,方差为0.001的高斯噪声进一步对图像进行退化) title('退化图像'); HC=zeros(a,b); M1=H>0.1; HC(M1)=1./H(M1); K=fftfilter(J,HC);% 逆滤波操作 HC=zeros(a,b); M2=H>0.01; HC(M2)=1./H(M2); L=fftfilter(J,HC);% 逆滤波操作 figure; subplot(121),imshow(K,[]);% 逆滤波复原,频率大 title('逆滤波时频率范围较大得到的图像'); subplot(122),imshow(L,[]);% 逆滤波复原,频率小 title('逆滤波时频率范围较小得到的图像'); function Z = fftfilter(X,H) % 图像的频域滤波处理 % X为输入图像 % H为滤波器 % Z为输出图像 F=fft2(X,size(H,1),size(H,2));% 傅里叶变换 Z=H.
站位
站位
站位
站位
Vue使用pinia管理数据 Vue3 + TS 步骤: 在main.ts中注册 pinia
import { createPinia } from 'pinia' const pinia = createPinia() app.use(pinia) 创建文件store/modules/home.ts,用于管理home模块的数据
import { defineStore } from 'pinia' const useHomeStore = defineStore('home',{ state:()=>({ name:'tony' }) }) export default useHomeStore 创建store/index.ts统一管理所有的模块
import useHomeStore from './modules/home' const useStore = () => { return { home:useHomeStore() } } export default useStore 测试
import useStore from '@/store' const { home } = useStore() console.log(home.tony) 实际操作:使用 Pinia 获取头部分类导航 在store/modules/home.
文章目录 一、前言二、资源1. WPF对象级资源的定义与查找2. 且“静”且“动”用资源3. 向程序添加二进制资源4. 使用Pack URI路径访问二进制资源 三、总结 一、前言 我们把有用的东西称为资源。“兵马未动,粮草先行”——程序中的各种数据就是算法的原料和粮草。程序中可以存放数据的地方有许多,可以放在数据库里、可以存储在变量里。介于数据库存储和变量存储之间,我们还可以把数据存储在程序主体之外的文件里。外部文件与程序主体分离,这就有可能丢失或损坏,为了避免丢失或损坏,编译器允许我们把外部文件编译进程序主体、成为程序主体不可分割的一部分,这就是传统意义上的程序资源(也称为二进制资源)。
WPF不但支持程序级的传统资源,同时还推出了独具特色的对象级资源,每个界面元素都可以携带自己的资源并可被自己的子级元素共享。比如各种模板(Template)、程序样式(Style)和主题(Themes)就经常放在对象级资源里。这样一来,在WPF程序中数据就分为四个等级存储了:数据库里的数据相当于放在仓库里,资源文件里的数据就相当于放在旅行箱里,WPF对象资源里的数据相当于放在随身携带的背包里,变量中的数据相当于拿在手里。
二、资源 1. WPF对象级资源的定义与查找 每个WPF的界面元素都具有一个名为Resources的属性,这个属性继承自FrameworkElement类,其类型为ResourceDictionary。ResourceDictionary能够以“键-值”对的形式存储资源,当需要使用某个资源时,使用“键-值”对可以索引到资源对象。在保存资源时,ResourceDictionary视资源对象为Object类型,所以在使用资源时先要对资源对象进行类型转换,XAML编译器能够根据标签的Attribute自动识别资源类型,如果类型不对就会抛出异常,但在C#代码里检索到资源对象后,类型转换的事情就只能由我们自己来做了。
在之前的WPF介绍中说过,XAML中的标签元素对应到后台C#代码,可以看作是对象的实例化。
也就是XAML中的<xxx/> 相当于C#中的 xxx x = new xxx();
这样理解有什么好处呢?
至少我第一次接触XAML,看到Resource中加各种各样的东西是很不习惯的。
而将Resources中添加元素看成上述形式后,
其实就是 ResourceDictionary rd = new ResourceDictionary();
rd.Add(a); rd.Add(b);…
这不是和后台代码对应起来了么?
而且查看ResourceDictionary类型发现它就是一个通用集合类型。
ResourceDictionary可以存储任意类型的对象。在XAML代码中向Resources添加资源时需要把正确的名称空间引入到XAML代码中。看个例子:
<Window x:Class="WpfResourceDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfResourceDemo" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" Title="Resource" Height="250" Width="400"> <Window.Resources> <ResourceDictionary> <sys:String x:Key="str"> 床前明月光,疑是地上霜。 </sys:String> <sys:Double x:Key="db1">3.1415926</sys:Double> </ResourceDictionary> </Window.Resources> <StackPanel> <TextBlock Text="{StaticResource ResourceKey=str}" Margin="5"/> <!--TextBlock Text="{StaticResource ResourceKey=db1}" Margin="5"/--> </StackPanel> </Window> 首先将System命名空间引入XAML代码并映射为sys命名空间,然后在Window.
1、全选、全不选:
function checkAllFun(a){ if (a.checked){ $("input[name='checkbox']:checkbox").each(function(){ $(this).prop("checked", true); }); } else { $("input[name='checkbox']:checkbox").each(function() { $(this).prop("checked", false); }); } }; 2、获取复选框的值
方法一: var updateProSkuIds =[]; $('input[name="productSkuId"]:checked').each(function(){ updateProSkuIds.push($(this).val()); }); if(updateProSkuIds.length == 0){ layer.msg("你还没有选择任何要设置!"); return; }; if(updateProSkuIds.length > 1){ layer.msg("最多只能选一条设置!"); return; }; 方法二: var ids =[]; $('input[name="checkbox"]:checked').each(function(){ ids.push($(this).val()); }); 3、回选
$(function(){ //获得所要回显的值,此处为:100,1001,200,1400 var checkeds = '${user.userHobby}'; //拆分为字符串数组 var checkArray =checkeds.split(","); //获得所有的复选框对象 var checkBoxAll = $("input[name='userHobby']"); //获得所有复选框(新闻,微信,论坛,问答,博客,平媒)的value值,然后,用checkArray中的值和他们比较,如果有,则说明该复选框被选中 for(var i=0;i<checkArray.length;i++){ //获取所有复选框对象的value属性,然后,用checkArray[i]和他们匹配,如果有,则说明他应被选中 $.each(checkBoxAll,function(j,checkbox){ //获取复选框的value属性 var checkValue=$(checkbox).
第1步:在github项目中下载或者自行生成所需的requirement.txt文件,将其放在任一路径位置。例如 D:\requirement.txt\requirement.txt
第2步:使用anaconda prompt直接进入指定环境,例如我这里进入tat-qa这个环境。
conda activate tat-qa 第3步:直接安装,注意在requirement.txt前指定好本地路径即可。
pip install -r D:\requirement.txt\requirement.txt 因为我本次所需环境仅有几个包,没有断掉,直接安装成功。介绍下两个容易出现的问题。
1)报错如下:
THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS FILE
原因:网速原因导致对应的哈希值不匹配,没下载完整文件。
方法1(推荐):使用镜像源下载例如清华源。例如清华源将第3步修改为
pip install -r D:\requirement.txt\requirement.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ 方法2:更换网络。
2)报错如下:
ERROR: Could not open requirements file: [Errno 2] No such file or directory: 'requirements.txt'
这是因为在安装该依赖包之前,需要在对应文件夹路径下先创建 requirements.txt 文件,该报错是没有找到对应的文件。
方法1:断了以后直接从断点包借助清华源继续下载,简单粗暴。例如gensim。
# 清华源 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple gensim #豆瓣源 pip install gensim -i http://pypi.douban.com/simple --trusted-host pypi.douban.com 方法2:通过加命令,让出现该报错跳过没有的包继续安装,比对缺失的包之后,再自己安装缺失的包。
Vue项目吸顶功能实现—@vueuse/core的使用 电商网站的首页内容会比较多,页面比较长,为了能让用户在滚动浏览内容的过程中都能够快速的切换到其它分类。需要分类导航一直可见,所以需要一个吸顶导航的效果。
核心步骤:
目标: 完成头部组件吸顶效果的实现
交互要求
滚动距离大于等于 78 的时候,组件会在顶部固定定位滚动距离小于 78 的时候,组件消失隐藏 实现思路
准备一个吸顶组件,准备一个类名,控制显示隐藏监听页面滚动,判断滚动距离,距离大于 78 添加类名 静态结构 核心代码:
在 Layout/components/下,新建 app-header-sticky.vue 组件 <script setup lang="ts"> import { RouterLink } from "vue-router"; import AppHeaderNav from "./app-header-nav.vue"; </script> <template> <div class="app-header-sticky" :class="{ show: true }"> <div class="container"> <RouterLink class="logo" to="/" /> <AppHeaderNav /> <div class="right"> <RouterLink to="/">品牌</RouterLink> <RouterLink to="/">专题</RouterLink> </div> </div> </div> </template> <style scoped lang="less"> .app-header-sticky { width: 100%; height: 80px; position: fixed; left: 0; top: 0; z-index: 999; background-color: #fff; border-bottom: 1px solid #e4e4e4; // 此处为关键样式!
目录
检查客户端与DHCP服务器之间的连通性 检查中间链路转发DHCP报文是否正确
检查DHCP基本配置是否正确
检查地址池是否有可用IP地址
检查STP生成树状态是否影响IP地址获取
检查是否针对DHCP的攻击或者私接设备
收集信息并寻求技术支持
检查客户端与DHCP服务器之间的连通性 操作步骤
1、当客户端(一般指PC)与服务器(交换机作为DHCP服务器)在同一个网段,之间没有中继设备时,在客户端上配置IP地址,该地址要与服务器VLANIF接口地址属于同一个网段,从客户端Ping VLANIF接口的IP地址。
当客户端与服务器不在同一个网段内,中间存在中继设备时,请分别检查客户端与中继设备、中继设备与服务器之间的链路状态是否正常
如果Ping不通,请先检查链路连通性。
检查中间链路转发DHCP报文是否正确 操作步骤
当客户端与服务器在同一个网段时,请将客户端直连到DHCP服务器上,尝试能否正常获取IP。
如果客户端能够正常获取IP,说明中间链路转发DHCP报文异常,请检查中间链路设备是否出现了CPU高、配置DHCP snooping 但是没有配置信任端口等情况。
如果客户端无法获取IP,请检查服务器是否设置正确,以及是否有空闲IP地址
如果不方便进行客户端进行服务器直连测试,请在客户端与服务器上分别获取报文信息,确认DHCP报文是否交互正确。
检查DHCP基本配置是否正确 操作步骤
DHCP服务器配置分为全局地址池及地址池两种方式,可通过命令display current-configuration | include dhcp 查看DHCP的配置,如果无DHCP配置可参考如下举例,重新进行配置。
举例:配置接口VLANIF100 采用接口地址池的DHCP服务功能
部分交换机不支持做DHCP服务器,无法配置相关命令
检查地址池是否有可用IP地址 操作步骤
1、执行命令display ip pool name ip-pool-name,检查全局地址池中IP地址使用情况;或者执行命令display ip pool interface vlanif, 检查接口地址池中IP地址使用情况。
如果Idle(Expired)值等于零,说明地址池中的IP地址已经用尽,如果确认正常使用地址池不够,可以调整地址池掩码长度。
如果Conflict值较大,说明IP地址产生大量冲突,可通过reset ip pool 命令重置地址来手动回收地址IP地址。
2、一下列出了几种典型的配置报错,可针对具体报错做排错修改。
掩码设置有问题,需要调整地址池掩码长度
Error: The IP address number of single interface pool must be less than 65536.
无法配置保留IP,需要排查该IP是否已经被分配出去或者被占用。
Error: Only idle or expired IP address can be disabled.
gorm事务 目录 gorm事务准备工作禁用默认事务事务嵌套事务手动事务SavePoint、RollbackTo 准备工作 建立数据库连接
import ( "fmt" _ "github.com/go-sql-driver/mysql" "gorm.io/driver/mysql" "gorm.io/gorm" "log" ) var db *gorm.DB func OpenDB() { dsn := "root:adss123@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True&loc=Local" res, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) db = res if err != nil { log.Fatal(err) } fmt.Printf("成功:%v\n", db) } 建立一个表
type TransactionTest struct { gorm.Model Name string } 禁用默认事务 为了确保数据一致性,GORM 会在事务里执行写入操作(创建、更新、删除)。如果没有这方面的要求,您可以在初始化时禁用它,这将获得大约 30%+ 性能提升。
// 全局禁用 db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{ SkipDefaultTransaction: true, }) // 持续会话模式 tx := db.
一、
1.源地址测试 2.网络管理地址范围测试 3.BSM状态测试
4.Bus Sleep Mode进入Repeat Message State测试
5.Repeat Message State进入Normal Operation State测试
6.Repeat Message State进入Ready Sleep State测试
7.Normal Operation State进入Repeat Message State测试
8.Normal Operation State进入Ready Sleep State测试
9.Ready Sleep State进入Repeat Message State测试
10.Ready Sleep State进入Normal Operation State测试
11.Ready Sleep State进入Prepare Bus Sleep Mode测试
12.Prepare Bus Sleep Mode进入Repeat Message State测试
13.Prepare Bus Sleep Mode进入Bus Sleep Mode测试
14.BusOff错误模式处理测试
15.节点掉线错误处理测试
16.诊断报文唤醒测试
17.诊断维持唤醒测试
18.CAN初始化时间测试
19.周期帧发送时间测试
20.接收使能时间测试
21.网络关闭时间测试
22.工作电流电流测试
目录
1.打印100~200之间的素数
2.打印闰年(重点在于如何判断闰年)
3.9*9乘法口诀表
4.1-100之间数字9的个数
5.水仙花数
6.最大公约数
7.模拟用户登录情景,并且只能登录三次
8.演示多个字符从两端移动,向中间汇聚
9.二分查找(折半查找算法)
10.猜数字小游戏
1.打印100~200之间的素数 首先我们应该了解什么是素数
素数:是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
首先我们用for循环去遍历需要筛选的数字,接着再根据素数的判断条件加以判断,然后打印出素数
#include<stdio.h> int main() { int i = 0; for (i = 100; i <= 200; i += 1) { int j = 0; //判断i是否为素数:用[2, i)之间的每个数据去被i除,只要有一个可以被整除,则不是素数 for (j = 2; j < i; j++) { if (i % j == 0) { break; } } // 上述循环结束之后,如果j和i相等,说明[2, i)之间的所有数据都不能被i整除,则i为素数 if (i == j) printf("%d ", i); } return 0; } 进一步优化:
// CUDA runtime 库 + CUBLAS 库 #include "cuda_runtime.h" #include "cublas_v2.h" #include <time.h> #include <iostream> using namespace std; // 定义测试矩阵的维度 int const M = 5; int const N = 10; int main() { // 定义状态变量 cublasStatus_t status; // 在 内存 中为将要计算的矩阵开辟空间 float *h_A = (float*)malloc(N*M * sizeof(float)); float *h_B = (float*)malloc(N*M * sizeof(float)); // 在 内存 中为将要存放运算结果的矩阵开辟空间 float *h_C = (float*)malloc(M*M * sizeof(float)); // 为待运算矩阵的元素赋予 0-10 范围内的随机数 for (int i = 0; i < N*M; i++) { h_A[i] = (float)(rand() % 10 + 1); h_B[i] = (float)(rand() % 10 + 1); } // 打印待测试的矩阵 cout << "
表格组件的排序功能,点击排序表头可以进行升序和降序进行排序
重点:数据由后台进行排序时sortable="custom",需要监听排序点击事件,会返回当前的prop和order,<el-table需要添加事件@sort-change="changeSort"
如果需要对表格的那一列进行排序,加一个sortable参数,可取的值有true,false,custom
<el-table :data="tableData" style="width: 100%" <!-- 数据由后台进行排序时sortable="custom",需要监听排序点击事件,会返回当前的prop和order --> @sort-change="changeSort" <!-- default-sort指定的默认排序,默认用date这一列排序,排序为升序,默认的排序也是升序 --> :default-sort="{prop: 'date', order: 'ascending'}" border> <el-table-column prop="date" label="日期" <!-- 如果需要对表格的那一列进行排序,加一个sortable参数,可取的值有true,false,custom --> sortable <!-- sort-orders接收一个数组,用来指定点击可排序表头时排列的顺序,默认是['ascending', 'descending', null]点击时先升序ascending,再点击降序descending,再点击不排序null,按表格的默认索引排.可以自己设置排列顺序 --> :sort-orders="['ascending', 'descending']" width="180"> </el-table-column> <el-table-column prop="name" label="姓名" <!-- sort-by指定数据按哪个属性进行排序,如果不指定,就是按这里的prop值排,指定一个时写成字符串形式:sort-by="name",指定多个时,使用数组.这里的效果就是,当姓名的值全部一样时,就按address进行排序 --> :sort-by="['name', 'address']" sortable width="180"> </el-table-column> <el-table-column prop="address" label="地址" <!-- 以上的参数排序都是在已得到的tableData数据上进行排序,如果数据做了分页当前的数据不是全部的数据时,排序就需要后台进行排序,这时需要把sortable的值改为custom,在table中用sort-change事件监听排序点击事件 --> sortable="custom"> </el-table-column> </el-table> methods: { // 从后台获取数据,重新排序 changeSort (val) { console.log(val) // column: {…} order: "ascending" prop: "
定义 import random random.seed(x) print('随机数:',random.random()) seed从字面意思上翻译为 "种子",我们可以通过参数 "x" 改变随机数生成器的种子seed,即从不同的 "x" 可以得到不同的随机数生成器的种子。
每颗种子能够生长为一组固定顺序的随机数序列,其通常和random.random()搭配使用以生成一个随机数。
例如:若假定random.seed(1)生成的随机数序列为(1,2,3,4),则调用四次random.random()函数,产生的数依次为1,2,3,4。如果期间又执行了random.seed(1)语句,下一步调用random.random()函数产生的数又将变为1,即从开头开始,按照固定顺序推进。
参照下面的实例一目了然
实例 import random # 当不给出x的具体值时,系统将根据时间自己选择x的值 # 每次生成的随机数序列因时间差异而不同,所得到的随机数就不一样 random.seed() print('随机数1:',random.random()) random.seed() print('随机数2:',random.random()) # 当x=1时,同一颗种子将生成固定顺序的随机数序列 random.seed(1) print('随机数3:',random.random()) print('随机数4:',random.random()) #这里重复执行了random.seed(1),因此又将从头开始,生成0.13436424411240122 #现实意义可参照 while 循环等 random.seed(1) print('随机数5:',random.random()) # 这里x=2时,注意和上面区分,种子长出了一棵新的树(序列) random.seed(2) print('随机数6:',random.random()) 随机数1: 0.9250541321707577 随机数2: 0.18139904497935255 随机数3: 0.13436424411240122 随机数4: 0.8474337369372327 随机数5: 0.13436424411240122 随机数6: 0.9560342718892494 总结 random.seed() 是一种非常方便的生成随机数的方法
1.如果使用相同的x值,则每次生成的随即数序列都相同;
2.如果不设置x值,系统将根据时间自动选择x值,此时生成的随机数序列因时间差异而不同;
3.对于同一x值,若多次执行random.seed(x),将按照固定的序列顺序从头开始生成随机数。
错误信息 found character '@' that cannot start any token. (Do not use @ for indentation) in 'reader', line 4, column 13: active: @profileActive@ 说@profileActive@这里出问题了
按照网上的解决思路,需要重新加载项目,然后重新编译就没事了。
我尝试了两次,发现还是有问题
解决方法 后来通过网上的另外一个方案解决了。
解决方案如下
在pom文件的build中添加resources,在里面引用profileActive来解决这个问题。
栅格系统 栅格系统(Grid Systems),即网格系统,它是一种清晰、工整的设计风格,用固定的格子进行网页布局。栅格系统最早应用于印刷媒体上,一个印刷版面上划分了若干个格子,非常方便排版。
后来,棚格系统被应用于网页布局中,使用响应式栅格系统进行页面布局时,可以让一个网页在不同大小的屏幕上,呈现出不同的结构。
例如~在小屏幕设备上有某些模块将按照不同的方式排列或者被隐藏
栅格系统的行和列
Bootstrap栅格系统是指将页面布局划分为等宽的列。随着屏幕或视口尺寸的增加,系统会自动分为1~12列。
栅格系统用于通过一系列的行(row)与列(column)的组合来创建页面布局。
开发者可以将内容放入这些创建好的布局中,然后通过列数的定义来模块化页面布局。
栅格系统页面的内容可以放入这些创建好的布局容器中,并且会根据父元素盒子(布局容器)尺寸的大小进行适当地调节,从而达到响应式页面布局的效果。
栅格系统的基本使用方式
1.Bootstrap棚格系统为不同屏幕宽度定义了不同的类,直接为元素添加类名即可。
2.行必须包含在布局容器中,以便为其赋予合适的排列和内补。
3.通过行可以在水平方向创建一组列并且只有列可以作为行的直接子元素。
4.行使用样式.row,列使用样式.col--,内容应当放置于列内,列大于12时,将会另起一行排列。
栅格系统的类前缀
栅格系统提供了基本的前缀,用于在不同宽度的屏幕中实现不同的排列方式,列的类名可以写多个,也就是可以同时设置.col-、.col-sm-、.col-md-、.co-/g-和.col-xl*类名。当同时使用这些类的时候,它会根据当前屏幕的大小来使相应的类生效,实现在不同屏幕下展示不同的页面结构。
超小屏幕<576px平板≥576px桌面显示器≥768px大桌面显示器≥992px超大桌面显示器≥1200px.container最大容器宽度(自动)100%540px720px960px1140px类前缀.col-.col-sm-.col-md-.col-lg-.col-xl- 使用类前缀设置列的宽度
由于栅格系统就是默认将父元素分成12等份,所以可根据占据的份数来设置子元素的宽度,在设置列的宽度时,只需要在不同的类前缀后面加上栅格数量即可。
col-栅格的数量(设置超小设备);
col-sm-栅格的数量(设置平板);
col-md-栅格的数量(设置桌面显示器);
col-lg-栅格的数量(设置大桌面显示器);
col-xl-栅格的数量(设置超大桌面显示器);
offset列偏移
栅格系统:使用.offset-md-类将列向右侧偏移
主要是通过使用offset-md-获取到当前元素并且增加了当前元素左侧的边距(margin)来实现的。
md可以使用sm、xl和lg等替代,分别表示在不同屏幕下设置列的偏移。
布局容器 容器是Bootstrap中最基本的布局元素,容器用于在其中容纳、填充一些内容,以及有时需要使内容居中。
在实现Bootstrap页面布局容器之前,需要了解设备屏幕的尺寸。
屏幕大小常见宽度范围超小屏幕<576px平板≥576px桌面显示器≥768px大桌面显示器≥992px超大桌面显示器≥1200px Bootstrap带有3个不同的容器,具体如下:
.container容器
它在每个响应断点处设置了一个max-width最大宽度,.container设置容器居中显示
.container-fluid容器
它在每个响应断点处设置布局容器的宽度为100%,.container-fluid类设置容器始终占据视口100%
.container-(breakpoint}容器
它在每个响应断点处设置布局容器的宽度为100%,直到达到指定的断点为止。
组件 组件是一个抽象的概念,是对数据和方法的简单封装。用面向对象思想来说,将一些符合某种规范的类组合在—起就构成了组件,通过组件可以为用户提供某些特定的功能。
组件是构成页面中独立结构单元,是对结构的抽象,它主要以页面结构形式存在,可复用性很强。组件的使用并不复杂,每个组件拥有自己的作用域,每个组件区域之间独立工作,并且互不影响。组件可以有自己的属性和方法。不同组件之间也具有基本的交互功能,能够根据业务逻辑来实现复杂的项目功能。
特点:
组件可以复用,提高开发效率
模块化
降低代码之间的耦合程度
代码更容易维护和管理
依赖文件
bootstrap组件依赖于Bootstrap框架,所以首先要引用bootstrap.min.css再引入jQuery文件,最后引入bootstrap.bundle.min.js,注意先后顺序,jQuery文件在bootstrap.bundle.min.js之前引入
前言:上一期文章,我们讲解了unittest框架的核心及使用方式,今天我们再来介绍另外一个框架:Pytest
一、pytest安装 a) 主流框架:
unittest -python自带
pytest -三方库
nose -三方库
behava -BDD
b) 安装Pytest:
1.安装命令:pip install pytest
2.设置pychram编译为:pytest
3.删除历史运行,不然pytest运行不了
二、pytest的使用 a) 具体使用
1.用例名称:
不可以有__init__() ,类下下面的方法也是如此
函数名,必须以 def test_开头
2.断言比对: 断言(实际和预期的对比 ) assert 表达式(True/False)
例子: assert random_num() == 7 我希望这个随机数是7
3.异常捕获: AssertionError就代表用例失败
用例抛其他异常了
异常报错示例: b) 编写用例及运行
用例示例:
import pytest class TestDemo: #类名以Test开头,不然识别不了这个个用例类 #这里不能写__init__初始化函数,因为这是个测试类 def test_demo001(self): #函数名以Test开头,不然识别不用例 """测试用例函数""" assert 1 == 1 #assert:pytest内置的断言方法 ——》 assert A == B 断言A是否等于B def test_demo002(self): "
文章目录 前言1. Entity Framework Core反向工程定义2.实现工作原理3.准备工作4. 编写命令 前言 Entity Framework Core 是适用于 .NET 的新式对象数据库映射器。 它支持 LINQ 查询、更改跟踪、更新和架构迁移。 EF Core 适用于很多数据库,包括 SQL 数据库(本地和 Azure)、SQLite、MySQL、PostgreSQL 和 Azure Cosmos DB。 1. Entity Framework Core反向工程定义 EntityFramework Core 有基于实体类去生成数据库表 和 数据库表生成实体类两种工作机制。反向工程则是其中 的一种是基于数据库架构搭建**实体类型类**和 **DbContext 类基架**的过程 2.实现工作原理 反向工程从读取数据库架构开始。 它会读取有关表、列、约束和索引的信息。 接下来,它将使用架构信息创建 EF Core 模型。 使用表创建实体类型;使用列创建属性;使用外键创建关系。 最后,使用模型生成代码。 为相应实体类型类、Fluent API 和数据注释搭建基架,以便从应用重新创建相同的 模型。 3.准备工作 (1-1)在NuGet包中安装 Microsoft.EntityFrameworkCore.Tools(使用Visual Studio时使用) (1-2)在NuGet包中安装 Microsoft.EntityFrameworkCore.Design(使用命令行接口CLI时使用) (2)在NuGet包中安装 Pomelo.EntityFrameworkCore.MySql (根据自己使用的数据库选择不同的插件) 链接: Microsoft.EntityFrameworkCore.Tools 链接: Pomelo.EntityFrameworkCore.MySql 4. 编写命令 EntityFramework Core 可以通过PMC 和CLI两种工具命令来执行命令 **PMC**: Scaffold-DbContext EF Core 包管理控制台命令 **CLI**: dotnet ef dbcontext scaffold .
要求:获取某个字符指定字符的前面或后面的所有字符内容
##############取字符串中的某一部分############ E='V2A935.pdb' #取.之前 e=E[0:E.rfind('.')] #print 'A2A935' #取.之后 e=E[E.rfind('.'):] #print '.pdb' #取A和.之间 e=E[E.rfind('A'):E.rfind('.')] #print 'A935' 参考:http://www.cnblogs.com/syw20170419/
步骤一:写入镜像文件 下载Ubuntu20.04镜像文件:http://mirrors.163.com/ubuntu-releases/20.04/ubuntu-20.04.4-desktop-amd64.iso
下载软碟通:
UltraISO软碟通中文官方网站 - 光盘映像文件制作/编辑/转换工具
然后,我们需要一个存储空间大于4GB的U盘,插在电脑上,打开软碟通。
进行如下操作选择文件,并且打开你下载的 ubuntu 所在的目录,选择 ubuntu 镜像(改成选择自己的Ubuntu镜像即可),双击打开,如图:
然后在软碟通界面菜单栏选择启动,选择写入硬盘映像,如图所示:
1) 看你的硬盘驱动器是否对应的是你的 U 盘(必须是) ,一般默认是
2) 看映像文件是否对应你的 ubuntu 镜像
3) 如果上述均没有错误,选择格式化,之后就会格式化你的 U 盘
4) 在 U 盘格式化完毕之后,选择写入,之后就是慢慢等待了,等待写入完毕
步骤二:系统分盘 右键此电脑,打“管理”-“磁盘管理”,选择最后一个磁盘空间的磁盘,比如 CD两个盘的最后一个盘是D盘(CDE盘的最后一个E盘,CDEF盘的最后一个盘F盘,以此类推),右键点击该磁盘,选择压缩卷,结果如下:
我的建议是分出100GB以上,即102400MB,最好150GB以上,如果空间不够的话还请稍微清理一下磁盘空间
步骤三:Ubuntu安装 重启电脑,进入系统BIOS界面(一般电脑是F2,你可以F2和F12在开机的时候狂按,如果没用,百度搜索对应电脑型号进入BIOS的方法),将secure boot设置为disabled,同时将第一启动设置为U盘,保存设置(注意,也可以不设置第一启动,在开机时按F12来选择启动区)。
再次重启电脑,就会出现一个黑色界面,有五个选项,我们之间选择第一个然后enter,如果进入文件检查阶段,即开始安装ubuntu。
进入后选择install 第二步:选择语言的话建议选择英文English,否则会出莫名其妙的bug。
第三步:然后联网的话不连,直接下一步。
第四步:选择minimal install
第五步:选择something else
然后进入分区界面,往下拉,里面有一个 free space,即是刚刚压缩卷分出的空白区域。
我们点击该区域,点左下角+号,将这个free space分为四个区:
1)efi:这是ubuntu的启动分区,我们分出400MB
2)swap:这个是 Linux 也就是 ubuntu 的交换区目录,这个一般的大小为内存的 2 倍左右, 主要是用来在电脑内存不足的情况下,系统会调用这片区域,来运行程序,我们可以将其分为 8G, 3) /:这是 linux 也就是 ubuntu 的根目录就一个反斜杠表示,相当于windows的C盘, 我们将其分为 40G,文件格式为 ext4,条件允许可以大一点,可以60G,毕竟ubuntu装软件默认是装在这里的,大一点可能会省去后面隐藏的麻烦。
MyBatis中的一对多和对多一,多对多 主要就是resultMap中
1.association(关联) – 一个复杂的类型关联;许多结果将包成这种类型(多对一
嵌套结果映射 – 关联本身可以是一个 resultMap 元素,或者从别处引用一个
2. collection(集合) – 复杂类型的集合(一对多)
嵌套结果映射 – 集合本身可以是一个 resultMap 元素,或者从别处引用一个
多对一或一对多,实际上就是选择的参照表不一样
更多详细信息,在mybatis官方文档就能找到,建议大家可以直接看官方文档
什么是关联:
在mybatis中是用来处理"has a"关系,比如一个学生有一所学校,即一个学生关联一所学校,所以association能用来处理我们数据中所谓的一对一,多对一关系(一个学校有多个学生,但是对于学生来说,一个学生只能关联一个学校)。
什么是集合:
将嵌套映射的结果集合到一个list中,比如一个学校有多个学生,即1个学校对应多个学生,对于学校来说,一个学校有多个学生。
可以看到,在处理我们数据关系的时候,就是对这2个属性的使用,而一对多和多对一都是相互的,只是各自站的角度不同。
多对一 多对一首先就是在多方编写一方的实体类属性
然后编写嵌套查询的xml
多对一使用的是 collection 关联查询
多方的数据
一方的数据库
lombok的maven坐标
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> 多方的实体类(图中的注解使用的式lombok)
import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.ToString; import java.io.Serializable; /** * (ComponentPeijian)表实体类 * 多对一 * 在多方的实体类上面编写一方的实体类属性 * @author makejava * @since 2022-08-17 15:55:53 */ @SuppressWarnings("serial") @ToString @Data public class ComponentPeijian extends Model<ComponentPeijian> implements Serializable{ //配件编号 private Integer componentId; //类型编号 private Integer typeId; //配件说明 private String componentName; //容器 private String capacity; //价格 private Integer price; // @TableField(exist = false) //标识不是数据库的字段,但在项目中必须使用 // 多个配件对应一个类型 多对一关系 private ComputerType computerType; /** * 获取主键值 * * @return 主键值 */ @Override protected Serializable pkVal() { return this.
前言 在上一篇文章中:Spring Boot使用WebSocket模拟聊天 已经简单实现了我们WebSocket的Demo,里面使用的WebSocket事件函数在此做一个总结。
WebSocket整体通讯的流程就是 建立链接->发送消息->关闭链接/终止链接,这几步需要的事件Api主要就是以下几个
建立连接 当在客户端和服务器建立连接时,就会从`WebSocket`实例触发open事件。可以认为onopen是客户端和服务器之间的初始握手。 客户端代码 客户端通过new WebSocket指定WebSocket ServerEndpoint地址就可以与服务器建立连接
new WebSocket("ws://127.0.0.1:8080/api/websocket"); 服务端代码 服务端则需要@OnOpen注解标明建立连接时触发的方法和业务逻辑
@OnOpen public void onOpen(Session session){ log.info("客户端建立连接,Id为:{}",session.getId()); } 客户端回调 在连接建立成功后需要通知客户端连接已经建立成功,这一步操作WebSocket提供了onopen事件来进行客户端连接成功的回调操作,代码如下:
websocket.onopen = function() { console.log("WebSocket连接成功"); } 发送接收消息 WebSocket是双工通信,允许服务端主动发送消息到客户端,所以发送接收消息是双向的,他们的接受和发送消息的方式却各有不同 客户端发送消息 建立连接后客户端主动发送消息到服务端是通过send事件,客户端可以发送的信息包括纯文本消息,二进制数据或图像。
websocket.send(message); 服务端接受消息 在建立连接后无论客户端何时发送消息服务端都会触发OnMessage事件来接收消息数据,在Java中是通过
@OnMessage注解标明触发的方法的。
@OnMessage public void onMessage(String message,Session session){ log.info("客户端:{},接受到消息:{}",session.getId(),message); } 服务端发送消息 既然是双工通信服务端自然也可以给客户端发生消息,但发送消息是个主动的操作,并且还要知道发生给那个客户端,所以服务端发送消息不是用的注解方式,是通过WebSocket的Session类的两个方法
getAsyncRemotegetBasicRemote 两种的区别就是同步跟异步的消息发送方式,可以根据具体情况选择使用,发送的消息类型则有五种
sendText(): 此方法发送的消息是String类型,支持部分消息发送,通过boolean值操控sendBinary():此方法发送的消息是ByteBuffer类型,支持部分消息发送,通过boolean值操控sendObject():此方法发送的消息类型是Object类型sendPing():此方法发送的消息是ByteBuffer类型,ping是请求消息 没有特定类 byte buffersendPong():此方法发送的消息是ByteBuffer类型,pong是响应消息 它也可以用作单向心跳消息 注意:
sendPing和sendPong的字节数据不能大于125bytes。只能用来检测状态,不应用与业务数据传输。Ping消息只能发送(不能接收)而Pong可以发送和接收Ping的消息不需要写逻辑来明确地返回去响应一个ping - Java WebSocket API的实现会为你自动的处理 在业务上发送消息最常用的还是sendText与sendBinary,代码如下:
public void send(Session session, String msg) throws IOException { session.
方法不唯一,此处只列出七种方式
文章目录 第一种方法:利用margin第二种方法:利用定位:子绝父相第三种方法:利用定位:子绝父相第四种方法:利用伸缩盒/网格布局第五种方法:利用伸缩盒/网格布局第六种方法:利用定位以及平移:子绝父相第七种方法:利用margin和平移当子元素是行内元素时利用text-align以及line-height 第一种方法:利用margin 前提:父元素和子元素都设置了宽高
给父元素设置border避免外边距合并问题; margin-top/margin-bottom = (父height-子height)/2; margin-left/margin-right = (父width-子width)/2或者为auto; <div class="outer"> <div class="inner">aaa</div> </div> .outer { width: 500px; height: 500px; background-color: pink; border: 1px solid red; } .inner { width: 100px; height: 200px; background-color: skyblue; margin: 150px 200px; } 第二种方法:利用定位:子绝父相 前提:父元素和子元素都设置了宽高
给父元素设置position:relative; 子元素设置position:absolute 子元素设置偏移量:top、bottom、left、right都为0 子元素设置margin:auto <div class="outer"> <div class="inner">aaa</div> </div> .outer { width: 500px; height: 500px; background-color: pink; position: relative; } .inner { width: 100px; height: 200px; background-color: skyblue; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; } 第三种方法:利用定位:子绝父相 前提:父元素和子元素都设置了宽高
2022年8月 解决Windows 11 telnet命令无法使用问题 新电脑无法直接使用telnet命令,一般预装家庭版的Windows都会有这个问题,不过这只是没有给你加载,按照下文步骤可以轻松解决。 w7、10都直接可以找到,网上教程一大堆,这里只是针对Windows11 !!!
w11环境下,cmd中提示telnet不是内部命令,也不是可运行的程序或批处理文件。一张截图帮你解决!
废话不多说,直接上料
1、打开设置,找到应用。 2、选择可选功能,滑动到最下面,找到 更多Windows功能,勾选telnet即可 3、cmd正常测试即可,已经识别telnet命令
2020.2 IDEA maven设置home路径不成功 最近在2020.2IDEA中新起一个maven管理的springboot项目时,设置maven home路径老是失效。设置完成重新打开setting中的maven时还是选择${user}/.m2/wrapper中的maven,当我删除.m2目录重启IDEA时,它直接又生成了一个.m2/并在目录下下载一个maven。很奇怪,但是我其他项目又是可以设置成功,最后对比其他项目和我目前项目的文件区别,发现在我当前项目中多了一个.mvn目录,当我该目录之后,重新设置maven home路径成功了。
maven-wrapper.properties
原因:
我们配置了IDEA的maven后,默认情况下,所有项目都会使用配置的这个Maven版本。但是,对于某些项目来说,它可能必须使用某个特定的Maven版本,这个时候,Maven Wrapper就自动给这个特定的项目安装指定版本的Maven,而其他项目不受影响。简单地说,Maven Wrapper就是给一个项目提供一个独立的,指定版本的Maven给它使用。
【校内模拟】【状压DP】number 题目 解题思路 第一次听说变进制状压
先统计每个数字出现过的次数
然后用1~a[0]表示选了“0”的个数,一个“1”用a[0]+1,两个“1”用a[1]*2+1,以此类推
然后用一个数组g统计每种状态选了多少个数字
f[i][k]表示在i这种选法下,余数为k
代码 #include<iostream> #include<cstring> #include<cstdio> using namespace std; const long long p=998244353; string s; int m,j,len,pow[21],f[60010][102],cnt[21],a[20],g[60010]; int main() { cin>>s; len=s.size(); scanf("%d",&m); for (int i=0;i<len;i++) a[s[i]-48]++; cnt[0]=1; for (int i=0;i<=9;i++) cnt[i+1]=cnt[i]*(a[i]+1); for (int i=1;i<cnt[10];i++) for (int j=0;j<=9;j++) if (i%cnt[j+1]/cnt[j]) //是否选了j g[i]=g[i-cnt[j]]+1; //i这个状态选了多少个数字了 pow[0]=1; for (int i=1;i<=len;i++) pow[i]=pow[i-1]*10%m; f[0][0]=1; for (int i=1;i<cnt[10];i++) { if (cnt[10]-1==i) j=1; else j=0; for (;j<=9;j++) if (i%cnt[j+1]/cnt[j]) //状态i有选j for (int k=0;k<m;k++) //枚举余数 f[i][k]=(f[i][k]+f[i-cnt[j]][((k-pow[g[i]-1]*j)%m+m)%m])%p; //从少选一个j转移 } printf("
前言 项目过程中,经常会遇到 JS 数组合并的情况,时常为这个纠结。这里整理一下。
简单而实用的for 最容易想到的莫过于 for 了。
会变更原数组,当然也可以写成生成新数组的形式。
经读者提点,数组不建议使用for…in,具体可参考MDN for…in
let arr = [1, 2] let arr2 = [3, 4] for (let i = 0; i < len(arr2); i++) { arr.push(arr2[i]) } console.log(arr) // [1, 2, 3, 4] arr.concat(arr2) 会生成新的数组。
let arr = [1, 2] let arr2 = [3, 4] arr = arr.concat(arr2) console.log(arr) // [1, 2, 3, 4] arr.push.apply(arr, arr2) 第一种 for 循环就是使用的 push 来实现的。
因为 push 是可以接收多个参数的,所以我们可以使用 apply 来实现。
多对多关联模式只与前几种关联模式有少许区别,本文着重的利用Many2Many关系学习并实验关联模式的相关操作,包括建立关系,更换关系等等。
目录 gorm中多对多关系准备工作建立Many2Many关系表 关联模式添加关联查找关联替换关联删除关联清空关联关联计数带 Select 的删除 gorm中多对多关系 准备工作 建立数据库连接
import ( "fmt" _ "github.com/go-sql-driver/mysql" "gorm.io/driver/mysql" "gorm.io/gorm" "log" ) var db *gorm.DB func OpenDB() { dsn := "root:adss123@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True&loc=Local" res, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) db = res if err != nil { log.Fatal(err) } fmt.Printf("成功:%v\n", db) } 建立Many2Many关系表 Many to Many 会在两个 model 中添加一张连接表。
例如,您的应用包含了 user 和 language,且一个 user 可以说多种
language,多个 user 也可以说一种 language。
// User 拥有并属于多种 language,`user_languages` 是连接表 type User struct { gorm.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" /> <title>Custom Range Slider</title> </head> <body> <h2>Custom Range Slider</h2> <div class="range-container"> <!-- type="range" 滑块或拨号控件 --> <input type="range" id="range" min="0" max="100"> <label for="range">50</label> </div> <script src="script.js"></script> </body> </html> @import url('https://fonts.googleapis.com/css?family=Lato&display=swap'); * { box-sizing: border-box; } body { background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); font-family: 'Lato', sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; } h2 { position: absolute; top: 10px; } .
typora打开报错解决方案 一、更新到老版本二、关闭自动更新三、其他常用操作3.1 Typora拼写检查如何关闭3.2 Typora如何实现页内跳转3.2.1 HTML链接标签3.2.2 修改内容3.2.3 验证效果 一、更新到老版本 今天一大早打开Typora准备接着记笔记,结果发现打开有报错,由于Typora现在收费了,所以可能是我这个版本还是过高,或者是没有关闭自动更新导致的,解决办法就是更新到老的版本。
报错如下: The beta version of typora is expired, please download and install a newer version. 老版本Typora
链接:https://pan.baidu.com/s/1aSVnc2GHe6w_kzP_b8PbXg
提取码:mp69
二、关闭自动更新 检查下自动更新,这里应该默认就是没有勾选的。
三、其他常用操作 3.1 Typora拼写检查如何关闭 在日常书写过程中,往往会出现一堆报错的情况,这是因为Typora默认开始了拼写检查,只需要关闭就不会有任何提示了。
1.鼠标移动到页面的右下角
2.点击词数统计左侧的"A"图标
3.勾选上不进行拼写检查
3.2 Typora如何实现页内跳转 使用场景:
当我们利用Typora时,经常会遇到需要跳转的情况,比如:
通过汇总表格,直接跳转到内容详细。 如何实现
由于Typora是支持HTML语法的,所以我们可以利用HTML的链接标签(a标签)来实现跳转。
3.2.1 HTML链接标签 格式:
<a href="" target=''></a> href:
值为URL时,用户点击会跳转到该URL页面
值为其他标签的ID时,点击即可跳转到对应的标签位置。
target:
值为self时,表示在当前页面完成跳转的,默认就是self值为_blank时,表示在新建页面跳转。 3.2.2 修改内容 下列为符合markdown语法的表格
| 语法 | 作用 | | :---------------: | -------------------------------------------------------- | | 构造函数.call() | 调用函数,改变函数内的this指向,多用于继承 | | 构造函数.
MYSQL 空间坐标 MYSQL空间数据形式MKTMKBGEOJSON MYSQL空间数据类型GEOMETRYPOINTLINESTRINGPOLYGONMULTIPOINTMULTILINESTRINGMULTIPOLYGONGEOMETRYCOLLECTION MYSQL空间坐标函数 MYSQL空间数据形式 MKT 已知文本(WKT)格式。用已知文本(WKT)表示几何值是为用ASCII格式交换几何数据而设计的。OpenGIS规范提供了一个Backus Naur语法,它指定了写入WKT值的正式生成规则。
MKB 已知二进制(WKB)格式。用已知二进制(WKB)表示的几何值,用于交换二进制流格式的几何数据,用包含几何WKB信息的BLOB值表示。该格式由OpenGIS规范定义。ISO SQL/MM第3部分:空间标准中也对其进行了定义。WKB使用1字节无符号整数、4字节无符号整数和8字节双精度数字(IEEE 754格式)。一个字节有八位
GEOJSON GeoJSON 是用于描述地理空间信息的数据格式。GeoJSON 不是一种新的格式,其语法规范是符合 JSON 格式的,只不过对其名称进行了规范,专门用于表示地理信息。
GeoJSON 的最外层是一个单独的对象(object)。这个对象可表示:
几何体(Geometry)。特征(Feature)。特征集合(FeatureCollection)。 最外层的 GeoJSON 里可能包含有很多子对象,每一个 GeoJSON 对象都有一个 type 属性,表示对象的类型,type 的值必须是下面之一。
Point:点。MultiPoint:多点。LineString:线。MultiLineString:多线。Polygon:面。MultiPolygon:多面。GeometryCollection:几何体集合。Feature:特征。FeatureCollection:特征集合。 每一个对象都有一个成员变量 coordinates。如果 type 的值为 Point、MultiPoint、LineString、MultiLineString、Polygon、MultiPolygon 之一,则该对象必须有变量 coordinates。
如果 type 的值为 GeometryCollection(几何体集合),那么该对象必须有变量 geometries,其值是一个数组,数组的每一项都是一个 GeoJSON 的几何对象。
MYSQL空间数据类型 MySQL的空间数据类型(Spatial Data Type)对应于OpenGIS类,包括单值类型:GEOMETRY、POINT、LINESTRING、POLYGON以及集合类型:MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION 。
GEOMETRY Geometry是所有空间集合类型的基类,其他类型如POINT、LINESTRING、POLYGON都是Geometry的子类。
POINT Point,顾名思义就是点,有一个坐标值。例如POINT(121.213342 31.234532),POINT(30 10),坐标值支持DECIMAL类型,经度(longitude)在前,维度(latitude)在后,用空格分隔。
LINESTRING LineString,线,由一系列点连接而成。如果线从头至尾没有交叉,那就是简单的(simple);如果起点和终点重叠,那就是封闭的(closed)。例如LINESTRING(30 10,10 30,40 40),点与点之间用逗号分隔,一个点中的经纬度用空格分隔,与POINT格式一致。
POLYGON Polygon,多边形。可以是一个实心平面形,即没有内部边界,也可以有空洞,类似纽扣。最简单的就是只有一个外边界的情况,例如POLYGON((0 0,10 0,10 10, 0 10))。
MULTIPOINT MultiPoint是由Point(点)元素组成的几何集合。这些点没有以任何方式连接或排序。MultiPoint的用法:在世界地图上,MultiPoint可以代表一连串的小岛。 MultiPoint属性:MultiPoint是零维几何。如果MultiPoint的两个Point值都不相等(坐标值相同),则它很简单。 MultiPoint的边界是空集。
代码编写 pom文件 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-spring-boot</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> yml文件 server: port: 8080 spring: application: name: springboot-rocketmq rocketmq: name-server: 127.0.0.1:9876 producer: group: producerGroup consumer package com.example.demo.example3.service; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class ConsumerService { private RocketMQTemplate rocketMQTemplate; @Autowired public void setRocketMQTemplate(RocketMQTemplate rocketMQTemplate) { this.rocketMQTemplate = rocketMQTemplate; } public void createOrder(String name){ System.out.println("正在生成订单。。。"); rocketMQTemplate.convertAndSend("topic_rocket",name); } } provider package com.
本文讨论 Oracle Java 数据库连接 (JDBC) 驱动程序版本、数据库版本和 Java 开发工具包 (JDK) 版本的兼容性。
下表描述了 JDBC 和 Oracle 数据库互操作性矩阵或认证矩阵:
JDBC 驱动程序版本数据库 19.x数据库 18.3数据库 12.2 和 12.1数据库 11.2.0.4JDBC 19.x是的是的是的是的JDBC 18.3是的是的是的是的JDBC 12.2 和 12.1是的是的是的是的JDBC 11.2.0.4是的是的是的是的 下表描述了特定于发行版的 JDBC JAR 文件以及各种 Oracle 数据库版本支持的 JDK 版本:
甲骨文数据库版本具有受支持的 JDK 版本的特定于发行版的 JDBC JAR 文件19.xojdbc10.jar与 JDK 10、 JDK 11 ojdbc8.jar与 JDK 8、 JDK 9、 JDK 11
18.3ojdbc8.jar与 JDK 8、 JDK 9、 JDK 10、 JDK 1112.2 或 12cR2ojdbc8.jar与 JDK 812.1 或 12cR1ojdbc7.jar与 JDK 7、 JDK 8 ojdbc6.