在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交。简单来说一个场景:在你使用git add .的时候,遇到了把你不想提交的文件也添加到了缓存中去的情况,比如项目的本地配置信息,如果你上传到Git中去其他人pull下来的时候就会和他本地的配置有冲突,所以这样的个性化配置文件我们一般不把它推送到git服务器中,但是又为了偷懒每次添加缓存的时候都想用git add .而不是手动一个一个文件添加,该怎么办呢?很简单,git为我们提供了一个.gitignore文件只要在这个文件中申明那些文件你不希望添加到git中去,这样当你使用git add .的时候这些文件就会被自动忽略掉。
有三种方法可以实现忽略Git中不想提交的文件:
1)在Git项目中定义.gitignore文件
对于经常使用Git的朋友来说,.gitignore配置一定不会陌生。这种方式通过在项目的某个文件夹下定义.gitignore文件,在该文件中定义相应的忽略规则,来管理当前文件夹下的文件的Git提交行为。.gitignore 文件是可以提交到公有仓库中,这就为该项目下的所有开发者都共享一套定义好的忽略规则。在.gitingore 文件中,遵循相应的语法,在每一行指定一个忽略规则。如:
1
2
3
*.log
*.temp
/vendor
2)在Git项目的设置中指定排除文件
这种方式只是临时指定该项目的行为,需要编辑当前项目下的 .git/info/exclude文件,然后将需要忽略提交的文件写入其中。需要注意的是,这种方式指定的忽略文件的根目录是项目根目录。
3)定义Git全局的 .gitignore 文件
除了可以在项目中定义 .gitignore 文件外,还可以设置全局的git .gitignore文件来管理所有Git项目的行为。这种方式在不同的项目开发者之间是不共享的,是属于项目之上Git应用级别的行为。这种方式也需要创建相应的 .gitignore 文件,可以放在任意位置。然后在使用以下命令配置Git:
1
# git config --global core.excludesfile ~/.gitignore
首先要强调一点,这个文件的完整文件名就是".gitignore",注意最前面有个“.”。一般来说每个Git项目中都需要一个“.gitignore”文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。实际项目中,很多文件都是不需要版本管理的,比如Python的.pyc文件和一些包含密码的配置文件等等。这个文件的内容是一些规则,Git会根据这些规则来判断是否将文件添加到版本控制中。
Git忽略文件的原则
- 忽略操作系统自动生成的文件,比如缩略图等;
- 忽略编译生成的中间文件、可执行文件等,也就是如果一个文件是通过另一个文件自动生成的,那自动生成的文件就没必要放进版本库,比如Java编译产生的.class文件;
- 忽略你自己的带有敏感信息的配置文件,比如存放口令的配置文件。
.gitignore文件的使用方法
首先,在你的工作区新建一个名称为.gitignore的文件。
然后,把要忽略的文件名填进去,Git就会自动忽略这些文件。
不需要从头写.gitignore文件,GitHub已经为我们准备了各种配置文件,只需要组合一下就可以使用了。
有时对于git项目下的某些文件,我们不需要纳入版本控制,比如日志文件或者IDE的配置文件,此时可以在项目的根目录下建立一个隐藏文件 .gitignore(linux下以.开头的文件都是隐藏文件),然后在.gitignore中写入需要忽略的文件。
1
2
3
4
[root@kevin ~]# cat .gitignore
*.xml
*.log
*.apk
.gitignore注释用'#', *表示匹配0个或多个任意字符,所以上面的模式就是要忽略所有的xml文件,log文件和apk文件。
.gitignore配置文件用于配置不需要加入版本管理的文件,配置好该文件可以为版本管理带来很大的便利。
.gitignore忽略规则的优先级
在 .gitingore 文件中,每一行指定一个忽略规则,Git检查忽略规则的时候有多个来源,它的优先级如下(由高到低):
目录
1、原理
1.1 为什么要分库分表
1.2 分库分表
1.3 不停机分库分表数据迁移
2、 配置
2.1 逻辑表
2.2 分库分表数据节点 - actual-data-nodes
2.3 inline分片策略
2.4 分布式主键配置
3、实战
3.1 需求
3.2 表结构
3.3 配置文件
3.4 测试类
3.5 验证
1、原理 1.1 为什么要分库分表 分库分表目的:解决高并发,和数据量大的问题。
1、高并发情况下,会造成IO读写频繁,自然就会造成读写缓慢,甚至是宕机。一般单库不要超过2k并发,NB的机器除外。
2、数据量大的问题。主要由于底层索引实现导致,MySQL的索引实现为B+TREE,数据量其他,会导致索引树十分庞大,造成查询缓慢。第二,innodb的最大存储限制64TB。
要解决上述问题。最常见做法,就是分库分表。
分库分表的目的,是将一个表拆成N个表,就是让每个表的数据量控制在一定范围内,保证SQL的性能。 一个表数据建议不要超过500W。
1.2 分库分表 水平拆分:同一个表的数据拆到不同的库不同的表中。可以根据时间、地区或某个业务键维度,也可以通过hash进行拆分,最后通过路由访问到具体的数据。拆分后的每个表结构保持一致 垂直拆分:就是把一个有很多字段的表给拆分成多个表,或者是多个库上去。每个库表的结构都不一样,每个库表都包含部分字段。一般来说,可以根据业务维度进行拆分,如订单表可以拆分为订单、订单支持、订单地址、订单商品、订单扩展等表;也可以,根据数据冷热程度拆分,20%的热点字段拆到一个表,80%的冷字段拆到另外一个表。
1.3 不停机分库分表数据迁移 一般数据库的拆分也是有一个过程的,一开始是单表,后面慢慢拆成多表。那么我们就看下如何平滑的从MySQL单表过度到MySQL的分库分表架构
(1) 利用MySQL+Canal做增量数据同步,利用分库分表中间件,将数据路由到对应的新表中
(2) 利用分库分表中间件,全量数据导入到对应的新表中
(3) 通过单表数据和分库分表数据两两比较,更新不匹配的数据到新表中
(4) 数据稳定后,将单表的配置切换到分库分表配置上
2、 配置 2.1 逻辑表 逻辑表是指:水平拆分的数据库或者数据表的相同路基和数据结构表的总称。比如用户数据根据订单id%2拆分为2个表,分别是:t_order0和t_order1。他们的逻辑表名是:t_order。在shardingjdbc中的定义方式如下:
spring: shardingsphere: sharding: tables: # t_order逻辑表名 t_order: 2.2 分库分表数据节点 - actual-data-nodes tables: # t_order 逻辑表名 t_order: # 数据节点:多数据源$->{0.
题目如上
题目分析:输入三个数,输出第二个数,进行赋值的时候是按顺序对变量进行赋值的,所以只要输出我们第二次进行赋值的数即可。
代码:
import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc = new Scanner(System.in); int a,b,c; a = sc.nextInt(); b = sc.nextInt(); c = sc.nextInt(); System.out.println(b); } } 照例用scanner进行输入,没啥好说的,很简单。
这里输入的是整数,没有长度要求等,直接设为int型即可。
这里使用python的话,用时和内存都可以有效缩减,代码很简单,我放在下面,有兴趣的人可以进行学习。
a,b,c= (input().split()) print(b) input相当于scanner进行输入,split()用于分割,此处分割标记为空格。
将三个数分割开后赋值给三个变量,输出第二个变量的值。
以下内容来源于哔哩哔哩UP主zst_2001的视频学习笔记,仅供复习所用
数据结构 1.查找1.1 平均查找长度1.2 顺序查找1.3 折半查找 2.哈希表3.小顶堆和大顶堆4.排序4.1 直接插入排序4.2 希尔排序4.3 简单选择排序4.4 堆排序4.5 冒泡排序4.6 快速排序4.7 归并排序 5.杂题 1.查找 1.1 平均查找长度 1.2 顺序查找 1.3 折半查找 2.哈希表 3.小顶堆和大顶堆 4.排序 4.1 直接插入排序 4.2 希尔排序 4.3 简单选择排序 4.4 堆排序 4.5 冒泡排序 4.6 快速排序 4.7 归并排序 5.杂题
org.springframework.messaging.MessagingException: No route info of this topic, course-sms-topic
See http://rocketmq.apache.org/docs/faq/ for further details.; nested exception is org.apache.rocketmq.client.exception.MQClientException: No route info of this topic, course-sms-topic
See http://rocketmq.apache.org/docs/faq/ for further details.
at org.apache.rocketmq.spring.core.RocketMQTemplate.sendOneWay(RocketMQTemplate.java:457)
at org.apache.rocketmq.spring.core.RocketMQTemplate.sendOneWay(RocketMQTemplate.java:469)
at cn.miss.ymcc.service.impl.CourseServiceImpl.SendSMSMessage(CourseServiceImpl.java:230)
at cn.miss.ymcc.service.impl.CourseServiceImpl.onLineCourse(CourseServiceImpl.java:209)
at cn.miss.ymcc.service.impl.CourseServiceImpl$$FastClassBySpringCGLIB$$585dd730.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:685)
at cn.miss.ymcc.service.impl.CourseServiceImpl$$EnhancerBySpringCGLIB$$3df20bb0.onLineCourse(<generated>)
at cn.miss.ymcc.web.controller.CourseController.onLineCourse(CourseController.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.
问题描述 在Ubuntu 20.04上运行代码lanx@lanx:~$ rosrun tf view_frames查看tf树的时候报错如下:
Listening to /tf for 5.0 seconds Done Listening b'dot - graphviz version 2.43.0 (0)\n' Traceback (most recent call last): File "/opt/ros/noetic/lib/tf/view_frames", line 119, in <module> generate(dot_graph) File "/opt/ros/noetic/lib/tf/view_frames", line 89, in generate m = r.search(vstr) TypeError: cannot use a string pattern on a bytes-like object 解决方案 在命令框中输入:
sudo gedit /opt/ros/noetic/lib/tf/view_frames 然后搜索 m = r.search(vstr)(89行),在这行前面添加 vstr=str(vstr)即可。
原来为:
vstr=str(vstr) 修改后:
vstr=str(vstr) m = r.search(vstr)
[xctf] 江苏工匠杯easyphp 考点
PHP弱类型
一、题目 <?php highlight_file(__FILE__); $key1 = 0; $key2 = 0; $a = $_GET['a']; $b = $_GET['b']; if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3){ if(isset($b) && '8b184b' === substr(md5($b),-6,6)){ $key1 = 1; }else{ die("Emmm...再想想"); } }else{ die("Emmm..."); } $c=(array)json_decode(@$_GET['c']); if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022){ if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0])){ $d = array_search("DGGJ", $c["n"]); $d === false?die("no..."):NULL; foreach($c["n"] as $key=>$val){ $val==="DGGJ"?die("no......"):NULL; } $key2 = 1; }else{ die("
第一次做要明白写这种测试题的代码必须精简才可以。
注意右上角的限制要求 如果超过限制 就会wa
接下来写代码,第一题很入门。
题目如上
最关键的是不要忘记导包,以及class的名字需取Main才可以进行测试,以及此处需要定义为long型,防止越界。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input =new Scanner(System.in); long a,b; a=input.nextLong(); b=input.nextLong(); System.out.println(a+b); } } 代码详解:
1、用scanner模块进行输入,输入需相加的两个数,此处定义a,b两变量,将输入的数字赋值给a,b方便后续相加。
2、直接输出答案即可。
写在前面:
本系列文章仅作为对《Python工匠》一书的知识点总结笔记。内容会比较简练,仅作为个人复习使用,大家喜欢的话就去买来原作看看吧,还是很有意思的。
数值与字符串 2.1基础知识 2.1.1数值基础 python中共有三种数值类型:整型(int)、浮点型(float)、复数(complex)
对于常用的两种类型:int与float,可通过内置方法进行转换:
float_num=12.3 int_num=10 x=float("inf")#无穷大 y=float("-inf")#无穷小 print(int(float_num))#12,小数部分被舍去 print(float(int_num))#10.0 对于较长的数值字面量,可以通过插入 “ _ ” 的方式使得数值变得清晰易读。
num=1_000_000 print(num+100)#1000100 Python的数值类型很方便,不必考虑溢出的问题,
如无符号64位最大值(2**64-1)*10也不必担心数值溢出造成的错误。 浮点精度问题:
print(0.1+0.2)#0.30000000000000004 造成浮点精度问题的原因是:
计算机二进制无法绝对精准地表示小数,所以使用一个固定的精度近似表示小数。
解决方案:
使用内置模块decimal
from decimal import Decimal print(Decimal('0.1')+Decimal('0.2'))#注意必须使用字符串作为数值定义 2.1.2 布尔值作为数字 True=1 False=0
2.1.3 字符串常用操作 字符串属于序列,则包括遍历、切片等操作
反转操作
s="Hello World" s[::-1]#切片反转,[起点:终点+1:步长],步长为-1表示反转 "".join(reversed(s))#reversed返回可迭代对象,可理解为字符列表,使用空白字符串加join方法进行拼接 字符串格式化微语言(需扩展)
#str.format格式 s="Hello {},你好 {}".format("World","世界") s2="Hello {0},你好 {0} - {1}".format("World","世界")#可通过索引重复使用 #f-string格式 name="xxx" s3=f"你好,我叫{name}" 字符串拼接
s="a" s+="b" print(s)#ab l=["ab","b","c"] s2="-".join(l)#join前的字符串作为被拼接序列的分隔符 print(s2)#ab-b-c s3="xyz" s3="+".join(s3) print(s3)#x+y+z,字符串可看为字符列表(序列) 字符串好用方法
目录
实验要求
实验代码
字符转ASCII码的实验
ASCII码转字符的实验
实验连线
字符转ASCII码的实验
ASCII码转字符的实验
实验现象
字符转ASCII码的实验
ASCII码转字符的实验
实验要求 实验代码 字符转ASCII码的实验 IOPORT EQU 0D100H-0280H LS273 EQU IOPORT+2A8H code segment assume cs:code start: MOV AH,02 ;输出显示字符指令 MOV DL,0DH ;将0dh送到DL INT 21H ; 执行中断程序,显示ASCII码为0dh的回车符 MOV AH,1 ;等待键盘输入 INT 21H CMP AL,27 ;判断是否为ESC键,若是,则zf=1 JE EXIT ;若是ESC键,则退出 MOV DX,2A8H ;将2A8H的数值送到DX OUT DX,AL ;输出ASCII码 JMP START EXIT: mov AH,4CH ;输出??? INT 21H ; 退出程序 CODE ENDS END START ASCII码转字符的实验 LS244 EQU 2A0H code segment assume cs:code start: MOV DX,LS244 ;从2A0H输入一数据 IN AL,DX MOV DL,AL ;将所读数据保存在DL中 MOV AH,02 ;显示DL字符对应的ASCII码 INT 21H MOV DL,0DH ;回车符 INT 21H MOV AH,06 MOV DL,0FFH INT 21H JNZ EXIT JE START ;若无,则转start EXIT: MOV AH,4CH INT 21H CODE ENDS END START 实验连线 字符转ASCII码的实验 ASCII码转字符的实验 实验现象 字符转ASCII码的实验 (键盘输入G)
多层感知器用实际例子和Python代码进行解释情绪分析 多层感知器是一种学习线性和非线性数据之间关系的神经网络。
这是专门介绍深度学习系列的第一篇文章,深度学习是一组机器学习方法,其根源可以追溯到20世纪40年代。在过去的几十年里,深度学习因其在图像分类、语音识别和机器翻译等领域的突破性应用而受到关注。
如果你想看到不同的深度学习算法,并通过现实生活中的例子和一些Python代码来解释,请继续关注。
这一系列的文章专注于深度学习算法,在过去的几年里,深度学习算法得到了广泛的关注,因为它的许多应用在我们的日常生活中占据了中心位置。从自动驾驶汽车到语音助手、人脸识别或将语音转录为文本的能力。
这些应用只是冰山一角。自20世纪40年代初以来,已经铺设了一条漫长的研究和渐进式应用的道路。我们今天看到的改进和广泛的应用是硬件和数据可用性赶上这些复杂方法的计算需求的高潮。
为什么深度学习改变了游戏规则
在传统的机器学习中,任何建立模型的人都必须是他们所从事的问题领域的专家,或者与专家合作。如果没有这种专家知识,设计和设计功能就会成为一个越来越困难的挑战[1]。机器学习模型的质量取决于数据集的质量,但也取决于特征对数据中的模式的编码程度。
深度学习算法使用人工神经网络作为其主要结构。它们与其他算法的不同之处在于,它们在特征设计和工程阶段不需要专家输入。神经网络可以学习数据的特征。
深度学习算法接收数据集并学习其模式,它们学习如何用自己提取的特征来表示数据。然后,它们将数据集的不同表征结合起来,每一个表征都能识别一个特定的模式或特征,成为数据集的一个更抽象、更高级的表征[1]。这种放手的方法,在特征设计和提取方面没有太多的人为干预,使算法能够更快地适应手头的数据[2]。
神经网络受到大脑结构的启发,但不一定是大脑结构的精确模型。关于大脑和它的工作原理,我们还有很多不了解的地方,但由于它具有开发智能的能力,它一直在许多科学领域充当着灵感的来源。尽管有一些神经网络是以了解大脑如何工作为唯一目的而创建的,但我们今天知道的深度学习并不是为了复制大脑的工作方式。相反,深度学习的重点是使系统能够学习多层次的模式组成[1]。
而且,就像任何科学进步一样,深度学习一开始并没有你在最近的文献中看到的复杂结构和广泛的应用。
这一切都始于一个基本结构,一个类似于大脑神经元的结构。
这一切都始于一个神经元
20世纪40年代初,神经生理学家沃伦-麦库洛赫(Warren McCulloch)与逻辑学家沃尔特-皮茨(Walter Pitts)合作,建立了一个大脑工作的模型。这是一个简单的线性模型,在给定一组输入和权重的情况下,产生一个正或负的输出。
麦库洛赫和皮茨的神经元模型
这种计算模型被有意称为神经元,因为它试图模仿大脑的核心构件如何工作。就像大脑神经元接收电信号一样,麦库洛赫和皮茨的神经元接收输入,如果这些信号足够强大,就把它们传递给其他神经元。
神经元和它的不同组成部分
神经元的第一个应用复制了一个逻辑门,其中你有一个或两个二进制输入,以及一个布尔函数,只有在给定正确的输入和权重时才会被激活。
AND和OR逻辑门的例子
然而,这个模型有一个问题。它不能像大脑那样学习。获得所需输出的唯一方法是在模型中作为催化剂的权重事先被设定。
神经系统是一个神经元网,每个神经元都有一个体细胞和一个轴突[......]在任何瞬间,神经元都有一些阈值,激励必须超过这个阈值才能启动冲动[3]。
只是在十年之后,弗兰克-罗森布拉特才扩展了这个模型,并创造了一个可以学习权重以产生输出的算法。
在McCulloch和Pitt的神经元基础上,Rosenblatt开发了Perceptron。
感知器 尽管今天Perceptron被广泛认为是一种算法,但它最初是作为一种图像识别机器。它的名字来源于执行类似人类的感知功能,看到并识别图像。
特别是,人们的兴趣集中在这样一个想法上:一台机器能够将直接来自光、声音、温度等物理环境的输入概念化--我们都熟悉的 "现象世界"--而不是需要人类代理人的干预来消化和编码必要的信息。
罗森布拉特的感知器机器依赖于一个基本的计算单位--神经元。就像以前的模型一样,每个神经元都有一个细胞,接收一系列的输入和权重对。
罗森布拉特模型的主要区别是,输入被合并为一个加权和,如果加权和超过预定的阈值,神经元就会启动并产生一个输出。
Perceptrons神经元模型(左)和阈值逻辑(右) 阈值T代表激活函数。如果输入的加权和大于零,神经元输出值为1,否则输出值为零。
二进制分类的感知器
有了这个由激活函数控制的离散输出,感知器可以被用作二元分类模型,定义一个线性决策边界。它找到分离超平面,使错误分类的点和决策边界之间的距离最小[6]。
感受器的损失函数
为了最小化这个距离,Perceptron使用随机梯度下降作为优化函数。
如果数据是线性可分离的,可以保证随机梯度下降法在有限的步骤内收敛。
Perceptron需要的最后一块是激活函数,这个函数决定了神经元是否会启动。
最初的Perceptron模型使用的是sigmoid函数,光看它的形状,就很有意义了
sigmoid函数将任何实际输入映射为0或1的值,并编码为非线性函数。
神经元可以接收负数作为输入,它仍然能够产生一个0或1的输出。
Sigmoid函数
但是,如果你看一下过去十年的深度学习论文和算法,你会发现它们中的大多数都使用整流线性单元(ReLU)作为神经元的激活函数。
ReLU函数
ReLU被更多采用的原因是,它可以使用随机梯度下降法进行更好的优化,计算效率更高,而且是尺度不变的,也就是说,它的特性不受输入尺度的影响。
把它放在一起
神经元接收输入并随机选择一组初始权重。这些权重被组合成加权和,然后由激活函数ReLU决定输出的值。
Perceptrons神经元模型(左)和激活函数(右)
但是你可能想知道,Perceptron实际上没有学习权重吗?
它是的! Perceptron使用随机梯度下降法来寻找,或者你可以说是学习,使错误分类点和决策边界之间的距离最小的权重集。一旦随机梯度下降收敛,数据集就会被一个线性超平面分隔成两个区域。
尽管有人说Perceptron可以代表任何电路和逻辑,但最大的批评是它不能代表XOR门,即排他性OR,其中门只在输入不同时返回1。
这一点几乎在十年后由Minsky和Papert在1969年证明了[5],并强调了只有一个神经元的Perceptron不能应用于非线性数据的事实。
多层感知器
多层感知器是为了解决这一限制而开发的。它是一种神经网络,输入和输出之间的映射是非线性的。
多层感知器有输入和输出层,以及一个或多个由许多神经元堆叠在一起的隐藏层。而在感知器中,神经元必须有一个施加阈值的激活函数,如ReLU或sigmoid,多层感知器中的神经元可以使用任何任意的激活函数。
多层感知器
多层感知器属于前馈算法的范畴,因为输入与初始权重的加权和相结合,并受到激活函数的影响,就像在感知器中一样。但不同的是,每个线性组合都被传播到下一层。
每一层都把它们的计算结果反馈给下一层,即它们对数据的内部表示。这一直通过隐藏层到输出层。
但它有更多的内容。 如果算法只计算每个神经元的加权和,将结果传播到输出层,并停在那里,它就无法学习使成本函数最小化的权重。如果该算法只计算一次迭代,就不会有实际的学习。
这就是Backpropagation[7]发挥作用的地方。
反向传播
反向传播是一种学习机制,它允许多层感知器反复调整网络中的权重,目的是使成本函数最小化。
逆向传播要正常工作,有一个硬性要求。在神经元中结合输入和权重的函数,例如加权和,以及阈值函数,例如ReLU,必须是可微的。这些函数必须有一个有界的导数,因为梯度下降通常是多层感知器中使用的优化函数。
多层感知器,突出显示了前馈和反向传播的步骤
在每个迭代中,在加权和通过所有层转发后,计算所有输入和输出对的平均平方误差的梯度。然后,为了把它传播回去,第一个隐藏层的权重用梯度的值来更新。这就是权重如何被传播回神经网络的起点!这就是梯度下降法。
什么是io io接口,又称为输入输出接口,是信息处理系统与外部世界之间的通信,输入时系统接受的信号或者数据,输出就是从其发送的信号或数据。
input:通过终端向程序中输入数据;
output:程序的结果通过终端(显示屏等)输出;
io的种类 文件io->系统调用 系统调用就是操作系统提给应用程序(编程人员)使用的接口,可以理解其为一种可供应用程序调用的 '特殊函数',应用程序可以发出系统调用来获操作服务。从要从用户空间到内核空间就发生一次系统调用。
系统调用的特点:1.系统调用的接口不同意,依赖于内核,不保证移植性
2.系统调用没有缓冲区,效率比较低。
标准io->库函数 库函数(AANSI C)是由文件io封装而来的,通过缓冲区机制减少系统调用,
库函数=系统调用+缓冲区;库函数具有缓冲区,所以效率比系统调用更高。
缓冲区 缓冲区:就是暂存输入(输出)的数据,等待缓冲区刷新,在一同输入(输出)到内核空间。
缓冲区的种类和大小: 全缓存:和文件相关的缓冲区就是全缓存(4096字节)4K;例如;fd;
行缓存:和终端相关的缓冲区就是行缓存 (1024字节)1K;例如:stdin 、stdout
不缓存:标准出错没有缓冲区 0 ;例如:stderr(标准出错)
缓冲区的刷新时机: 行缓存的刷新时机:
1.遇到换行符(\n)
2.输入输出切换时
3.程序运行结束时
4.关闭文件
5.缓存区存储满时
6.使用fflush主动刷新缓冲区
全缓存的刷新时机:
1.输入输出切换时
2.程序运行结束时
3.关闭文件
4.缓存区存储满时
5.使用fflush主动刷新缓冲区
标准io的API函数 在介绍标准io的API函数之前,先说一下FILE类型,FILE类型本质是一个结构体,这个结构体中记录所i有关于文件的信息,以后对文件的操作通过FILE*来完成。
在打开文件的时候,会返回一个FILE*的指针(文明)
FILE *fp 是声明,声明fp是指针,用来指向FILE类型的对象。
fopen ->使用标准io打开文件,
#include <stdio.h> FILE *fopen(const char *pathname, const char *mode); 功能:使用标准IO打开文件 参数: @pathname: 路径/文件名 "./hello.txt" @mode:打开文件的方式 "r" "r+" r:以只读的方式打开文件,将文件中的光标定位在文件的开头 r+:以读写的方式打开文件,将文件中的光标定位在文件的开头 w:以只写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空,将光标定位在开头 w+:以读写的方式打开文件,如果文件不存在就创建文件,如果文件存在就清空,将光标定位在开头 a:以追加(结尾写)的方式打开文件,如果文件不存在就创建文件,将光标定位在文件的结尾 a+:以读和追加(结尾写)的方式打开文件,如果文件不存在就创建文件,如果读从开头读,写在文件的结尾写 返回值:成功返回文件指针,失败返回NULL,置位错误码 fopen实例
如果遇到以下弹窗问题无法下载安装
1.首先查看电脑内是否缺失net framework 3.5组件
控制面板内——程序——启用或关闭Windows程序
将.NET Framework 3.5(包括.net2.0和3.0)展开
勾选全部文件
2.打开 Windows Update
点击此电脑——管理——服务——找到Windows Update
然后点击属性,将其设置为自动
完成以上操作之后,再进行正常的下载安装
python 环境配置 需要安装pywinauto, 可以使用pip,具体过程,这里就不累述。
当安装完成,执行下
from pywinauto.application import Application 不报错,就说明安装成功
pywinauto 与application建立连接 官网这里显示了好几种建立
连接
这里采用如下
app = Application('uia').start(r'C:\WINDOWS\system32\mstsc.exe') uia是一个backend参数,与这个windows dialog的底层实现有关。一般都是uia
在这个建立的过程中,app会解析出这个dialog的参数
pywinauto 定位元素,操作元素 如果操作dialog上的元素呢? 例如点击,输入文本等?
点击 获取到元素,调用click()方法就可以
可点击的元素,一般是Button类型的
输入文本 获取到元素,调用 set_edit_text 就可以。
可输入文本的元素,一般是type是EditL类型的。
获取元素 有一种我认为比较简单的写法,用于定位元素。
app[][]...
其中每个[]里面是dialog的名字,就是我们ui上看到的,也是我们在spy上看到的class name.
在这里,第一个dialog的名字是Remote Desktop Connection
如果是中文的话,填相应的中文,可以使用spy, copy其caption
以防止文字拼写错误。spy
有两种辅助方式,可以帮助我们定位到 准确的元素。一个是spy工具,
一个是pywinauto自带的print_control_identifiers
spy 辅助 如果电脑没有,这个需要安装。
操作步骤:
打开spyctrl +fdrag
如上图所示,有的定位dialog是没有名称的。有的是有名称的。
print_control_identifiers 这个可以打印出dialog的具体信息,比如,我们想知道 想往computer里面输入机器号,
app[‘Remote Desktop Connection’][‘???’]
这里的???指的是 我们想定位的computer那里。
如果正确定位了,接下来我们只需要 app[‘Remote Desktop Connection’][‘???’].set_edit_text(“”) 就可以了
下面是remote desktop connection 打印出的信息
和平台总线实现的驱动不同的地方在于,设备树将平台设备,也就是 platform_device 进行了完全的抽象,对于不同的设备并不需要去写一个个平台设备。而只是需要修改设备树就行了。设备树是一个用节点描述系统中设备的树状结构。
一,设备树相关定义
1,设备树文件定义
• DTS :dts 文件是对 Device Tree 的描述,放置在内核的/arch/arm64/boot/dts 目录,描述了一个板子的硬件
资源。以前写在 mach-xxx 文件中的内容被转成了 dts 文件。
• DTC :编译工具,存放在目录 scripts/dtc 位置,它可以将.dts 文件编译成.dtb 文件。
• DTB :DTC 编译*.dts 生成的二进制文件(.dtb),bootloader 在引导内核时,会预先读取.dtb 到内存,进而由内核解析。
• DTSI :由于同一系列 SOC 很多相同的地方,为了减少代码的冗余,设备树将这些共同部分提炼保存在.dtsi 文件中,供不同的 dts 共同使用。
2,设备树文件类型
一根节点多个子节点,子节点又可以包含多个子节点,以树状的结构散开。 在编写驱动程序时,我们只需关心设备树和平台驱动两样东西,使用平台驱动直接调用设备树的内容。
3, dts 节点node和文件结构
设备树节点是用节点名和单元地址和一个用大括号作为节点定义的开始和结尾来定义的。
• [lable:]:设备树文件允许标签附加在任何节点或者属性上。
• node-name:是指节点的名字。
• [@unit-address]:是指节点所在的基地址。
• [properties definitions]:是指相关属性的定义。
• [child nodes]:是指相关的子节点。
如果父节点中有子节点相同的属性,那么以设备树的父节点的属性为主。所有的 dts 文件都需要有一个 root 节点,并且 root 节点内必须有一个 cpus 节点和至少一个的 memory 节点。
一、Type-C简介以及历史 自1998年以来,USB发布至今,USB已经走过20个年头有余了。在这20年间,USB-IF组织发布N种接口状态,包括A口、B口、MINI-A、MINI-B、Micro-A、Micro-B等等接口形态,由于各家产品的喜好不同,不同产品使用不同类型的插座,因此悲剧来了,我们也要常备N中不明用途的接口转接线材。
图1 USB协议发布时间节点
而对于Type-C来说,看起来USB标准化组织也是意识到统一和标准化问题,在定义标准时,除了硬件接口定义上,还增加了一部分“个性化”特点。分别是什么呢?
1.1 定义了全新的接口形态(Pin Assignments)
接口大小跟Micro USB相近,约为8.3mm x 2.5mm,支持正反插,同时也规范了对应的线材,接口定义如下(线材端只有一对USB2.0 DATA):
图2 Type-C端口的PIN定义-1
图3 Type-C端口的PIN定义-2
在插座定义上,定义了如下两种插座:
a)全功能的Type-C插座,可以用于支持USB2.0、USB3.1、等特性的平台和设备。
b)USB 2.0 Type-C插座,只可以用在支持USB2.0的平台和设备上。
在插头定义上,定义了如下三种插头:
a)全功能的Type-C插头,可以用于支持USB2.0、USB3.1、等特性的平台和设备。
b)USB 2.0 Type-C插头,只可以用在支持USB2.0的平台和设备上。
c)USB Type-C Power-Only插头,用在那些只需要供电设备上(如充电器)。
在线缆定义上,定义了如下三种线缆:
a)两端都是全功能Type-C插头的全功能Type-C线缆。
b)两端都是USB 2.0 Type-C插头的USB 2.0 Type-C线缆。
c)只有一端是Type-C插头(全功能Type-C插头或者USB 2.0 Type-C插头)的线缆。
还定义了N种为了兼容旧设备的线缆:
a)一种线缆,一端是全功能的Type-C插头,另一端是USB 3.1 Type-A插头。
b)一种线缆,一端是USB 2.0 Type-C插头,另一端是USB 2.0 Type-A插头。
c)一种线缆,一端是全功能的Type-C插头,另一端是USB 3.1 Type-B插头。
d)一种线缆,一端是USB 2.0 Type-C插头,另一端是USB 2.0 Type-B插头。
e)一种线缆,一端是USB 2.0 Type-C插头,另一端是USB 2.0 Mini-B插头。
f)一种线缆,一端是全功能的Type-C插头,另一端是USB 3.1 Micro-B插头。
g)一种线缆,一端是USB 2.0 Type-C插头,另一端是USB 2.0 Micro-B插头。
转自:
Java如何接收命令行参数呢?
Java使用接收命令行参数 实现思路:
main函数中会自动接收命令行参数至 args[]数组中,如下例所示:
例
public class testClass {
public static void main(String args[]) { for(int i = 0; i<args.length; i++) {
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
/*
以上代码运行后,将输出以下信息
I:\E\Tmp>java testClass the website java265.com
args[0]: the
args[1]: website
args[2]: java265.com
*/
目录 一、简介二、相关术语三、二叉树1. 相关概念2. 特殊二叉树(1)满二叉树(2)完全二叉树(3)二叉排序树(4)平衡二叉树 3. 二叉查找树的创建(1)二叉树的结点类(2)二叉查找树插入实现(3)二叉查找树查询实现(4)二叉查找树删除实现 4. 二叉树的遍历(1)前序遍历(2)中序遍历(3)后序遍历(4)层次遍历 5. 最大深度问题6. 折纸问题 一、简介 树是我们计算机中非常重要的一种数据结构,同时使用树这种数据结构,可以描述现实生活中的很多事物,例如家谱、单位的组织架构、等等。
树是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”,是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
树具有以下特点:
每个结点有零个或多个子结点;没有父结点的结点为根结点;每一个非根结点只有一个父结点;每个结点及其后代结点整体上可以看做是一棵树,称为当前结点的父结点的一个子树; 二、相关术语 结点的度:
一个结点含有的子树的个数称为该结点的度;
叶结点:
度为0的结点称为叶结点,也可以叫做终端结点
分支结点:
度不为0的结点称为分支结点,也可以叫做非终端结点
结点的层次:
从根结点开始,根结点的层次为1,根的直接后继层次为2,以此类推
结点的层序编号:
将树中的结点,按照从上层到下层,同层从左到右的次序排成一个线性序列,把他们编成连续的自然数。
树的度:
树中所有结点的度的最大值
树的高度(深度):
树中结点的最大层次
森林:
m(m>=0)个互不相交的树的集合,将一颗非空树的根结点删去,树就变成一个森林;给森林增加一个统一的根结点,森林就变成一棵树
孩子结点:
一个结点的直接后继结点称为该结点的孩子结点
双亲结点(父结点):
一个结点的直接前驱称为该结点的双亲结点
兄弟结点:
同一双亲结点的孩子结点间互称兄弟结点
三、二叉树 1. 相关概念 二叉树就是度不超过2的树(每个结点最多有两个子结点)
2. 特殊二叉树 (1)满二叉树 一个二叉树,如果每一个层的结点树都达到最大值,则这个二叉树就是满二叉树。满二叉树的叶子结点都集中在二叉树的最下一层,并且除叶子结点之外的每个结点度数均为 2。
(2)完全二叉树 叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树。
(3)二叉排序树 左子树上所有结点的关键字均小于根结点的关键字;右子树上的所有结点的关键字均大于根结点的关键字;左子树和右子树又各是一棵二叉排序树。
(4)平衡二叉树 树上任一结点的左子树和右子树的深度之差不超过1。
3. 二叉查找树的创建 二叉查找树是二叉树中一种常用的一种类型。二叉查找树是为了实现快速查找产生的。不过,它不仅支持快速查找,还支持快速插入和删除。这主要归功于二叉查找树的一个特性,那就是树中任一节点,这个节点的左子树的值总是小于这个节点的值,这个节点右子树的值总是大于这个节点的值。
二叉查找树API设计
(1)二叉树的结点类 根据对图的观察,我们发现二叉树其实就是由一个一个的结点及其之间的关系组成的,按照面向对象的思想,我们设计一个结点类来描述结点这个事物。
private class Node { // 存储键 public Key key; // 存储值 private Value value; // 记录左子结点 public Node left; // 记录右子结点 public Node right; public Node(Key key, Value value, Node left, Node right) { this.
方法一:简单粗暴,内存消耗大 x = int(input()) res = int(x **0.5) print(res) 方法二:使用math模块 # 引入math模块 import math x = int(input()) ans = math.sqrt(x) ans = str('%.4f' % ans) # 保留四位小数 print(ans.center(20, '*')) # 居中显示,20个字符填充 方法三:二分法 # 二分法 x = int(input()) low, high, ans = 0, x, -1 while low <= high: mid = (low + high) // 2 if mid * mid <= x: ans = mid low = mid + 1 else: high = mid - 1 print(ans) 本文内容原链接
参考书籍: 3.1节
书籍信息:《The Linux Programming Interface》
作者:Michael Kerrisk 时间:2010
流程:
1、应用程序调用C库,其封装的一个系统调用2、封装函数,进行陷入处理的流程,传参,调用陷入指令(int 0x80)。。。。。略3、为了响应,内核激发一个系统调用流程(在一个汇编文件里。)。。 |------------------------- User Mode --------------------------------| | | | Application glibc wrapper function | | program (sysdeps/unix/ | | sysv/linux/execve.c) | | | | | | | | ┌─────────────────────────────┐ | | ┌────┤►execve(path, argv, envp) │ | | │ │ { │ | | ┌───────────────────┐ │ │ │ | switch to | │ ... │ │ │ ... │ | kernel mode | │ execve(path, ────┼───┘ │ int 0x80 ──────────────────┼──|──────┐ | │ argv, envp); │ │ (arguments:__NR_execve, │ | │ | │ .
代码复制于Linux内核:tools/include/linux/kernel.h
作用图:
功能:
1、typeof是编译器扩展的特性(推断出类型),https://gcc.gnu.org/onlinedocs/gcc/Typeof.html#Typeof2、container_of:1、先报地址强制转换为特定成员地址,变量前_为了不冲突 2、计算成员偏移字节 3、再转换为char*,为了进行字节单位的地址运算 4、最终转换为结构体类型即可。。。 5、整个宏是一个复合语句,最后一个子表达式的值就是整个表达式的值。(也是编译器扩展特性,https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html) #include <stdio.h> #include <stdlib.h> //复制于:tools/include/linux/kernel.h #ifndef offsetof #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #endif #ifndef container_of /** * container_of - cast a member of a structure out to the containing structure * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define container_of(ptr, type, member) ({ \ const typeof(((type *)0)->member) * __mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); }) #endif #ifndef max #define max(x, y) ({ \ typeof(x) _max1 = (x); \ typeof(y) _max2 = (y); \ (void) (&_max1 == &_max2); \ _max1 > _max2 ?
文章目录 前言一、软件设计与创新协会会长1.实验室招新2.协会招新3.比赛宣传、活动举办4.回顾,亦是遗憾 二、校企合作项目三、字节跳动青训营四、腾讯云智的实习生活启程,开启实习之路初入公司实习工作业余生活转正失败,夜游武汉离开,亦是归途 五、惨不忍睹的秋招历程六、未来结语 前言 实习结束从外省回到学校,才发现自己已然是大四,回顾一年的大学生活,脑海中更多的是自己忙碌的身影,似乎做了很多,又似乎什么也没做。
过去一年,亦有欣喜、亦有失落;亦有期待,亦有焦虑。
临近就业,不得不在这个人生的十字路口,找一条属于自己的未来之路。
PS:最近一年很少有机会静下心来好好回顾总结了,正好今天没有笔试面试,也趁此机会来回顾一下我过去的大三生活。
一、软件设计与创新协会会长 很多时候我们会不求回报的为学弟学妹提供帮助,因为我们心里明白,当年的自己,也是受到了学长学姐的帮助,从一个菜鸟逐渐成长起来的。
或许这就是一种传承。
大三那年,也是我接任协会会长、实验室负责人的一年。
这一年里,我做了很多事情,也逐渐从稚嫩走向成熟。
1.实验室招新 每逢换届的那个暑假,我们就要开始筹划实验室的换届招新,就像上一届学长学姐招我们进来一样,当年的招新我依然记忆犹新,至今我还保存着上届会长发的实验室录取邮件。
本着传承的精神,我也想把这届的实验室招新办好,为此我也下了一番功夫。
从课程筹划、人员安排、招新宣传,到考勤、授课、邀请实验室的优秀学长学姐分享,再到最后的作业评分、统计,这一切的顺利进行离不开实验室成员的共同努力。
对此我也将其总结为一篇博文,包括集训计划、课程内容、感想等等。
【2021软件创新实验室暑假集训】总结篇
至此,实验室迎来17名新同学。
2.协会招新 我们学校协会招新的活动叫做“百团大战”,顾名思义,就是学校所有注册在案的协会会在这天进行“摆摊”,由于咱们是技术协会,所以也没啥才艺展示,和旁边的acm协会、网络安全协会一起默默摆摊hh。
虽然人不多,但也不乏有些热爱技术的同学上前咨询,从这些同学身上或多或少能看到自己当初的影子。
3.比赛宣传、活动举办 在大三的时候,我也组织了一些活动,比如开学初实验室团建,也沿袭了上一届的一些规则和活动,比如学习小组、两周一篇技术博文等等。
当然,我也负责了一些比赛的宣传和讲座答疑,比如服创、软件杯等等。
4.回顾,亦是遗憾 如今新一任的会长已由学弟接任,回首实验室两年生活,实验室和协会带给我了些什么呢?
在我看来,是知识、担当、眼界和伙伴。
在这里有一群和你一起学习的小伙伴,尽管方向不同,年级不同,但是同在实验室,在这个学习氛围下,可以在大学中中寻得一隅学习的宁静。
同时有了学长学姐和导师的交流,我们的眼界不断开拓,不再拘泥于学校所传授的些许知识,而是根据自己的兴趣去探索学习。
…
当然了,回顾过往,难免有些遗憾,从开始踌躇满志想把实验室办好,到后来受到学业、比赛和实习的影响变成一切从简,和上任会长相比,自己确实不算尽职尽责。
二、校企合作项目 在我大二暑假的时候,通过导师的牵头,我接手了一个校企合作项目——玛嘉环境物联网平台。
物电老师负责硬件开发,而我负责软件平台的建设。
和过往的练手项目,这是第一个投入生产的系统,从需求沟通到项目设计与实现,以及后来的正式上线运行,在这个过程中遇到了非常多的困难。
我也花费了很多时间和精力去设计和实现,最终上线部署,也经历了几个版本的迭代升级。
不过具体的设计和实现就不展开了,当时我也写了一篇博文去总结这个项目【项目总结】玛嘉环境物联网平台(大三学生独立完成的真实企业外包项目)/网脉通用物联网平台/网脉铁塔监测系统。
后来也通过这个项目进行改编参加了浙江省大学生服务外包创新应用大赛,当时也录了参赛视频上传到b站,视频地址。
感兴趣的可以看一下。
通过这个项目,我也小赚了一笔,也算是尝到了通过技术挣钱的甜头。
三、字节跳动青训营 今年五月的时候,参加了字节跳动举办的第三届后端青训营进阶班。里面讲了很多学校里学不到知识和经验,包括go,架构设计、企业研发流程等等。
比较有意思的是组队做项目,当时也组了一个六人队,一起去完成最终的大作业项目——设计实现一款搜索引擎,而我也担任了队长一职。
当时我们也是一点点去收集资料,去学习,然后分工合作,遇到困难一起交流讨论,一起去协助解决问题。现在回想起来那真的是一段非常棒的合作体验,很幸运能遇到这么一群一起努力的小伙伴们。
尽管一些赛制的原因,并没有拿到非常好的成绩,但我认为我们是最棒的!
当时也写了一篇文档用于总结。
GoDance搜索引擎——汇总篇
git仓库地址
这个项目虽然比较粗糙,只实现了基本的功能,但是我之后会将它作为一个毕业设计去继续完成。
四、腾讯云智的实习生活 启程,开启实习之路 从今年三月开始,我开始找暑期实习,很不幸,这个过程四处碰壁。这也让我认识到自己的一些不足,在面试结束后我都会复盘面试中提及的技术点,回顾自己哪些地方没有做好。
在这个过程中不断改进自己,最终也拿到了腾讯云智的暑期实习offer,踏上了前往武汉的路。
初入公司 初入公司,很是兴奋,什么都是新鲜的,四处拍照留念。
实习工作 我们部门是做TDMQ消息队列的,刚进来主要是看iwiki文档,了解业务。一周过后mentor安排了CMQ公有云的测试任务,主要目的是用于了解产品。
大概入职两周后,恰好有个TDMQ私有云的需求,就扔给我做了。所以我后来也主要是负责TDMQ私有云这块的开发工作。
说实话对于项目开发,代码本身难度并不是很大。
但依旧遇到了很多卡点:
之前去看的文档并非私有云相关,所以上手需要时间项目规范对于新人而言不太友好
比如数据库表设计没有对应的文档,只有没有注释的SQL文件,对于理解数据库设计而言造成一定的障碍;又比如项目注释这块,由于很多业务逻辑并没有文档记录,相应的代码也没有注释,所以对于理解和修改业务逻辑这块造成了困难,因为你不知道改了这块对其他地方是否有影响,或者对于一些奇怪的操作不敢去优化(后面询问负责这块的同事,发现存在一些冗余操作)私有云开发这块流程很多,熟悉这块依旧需要时间(不同于公有云,私有云有很多自己的开发流程)私有云开发涉及链路很长,新人入门这块是一个巨大的挑战
在公有云中,每个组件都有专门的维护人员,而在私有云中,你要负责整个产品的稳定。当出现问题,尽管可能问题的解决不一定是你,但你需要定位问题,并和相关组件的同学沟通。而这就要求你对每个组件(包括运营端、底层基座Pulsar、监控组件等等)都要有或多或少的了解,不然根本没法定位问题。私有云开发需要和多个团队沟通协作,沟通效率这点非常难受
在我接手这块的两个月里,沟通过的团队就不下五个,比如CICD(流水线问题)、配置中心(配置消费问题)、vpc(无法连接问题)、barad、云哨(监控接入需求)、环境(监控接入过程中数次出现es写满问题)等等。 好在有负责私有云的师兄帮助,这些困难也一点点被克服解决。
不过憋屈的一点在于,mentor并不是做私有云这块的,在他看来,我做一个大需求做了快两个月,产出并不是特别明显,所以很多时候觉得我不够积极,能力不行。
文章目录 背景环境前置知识安装过程#bug1#bug2#bug3 背景 学习一项技能的最好方式自然是理解+实践,在了解了 hadoop 的基本概念后我开始尝试在本地搭建一个集群环境用于进一步学习。
但是经过尝试后发现想在 MacOS 中搭建一个集群比我想象中困难得多,其中也有一部分原因是我对 macOS 系统不太熟悉,可谓是一坑未填一坑又起了。经过不懈努力终于搭建了一个基于 docker 的 hadoop 集群,故有此一文作记录和分享~
环境 macOS (version: 12.3, chip: Apple M1 Pro, memory: 16GB)
colima 0.4.5
docker 20.10.18
前置知识 这里简单介绍下 hadoop 的一些基本概念。
hadoop 的基本组成为 MapReduce、Yarn、HDFS 等组件。
其中 HDFS 是一种分布式的文件系统,它的主要组成是 NameNode、SecondaryNameNode 和 Datanode 等。
而 Yarn 是 hadoop 在 2.x 版本后设计的分布式资源调度工具,其主要组成为 NodeManager 和 ResourceManager 等。
更详细的基础知识可以参考我的博客笔记:
https://blog.csdn.net/weixin_40815218/article/details/126838369
安装过程 一般情况下,搭建一个高可用的 hadoop 集群通常是选择两台以上的物理服务器来运行不同的节点。本文的目的是搭建一个用于学习的集群,可以先不考虑 HA,而据我了解,将一台机器用作多个服务器的方法一般有虚拟机方式和 docker 容器方式两种。
相比于搭建虚拟机,我更倾向于选择后者,因为虚拟机的安装和配置更加复杂,对资源消耗也更大。同时因为之前参加 twu 也已经安装好了 colima 虚拟环境下的docker,就愉快地决定用docker开始搭建了。
一条简单的SQL查询语句,执行流程: 查询缓存-词法分析-语法分析-语法书-预处理器-优化器-执行计划-执行器-调用API-引擎-数据
执行器-返回数据-返回缓存
概述 undo log:回滚日志,原子性,实现事务回滚和MVCC,引擎层实现
redo log:重做日志,崩溃恢复,持久性 ,引擎层实现
bin log:主从复制,数据备份,Server层实现
undo log作用? undo log:在事务还没有提交之前,记录更新修改前的数据,插入一个新的记录保存新纪录的索引,需要回滚时
找到索引并删掉记录,更新和删除需要保存完整记录,用于恢复。记录的是逻辑日志,delete操作时会有insert记录,
update时反向的update记录。
每产生一个undo log日志都会有一个trx_id和roll_point生成:
trx_id:保存生成此日志的事务id;
roll_point:将undo log连接起来形成版本连;
undo log+ReadView 实现MVCC(多版本并发控制):根据ReadView里面存储的trx_id 和undo log版本链记录中的trx_id进行对比。
读提交隔离级别:每次select操作都生成一个ReadView,保证每次查询到的数据都是已经提交的
可重复读隔离界别:只有第一次select生成一个ReadView,后续每次查询都依据那个ReadView进行查找。
redo log作用? redo log:Buffer pool提高了读写性能,但是数据放在内存中是不可靠的,当程序崩溃或者系统断电时会造成缓冲区中脏页
数据没来及持久化到磁盘,因此InnoDB引擎在一条记录需要更新时,现将内容保存在redo log中,后台线程择机将记录持久化
到磁盘中。WAL(Write-Ahead-Logging),即MySQL写操作并不马上更新磁盘,而是先记录在日志中,在适当时候在写到磁盘中。
redo log是物理日志,记录对XXX表空间YYY页的ZZZ偏移位置做了NNN更新。当事务提交时,先将更新记录在redo Log文件中并将其持久化
到磁盘即可,当发生崩溃,虽然缓存中脏页没有更新到磁盘,但是可以根据redo log文件进行恢复。
undo log 和 redo log的区别:
undo log记录事务提交前的状态,更新前的值,用于事务回滚;
redo log记录事务提交后的状态,更新后的值,用于数据恢复,持久化
事务提交前发生崩溃使用undo log来恢复,提交后崩溃使用redo log 恢复;
为什么将数据写入redo log文件比较快?
redo log文件记录时顺序写,而更新数据库磁盘是随机写,随机写速率远远低于顺写。
redo log直接写入磁盘嘛?
NO,redo log也有自己的缓冲区。所以redo log什么时候刷盘写入到磁盘的时机很重要。
主要有以下几个时机:
MySQL服务器正常关闭;
记录空间超过redo log缓冲区大小一半;
InnoDB后台线程1秒钟刷新一次;
线程的优先级(优先级(priority)要设置在.start之前)
线程的默认优先级为5(例如主线程main的),最低的优先级为1,最大的优先级为10.其中若是大于最大的优先级10或者小于最小的优先级1。他会抛出异常不会执行优先级低cpu可能会发生先与优先级高的调度 还是要看cpu心情(麻了)
package org.example.threadpriority; public class TestPriority { public static void main(String[] args) { System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority()); Priority priority = new Priority(); Thread thread1 = new Thread(priority); Thread thread2 = new Thread(priority); Thread thread3 = new Thread(priority); Thread thread4 = new Thread(priority); Thread thread5 = new Thread(priority); Thread thread6 = new Thread(priority); thread1.start(); thread2.setPriority(1); thread2.start(); thread3.setPriority(4); thread3.start(); thread4.setPriority(Thread.MAX_PRIORITY); thread4.start(); // thread5.setPriority(11); thread5.setPriority(8); thread5.start(); // thread6.setPriority(-1); thread6.setPriority(6); thread6.start(); } } class Priority implements Runnable{ @Override public void run() { System.
转载
SimpleDateFormat类简单介绍 SimpleDateFormat类是DateFormat的子类,叫日期格式化类,专门用来格式化和解析日期的,是一个以和语言环境有关的方式来格式化和解析日期的具体类,它允许进行格式化和解析。格式化指的是将存储日期的类转化为字符串记录的日期形式,这里主要指Date类转化为String类。解析是格式化的逆过程,指的是将表示日期的字符串转化为记载日期的类。
常用的模式字母及对应关系 日期和时间格式由日期和时间模式字符串指定,在日期和时间模式字符串中,从'A'到'Z'以及从'a'到'z'引导的字母被解释为表示日期或时间字符串的组件的模式字母,对应关系如下:
y 年M 月d 日H 时m 分s 秒 构造方法 无参构造方法public SimpleDateFormate():使用默认模式和日期格式带参构造方法public SimpleDateFormate(String pattern):使用给定的模式和默认的日期格式 成员方法 格式化(从Date到String) public final String format(Date date):将日期格式化成日期/时间字符串,示例代码如下:
Date d=new Date(); SimpleDateFormat sdf=new SimpleDateFormat(); String s=sdf.format(d); System.out.println(s); //输出:2022/10/15 下午3:04 因为使用的是无参构造方法,所以输出的是默认模式和日期格式
Date d=new Date(); SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String s=sdf.format(d); System.out.println(s); //输出:2022年10月15日 15:19:11 这里使用的是带参构造方法,给出了指定格式,所以按照指定格式输出
解析(从String到Date) public Date parse(String source):从给定字符串的开始解析文本以生成日期
String ss="2022-10-15 15:15:36"; SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dd=new Date(); dd=sdf2.parse(ss); System.out.println(dd); //输出:Sat Oct 15 15:15:36 CST 2022 这里需要使用带参构造方法,且带参构造方法中的指定格式要与给定字符串的格式相同,否则会抛出异常
数据通信的基本概念 通信的目的就是传递信息。
信源: 通信中产生和发送信息的一端
信宿: 接收信息的一端
信道: 信源和信宿之间的通信线路
变换: 信息在进入信道时要变换为适合信道传输的形式,在进入信宿时又要变换为适合信宿接收的形式
噪声: 信息在传输过程中可能会受到外界的干扰(雷电、大功率电器、变压器等)
模拟通信: 信源产生的是模拟数据并以模拟传输
数字通信: 信源发出的是模拟数据且以数字信号的形式传输
通信系统模型 信道特性 信道带宽W(常考) 模拟信道:
信道带宽计算: W = f 2 − f 1 W=f_2-f_1 W=f2−f1
f1是信道能通过的最低频率,f2 是信道能通过的最高频率,两者都是由信道的物理特性决定的,以赫兹(Hz)为单位。当组成信道的电路制成了,信道的带宽就决定了。
数字信道(无噪声):
数字信道是离散信道,带宽为信道能够达到的最大数据传输速率,单位是bit/s
数据传输速率:
指每秒钟能够传输的二进制数据位数,单位为比特/秒(记作bit/s、b/s或bps)
码元:一个数字脉冲称为一个码元
码元速率:
单位时间内信道传送的码元个数。如果码元宽度(脉冲周期)为T,则码元速率(波特率)为B=1/T,单位是波特Baud
一个码元携带信息量n(位)与码元种类数(N)的关系 n= log 2 N \log_{2}{N} log2N
尼奎斯特定理:
在一个理想的(没有噪音环境)信道中,若信道带宽为W,最大码元速率为:B=2W(Baud)
极限数据速率为:R=B log 2 N \log_{2}{N} log2N=2W log 2 N \log_{2}{N} log2N
香农定理:
在一个噪声信道的极限数据速率和带宽之间的关系
极限速率公式为:C=W log 2 ( 1 + S N ) \log_{2}{(1+\frac{S}{N})} log2(1+NS)
这里写自定义目录标题 1.1 什么是因特网1.1.1 具体构成描述1.1.2 服务描述1.1.3 什么是协议 1.2 网络边缘1.2.1 接入网1.家庭接入:DSL、电缆、FTTH、拨号和卫星2.企业(和家庭)接入:以太网和WiFi3.广域无线接入:3G和LTE 1.2.2 物理媒体1.双绞铜线(最便宜且最常用)2.同轴电缆(共享媒体)3.光纤(长途)4.陆地无线电信道(蜂巢接入技术)5.卫星无线电信道(同步卫星和近地轨道) 1.3 网络核心1.3.1 分组交换1.存储转发传输2.排队时延和分组丢失3.转发表和路由选择协议 1.3.2 电路交换1.电路交换网络中的复用2. 分组交换与电路交换的对比 1.3.3 网络的网络 1.4 分组交换网中的时延、丢包和吞吐量1.4.1 分组交换网中的时延概述1.4.2 排队时延和丢包 1.1 什么是因特网 1.1.1 具体构成描述 因特网是一个世界范围的计算机网络,即它是一个互联了遍及全世界数十亿计算设备的网络。而计算设备有传统的桌面PC、Linux工作站以及所谓的服务器(它们用于存储和传输Web页面和电子邮件报文等信息)、以及非传统设备(如便携机、智能手机、平板电脑、电视、游戏机、温度调节装置、家用安全系统、家用电器、手表、眼镜、汽车、运输控制系统等)正在跟因特网相连。以上所介绍的设备都称为主机或端系统。端系统通过通信链路和分组交换机连接到一起。其中通信链路的物理媒体包括同轴电缆、铜线、光纤以及无线电频谱。不同的链路以不同的速率传输数据,链路的传输速率以比特/秒(bit/s,或bps)度量。当一台端系统向另一台端系统发送数据时,发送端系统将数据分段,并在每段加上首部字节。因此形成的信息包称为分组。分组交换机从它的一条入通信链路接收到达的分组,并从它的一条出通信链路转发该分组。其中两种最著名的分组交换机有路由器(router)和链路层交换机(link-layer switch)。从发送端系统到接收端系统,一个分组所经历的一系列通信链路和分组交换机称为该网络的路径(route或path)。端系统通过因特网服务提供商(ISP) 1接入因特网,包括如本地电缆或电话公司那样的住宅区ISP、公司ISP、大学ISP,在机场、旅馆、咖啡店和其他公共场所提供WiFi接入的ISP,以及为智能手机和其他设备提供移动接入的蜂巢网络ISP。每个ISP自身就是一个由多台分组交换机和多段通信链路组成的网络。各ISP为端系统提供了各种不同类型的网络接入,包括如线缆调制解调器或DSL那样的住宅宽带接入、高速局域网接入和移动无线接入。ISP也为内容提供者提供因特网接入服务,将Web站点和视频服务器直接接入因特网。端系统、分组交换机和其他因特网部件都要运行一系列协议,这些协议控制因特网中信息的接收和发送。TCP(Transmission Control Protocol,传输控制协议) 和 IP(Internet Protocol,网际协议) 是因特网两个最为重要的协议。IP协议定义在路由器和端系统之间发送和接收的分组格式。因特网的主要协议统称为TCP/IP。因特网标准由因特网工程任务组(IETF)研发。IETF的标准文档称为请求评论(RFC)。 1.1.2 服务描述 云的音乐游、电影和电视流、在线社交网络、视频会议、多人游戏以及基于位置的推荐系统。因此这些应用程序涉及多个相互交换数据的端系统,故它们被称为分布式应用程序。(distributed application)。与因特网相连的端系统提供了一个套接字接口(socket interface),该端口规定了运行在一个端系统上的程序请求因特网基础设施向运行在另一个端系统上的特定目的地程序交付数据的方式。 1.1.3 什么是协议 协议(protocol) 定义了在两个或多个通信实体之间交换的报文的格式和顺序,以及报文发送和/或接收一条报文或其他事件所采取的行动。 1.2 网络边缘 端系统也称为主机,主机有时候又被进一步划分为两类:客户(client) 和服务器(server)。 1.2.1 接入网 接入网的作用:将端系统物理连接到其边缘路由器的网络。
边缘路由器是端系统到任何其他远程端系统路径上的第一台路由器。
1.家庭接入:DSL、电缆、FTTH、拨号和卫星 宽带住宅接入有两种最流行的类型:数字用户线(Digital Subscriber Line,DSL)和电缆。 住户通常从提供本地电话接入的本地电话公司处获得DSL因特网接入。因此,使用DSL的时候,用户的本地电话公司也是它的ISP。每个用户的DSL调制解调器使用现有的电话线(双绞铜线)与位于电话公司的本地中心局(CO) 中的数字用户线接入复用器(DSLAM) 交换数据。家庭的DSL调制解调器得到数字数据后将其转换为高频音,以通过电话线传输给本地中心局;来自许多家庭的模拟信号在DSLAM处被转换回数字格式。在用户一侧,一个分配器把到大家庭的数据信号和电话信号分隔开,并将数据信号转发给DSL调制解调器。在电话公司一侧,在本地中心局中,DSLAM把数据和电话信号分隔开,并将数据送往因特网。数百甚至上千个家庭与同一个DSLAM相连。DSL利用电话公司现有的本地电话基础设施,而电缆因特网接入(cable Internet access) 利用了有线电视公司现有的有线电视基础设施。电缆因特网接入需要电缆调制解调器(cable modem)。通过一个以太网端口连接到家庭PC。而电缆调制解调器端接系统(CMTS) 与DSL的DSLAM具有相似的功能,即将来自许多下行家庭中的电缆调制解调器发送的模拟信号转换回数字形式。电缆调制解调器将HFC网络划分为下行和上行两个信道。其接入是不对称的,下行信道分配的传输速率通常比上行信道的高。电缆因特网接入的一个重要特征是共享广播媒体。光纤到户(FTTH) 从本地中心局直接到家庭提供了一条光纤路径。光纤分布体系结构分为两类:有限光纤网络(AON) 和无限光纤网络(PON)。其中,AON的本质就是交换以太网。PON分布体系结构的FTTH中,每个家庭具有一个光纤网络端接器(ONT,Optical Network Terminator) ,它由专门的光纤连接到附近的分配器(splitter) 。该分配器将一些家庭(通常少于100个)集结到一根共享的光纤,该光纤再连接到本地电话和公司的中心局中的光纤线路端接器(Optical Line Terminator,OLT) ,该OLT提供了光信号和电信号之间的转换,经过本地电话公司路由器与因特网相连。在某些乡村环境,可以使用卫星链路 将住宅以超过1Mbps的速率与因特网相连。 2.
运行Arcgis和SWAT模型遇到Error Number 91和Error Number -2147467259报错怎么办? 问题描述 遇到如下报错
问题解决 把Arcgis的并行计算改为0即可。
打开Arcgis,点击Geoprocessing——Environments,进入Environment Settings面板,找到Parallel Processing, 输入0,点击OK。
PADS软件默认的焊盘结构有3层Mounted Side、Inner Layers、Opposite Side。根据使用经验,需要增加Layer_25层。为了后期设计使用的方便,插装元件还要增加3层Solder Mask Top、Solder Mask Bot、Assembly Drawing Top。
所以通孔焊盘共有7层:Mounted Side、Inner Layers、Opposite Side、Solder Mask Top、Solder Mask Bot、Assembly Drawing Top和Layer_25。
贴装焊盘只有4层Mounted Side、Solder Mask Top、Paste Mask Top、Assembly Drawing Top。在PADS软件中,贴装焊盘的Inner Layers、Opposite Side不能删除,只能把尺寸设置为0。
焊盘结构的每一层大小和形状都需要进行设置。
1)大小:除Layer_25层,其它层焊盘尺寸比孔尺寸至少大0.6mm,相当于环宽0.3mm,对于孔径较大的,可以适当增加焊盘尺寸。Layer_25层的焊盘尺寸比其它层焊盘大0.5mm(或20mil)。
2)形状:通孔焊盘图形的焊盘一般各层为圆形,用方形焊盘作为标识性引脚,如极性元件的正极引脚,多引脚元件的第一脚等。方形焊盘指Mounted Side、Opposite Side 及对应Solder Mask Top、Solder Mask Bot、Assembly Drawing Top为方形,Inner Layers、Layer_25这两层可以维持圆形不变。
边框线在Silkscreen Top、Assembly Drawing Top这两层绘制:
1)线宽(Width):≥0.1mm。
2)元件的边框线,按元件尺寸最大值进行绘制。
3)对于Silkscreen Top层,边框线外侧和焊盘外侧之间的距离根据元件尺寸调整,默认 ≥0.2mm,如下图所示。如果按2)绘制不满足此要求,需要进一步调整。
4)最好在装配层Assembly Drawing Top也加上name。
pads layout具体制作封装如下,以制作0402封装为例:
1、打开pads软件中的pads layout软件,我这里时VX2.4的版本,大体上操作区别不大
2、软件打开后选择文件->库,会弹出以下界面。如果你之前已经建好了库可以直接用,如果没有建好,则需要重新建一个库用于存放封装,我这里之前已经建了一个0402的库,就直接使用了,然后点击封装,新建,然后点击关闭。
3、在封装绘制界面选择绘图工具栏,弹出绘图工具
4、点击绘图工具中的端点添加焊盘,选择表贴焊盘(具体需要根据实际需要选择表贴或者通孔)如果制作焊盘你是按照公制的mm,输入umm命令切换成公制mm,um命令切换成mil。
5、选择添加的焊盘,右键选择焊盘栈,弹出如下界面,点击添加,添加阻焊顶层、助焊顶层、装配顶层,以及25层(也可以不加)。然后将贴装层以及这几层设置对应的焊盘尺寸
6、然后右键选择特性,设置焊盘的位置,一般来说如果封装时对称的,则以坐标原点为中心,计算后放置焊盘。
7、然后再选择焊盘,右键选择分布和重复 ,选择方向,数量以及焊盘间距,这个距离为焊盘的中心到原点的距离。
8、选择工具中的2D线绘制丝印框以及装配框
9、选择标签name以及Type,右键选择特性,将层改为丝印顶层,然后添加新标签,层设置为装配顶层
10、最后将建立好的封装保存
4.C++11的新特性:
(1)auto关键字,在编译时根据初始值自动推导类型,必须初始化,通常作为变量或返回值。
(2)decltype(declare type)用于推导数据类型,用于声明变量、配合auto设置返回值(如下:)(相较于auto不会计算初始值,可以加上括号获取引用)
template <typename Creator>
auto processProduct(const Creator& creator) -> decltype(creator.makeObject()) {
auto value = creator.makeObject();
return value;
}
(3)nullptr,空指针,与NULL(即int 0)进行区分。
(4)在make_pair的基础上扩展了make_tuple,可以构造N元组。
(5)容器初始化可以直接在{}内。
(6)简化for循环,for(auto element : container)
(7)Lambda表达式,可以创建函数对象,通常为:
[可以使用的Lambda表达式之外的全局变量](参数){运算;}
例如:for_each(vector1.begin(), vector.end(), [b](int x){ cout << b+x << endl; });
sort(vector1.begin(), vector.end(), [](int a, int b){ return a>b ;})
智能指针的析构函数
5.栈溢出:栈使用的内存是有限的,在编译时就确定了。如果程序运行期间栈内存超出最大值,就会发生栈溢出。
常见的原因是:递归(每次调用函数都会将局部变量放入栈中),死循环,使用超大对象(没有new到内存上,例如存面片信息的结构体)。
6.C++11智能指针:控制对象的生命周期,自动释放空间。实现原理是引用计数。C++11提供了三种智能指针,shared_ptr(共享指针),unique_ptr(独占指针),weak_ptr(弱指针)。
(1)shared_ptr:常用的智能指针,允许多个指针指向同一个内部对象。通过“.”调用智能指针函数,包括use_count获取引用数,move转移给其他智能指针,reset重置指针(而非对象),get()获取指针;使用对象的变量和函数的方式与普通指针相同(通过指向运算符“->”)。可以通过lambda表达式设置析构函数,一般使用default_delete。
(2)unique_ptr:不允许其他指针指向其内部对象。同样支持move和reset,但是不允许赋值、拷贝操作(make_unique)。实现原理:它的本质是类,离开作用域时会调用析构函数;把拷贝构造函数和赋值运算为private,从而禁用赋值和拷贝。
(3)weak_ptr:不会增加引用数,不控制对象生命周期(存在weak_ptr也会被正常销毁),不能操作资源(不能通过weak_ptr使用对象),用于监控shared_ptr的资源。通过expired函数判断内部对象是否被释放,lock创建shared_ptr(引用值会增加),reset相同。
循环引用:两个类A和B中分别有指向对方的shared_ptr成员变量,分别创建A和B对象的shared_ptr并让他们的成员变量指向对方,这样即使reset A和B的对象指针,二者的引用计数也均不为0,造成内存泄漏。解决办法:有一方采用weak_ptr即可。
weak_ptr可以存在vector等C++标准容器中,因为支持拷贝构造和赋值运算。但是由于不可操作指针指向的资源,不可以存在set这种容器中。
7.static:声明静态变量、静态函数,放在静态变量存储区中,生命周期是整个程序运行期间。类的静态成员变量、静态函数是所有对象共享的;即使在函数内部声明静态变量,也会置于静态存储区;即使重复声明,依旧会使用静态存储区内已经创建的变量(即重复声明无效)。
应用场景:类的静态成员变量、静态函数是所有对象共享的。静态函数通常用于配置类(设置系统属性),工具类(例如不需要关注内部细节的数据交换)。
全局变量与静态变量的区别:全局变量通过extern声明,作用于整个项目,静态变量通过static声明,作用于当前类。
extern:声明全局变量或函数的作用范围,使用其他文件的全局变量或函数时用到。
8.进程与线程:
(1)进程:是操作系统分配资源的基本单位。
(2)线程:是进程的子单位,是CPU调度的基本单位,共享同一进程的资源。线程执行本质是函数执行,有独立的线程上下文,包括程序计数器、栈区、寄存器。
(3)区别:①进程是操作系统分配资源的基本单位,线程是CPU调度的基本单位。②线程创建、撤销开销小,创建、撤销进程时需要分配、回收资源。③线程有更好的并发性,因为一个进程中的多个线程可以并发执行。
34.死锁:两个或两个以上的进程在执行过程中,由于竞争资源而导致无法推进的现象。
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-10-14 20:01:15.567 ERROR 9560 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : ***************************
APPLICATION FAILED TO START
***************************
Description:
Field employeeService in com.itheima.reggie.controller.EmployeeController required a bean of type 'com.itheima.reggie.service.EmployeeService' that could not be found.
解决方法:
在service的impl文件夹下的EmployeeServiceImpl中添加
@Service注解 package com.itheima.reggie.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.itheima.reggie.entity.Employee; import com.itheima.reggie.mapper.EmployeeMapper; import com.itheima.reggie.service.EmployeeService; import org.springframework.stereotype.Service; @Service public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService { }
一、Java语言简介 Java语言的前身是oak语言,是美国Sun Microsystems公司1991年推出的,仅限与公司内部使用的语言。Java是一种功能强大的程序设计语言,即是开发环境又是应用环境,它代表一种新的计算模式。Java的特点: 语法简单,功能强大,安全可靠。与平台无关。解释编译两种运行方式。多线程动态执行兼有丰富的API文档及类库。 二、Java开发环境的安装与设置 JDK(java SE Development Kit Java语言软件开发包)是原Sun公司提供的软件包,其中含有编写和运行程序的所有工具,包括组成Java环境的基本构件。jdk-8u131-windows-x64.exe安装完成后,需要设置环境变量。环境变量设置完毕,重启计算机让这些设置生效。 三、Java程序示例 Java程序分为两种,一种是Java应用程序,另一种是Java小应用程序,或叫Java小程序。Java程序由类构成,含一个main()方法,称为主方法或者主函数。程序是通过Java解释器来执行的独立程序,可以使用命令直接运行。整个程序的运行人口是main()方法,main()方法执行完毕,整个程序也即结束。一个程序可以包含一个或多个.java文件。不论文件个数有多少,其中只能由一个main()方法。源文件是文本形式的文件Java的执行系统是不能识别的,它必须经过编译,生成字节码的类文件后才能运行,类文件是二进制格式的,它有统一的格式,JVM可以识别文件并执行它。编译一个程序的命令格式是: javac 源文件名 运行一个程序的命令格式是: Java 程序名【参数列表】 Java是解释器的名称,表示要运行一个由程序名指定的程序,程序名也就是类的名字,后面的参数列表是可选的,如果想要向程序传送参数,则可以把这些参数一次列在程序名的后面,个数不限。IDE是集成开发环境的缩写。这是一个提供给开发人员使用的程序徐开发环境,通常包含了代码编辑器、编译器、调试器、和图形用户界面等工具。 四、 使用Java核心API的文档 JDK文档中又许多的HTML文件,这些事JDK提供的应用程序编程接口文档,可使用浏览器查看。最基本的是Java核心API。 五、Java中的面向对象技术 所谓的面向对象的方法学,就是使分析、设计和实现一个系统的方法尽可能地接近人们认识一个系统的方法。通常包括3各方面,面向对象的分析OOA、面向对象的设计OOD、和面向对象的程序设计OOP。OOP技术把问题看作是相互作用的事物的集合,也就是对象的集合。对象具有一个特性,一是状态,二是行为。状态是指对象本身的信息,行为是实现对对象的操作。OOP中采用了三大技术:封装、继承和多态。封装体现的特点是将对象的属性及实现细节隐藏起来,只给出如何使用的信息。将数据及对数据的操作捆绑在一起成为类,这就是封装的技术。
文章目录 pycharm interpreter设置Python包搜索路径与安装路径anaconda虚拟环境和Python包安装包后仍然no module named的原因jupyter notebook pycharm interpreter设置 在cmd中输入which Python,将输出路径复制到interpreter路径中即可。
(若安装了anaconda,先进行activate:conda env list→conda activate env_name)
此时在cmd pip的包即可在pycharm被调用。
若仍报错误的导入路径,可能是之前添加了错误路径,在settings-interpreter-show all-show path中删除多余路径即可
只保留默认路径:
Python包搜索路径与安装路径 python包搜索路径
Python中使用import sys sys.prefix
我们记输出为<prefix>,即Python路径的前缀,那么:
我们的Python解释器就位于<prefix>/ bin/ python;
在import包时会搜索:
Python标准库位于<prefix>\ lib(标准库)、Python第三方库位于<prefix>\ lib\ pythonX.Y\ site-packages(第三方库)、当前路径(pwd命令返回结果)等。
使用sys.path可查看当前配置下import的具体搜索路径。
如果安装的位置不在path中,可以使用PYTHONPATH=/path/file将该路径放入环境变量PYTHONPATH中,程序搜索时会默认先搜索PYTHONPATH。
但是要注意,把不同版本的Python库都到PYTHONPATH是不合适的。
Python包安装路径
在不进行自定义配置时,pip install 默认安装到<prefix>\ lib\ pythonX.Y\ site-packages下。
使用 pip install package --target TARGET可以将包安装到指定位置。
anaconda虚拟环境和Python包 虚拟环境可以隔离不同Python版本的包,每创建一个虚拟环境就会创建一个新的<prefix>目录,从而将包安装到不同目录下。
安装包后仍然no module named的原因 py文件在搜索目录的次级文件夹中.
例子:
pip install EulerPy 显示euler成功安装,但import euler 仍然报错no module named euler
打开安装目录发现目录下的文件夹名称是EulerPy,而euler.py在文件夹下
一、字面意思是请求体太大,一般出现在上传文件。
二、主要问题:
Nginx默认最大能够上传1MB文件,大于1MB的文件自然无法上传,打开nginx.conf(没权限找运维人员)在http{ }中设置:client_max_body_size 50m。
三 、总结:
文件无法上传大概就有以下四个方面的原因:
服务器对上传文件带下做了限制。(Nginx,Apache,IIS等服务器,文中仅对Nginx配置做了说明)
网关对上传文件大小做了限制,此时添加配置即可。
SpringBoot/Spring对上传文件大小做了限制,添加配置即可。
文件确实过大,前后端链接超时,自动断开链接。(可前端做限制)
今天突然想到用debug来调试一下unity,看一下我的东西,于是在vs的调试栏找到当初下载的Unity的Vs工具,如果不知道是否下载过这个工具可以在工具栏的第一项获取工具与功能中查看。 然后就选择当前存在的已经打开的unity项目。
如图:
根据项目名选择就好 但是确定之后出现了**“由于目标计算机积极拒绝,无法连接”**,连续尝试了几次包括重启之后依旧如此。
由于本菜鸡第一次遇见这种情况,所以直接百度了一下,具体的解决方案可以看其他博主的文章,我的方法是删除了上面划红线的工具,然后重新下载导入,此时打开这个项目的文件时,解决方案资源管理器会提示缺少一些文件,然后让你下载导入(忘了截图了,问题不大),完成之后再次调试附加,然后我就成功进入debug了。(这应该算是一个最原始的办法吧,但是还是成功了,也不算什么解决问题,还有就是unity的debug必须在unity运行你的项目之后程序到达断点才会出现下图,不然是没有数据的),至此记录结束。
文章目录 1 组件的 props2 在组件中声明 props3 无法使用未声明的 props4 props 的大小写命名5 props 验证6 对象类型的 props 节点7 props 验证8 基础的类型检查8.1 支持校验的基础类型 9 多个可能的类型10 必填项校验11 属性默认值12 自定义验证函数13 props配置项的注意点 1 组件的 props 为了提高组件的复用性,在封装 vue 组件时需要遵守如下的原则:
组件的 DOM 结构、Style 样式要尽量复用
组件中要展示的数据,尽量由组件的使用者提供
为了方便使用者为组件提供要展示的数据,vue 组件提供了 props 的概念。
props 是组件的自定义属性,组件的使用者可以通过 props 把数据传递到子组件内部,供子组件内部进行使用。
props 的作用:
父组件通过 props 向子组件传递要展示的数据。
props 的好处:
提高了组件的复用性。
2 在组件中声明 props 在封装 vue 组件时,可以把动态的数据项声明为 props 自定义属性。自定义属性可以在当前组件的模板结构中被直接使用。示例代码如下:
<template> <div> <h3>标题:{{title}}</h3> <h5>作者:{{author}}</h5> <h6>发布时间:{{pubTime}}</h6> </div> </template> <script> export default { name: 'MyArticle', // 外界可以传递指定的数据,到当前的组件中 props: ['title', 'author', 'pubTime'] } </script> 父组件向子组件传值,可以直接传值,也可以使用动态属性绑定。
Docker 安装 MySQL8.0(mac) 1. docker 安装 MySQL 8.01.1 拉取MySQL镜像1.2 查看 MySQL 安装情况1.3 创建 mysql8.0 容器1.4 操作 mysql8.0 容器1.5 远程登录 MySQL 2. 创建远程管理员帐号创建一个可以远程登陆的 admin 用户为账户开放权限 1. docker 安装 MySQL 8.0 1.1 拉取MySQL镜像 docker pull mysql:8.0.31 1.2 查看 MySQL 安装情况 docker images 1.3 创建 mysql8.0 容器 docker run -di --name=mysql8.0 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8.0.31 -p 代表端口映射,格式为 宿主机映射端口:容器运行端口-e 代表添加环境变量 MYSQL_ROOT_PASSWORD 是root用户的远程登陆密码(如果是在容器中使用root登录的话, 那么其密码为空) 1.4 操作 mysql8.0 容器 docker exec -it mysql8.0 /bin/bash mysql -u root -p 1.
uniapp中使用uview优雅地格式化时间 其他传统代码实现比较麻烦,因为项目本身用了uview框架,而且这种方式用起来很方便,所以借助uview提供的方式。
uView把timeFormat()注册到了全局过滤器中,方便在模板中使用: //我们可以直接使用date过滤器,默认参数为yyyy-mm-dd,我们也可以选择传参数date('yyyy-mm') //第一个参数: 任何合法的时间格式、秒或毫秒的时间戳(必传) //第二个参数: 时间格式,可选传。默认为yyyy-mm-dd,格式可以自由搭配,如: yyyy:mm:dd,yyyy-mm-dd,yyyy年mm月dd日,yyyy/mm/dd/,MM:ss等 <div class="pay-item"> <span>堆存期:</span> <span>{{ item.expectDate | date }} ~ {{item.fspExpiryDate | date}}</span></div> 在js中使用: //uni.$u.timeFormat(e.value, 'yyyy-mm-dd');这种写法传参和过滤器写法是一样的 selectDate(e){ let self = this; self.time = uni.$u.timeFormat(e.value, 'yyyy-mm-dd'); self.dateShow = false; },
ByteBuffer的使用 一、认识ByteBuffer二、ByteBuffer使用1、读取文本数据2、正确使用ByteBuffer3、ByteBuffer的结构4、ByteBuffer的常见方法(1)分配空间(2)向 buffer 写入数据(3)从 buffer 读取数据(4)mark 和 reset 5、练习 一、认识ByteBuffer Bytebuffer
官方解释A byte buffer,一个字节缓冲区。
二、ByteBuffer使用 1、读取文本数据 有一普通文本文件 data.txt,内容为
1234567890abcd 使用 FileChannel 来读取文件内容
@Slf4j public class ChannelDemo1 { public static void main(String[] args) { /** * FileChannel获取的方法 1、输入输出流 2、RandomAccessFile */ try (RandomAccessFile file = new RandomAccessFile("data.txt", "rw")) { FileChannel channel = file.getChannel(); // 准备一个缓冲区,大小可以自定义 ByteBuffer buffer = ByteBuffer.allocate(10); do { // 从channel中读取数据,向缓冲区中写入 int len = channel.read(buffer); log.debug("读到字节数:{}", len); if (len == -1) { break; } // 打印读出的数据即buffer中的内容 // 切换至ByteBuffer的读模式 buffer.
内网项目需要Mysql数据时,一步步手动安装Mysql数据库比较繁琐,使用Bat脚本一键安装,大大方便了项目部署过程。
Mysql安装脚本 @ECHO ON :: 获取当前运行路径 @set Home=%~dp0 :: 查询有没有安装过Mysql服务,安装过就不需要重复安装了。 @sc query mysql @if %errorlevel% EQU 0 @( @echo Mysql server exists @goto end ) @echo init mysql :: 安装Mysql 5.7 依赖于 C++ 环境 Redistributable 2013 @echo "Microsoft Visual C++ 2013 Redistributable Package Installation verification" @reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0\VC\Runtimes\x64" /v "Installed" @if %errorlevel% GTR 0 @( @goto call ) :verifyInstalled @for /f "skip=2 tokens=3" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\12.0\VC\Runtimes\x64" /v "
分数 10
全屏浏览题目
切换布局
作者 张庆
单位 集美大学
本题目要求编写SQL语句,
检索C002号课程的成绩最高的二人学号,姓名与成绩
提示:MSSQLServer 评测SQL语句。
表结构: 请在这里写定义表结构的SQL语句。例如:
-- 学生表 CREATE TABLE stu ( sno char(4) NOT NULL, sname nvarchar(8) NOT NULL, sex smallint DEFAULT NULL, mno char(2) DEFAULT NULL, birdate datetime DEFAULT NULL, memo ntext, PRIMARY KEY (sno) ); -- 学生选课成绩表 CREATE TABLE sc ( sno char(4) NOT NULL, -- 学生学号 cno char(4) NOT NULL, -- 课程号 grade decimal(4,1) DEFAULT NULL, PRIMARY KEY ( sno , cno ), CONSTRAINT fk_sc_sno FOREIGN KEY ( sno ) REFERENCES stu ( sno ) ) 表样例 请在这里给出上述表结构对应的表样例。例如
1、Echarts图表(一个基于JavaScript的开源可视化图表库)
Examples - Apache ECharts
它的功能非常强大,包含了各种样式的图表,在制作一些统计类网站时可以用到,能够将网站变得生动有趣,也可以高效率的多方面的展示数据。
各种折线图:
各种柱状图:
还有一些仪表盘等的显示:
或者是一些有趣的图形组件:
甚至还有3d图表:
更好的一点是,它是基于js开源的,也就是说,依照它给你的源代码,你可以根据自己需要,来将图表个性化。
有很多配置项可以选择
图表有不同样式风格的主题,也可以根据自己网站的主题,将图表定制成一系列主题。
作为一个以js为基础的图表,它的操作非常简单,只需要导入js文件,即可使用。在官网中,还有很多可供学习的资料,可以帮助你快速使用。
另外还有python版的echarts:pyecharts - A Python Echarts Plotting Library built with love.
可供python玩家使用,其基本功能都与echarts一致。我用的不多,就不献丑了,以后如果有深入使用,再补充这部分内容。
2、fontawesome图标库(一个CSS文件)
Font Awesome 中文网 – | 字体图标
如果你制作网页时遇到了找图标难、找到的不清晰等问题,就来看看这个网站吧,它提供了大量的图标,安装也十分简单,仅需在网页文件中导入一个CSS文件即可。
包含了网页图标、手势图标、计算图标、方向图标等等常用图标,一般网站制作从这里面找着用就足够了。另外它还提供了矢量版,供设计师们来使用。
3、Bootstrap 网格系统
Bootstrap 网格系统 | 菜鸟教程
Bootstrap 学前端的朋友们应该不陌生,我涉及不深,在此就不小巫见大巫的多加说明了,只是说一些对网格系统的个人使用体会。
以前刚接触前端时,什么都不懂,小米加步枪,仅用top、bottom、left、right来进行整个网页的布局。甚至还用了photoshop的切片工具,一个一个模块进行拼接,又费时又费力。后来接触了网格系统,这效率简直嗖嗖的,只需要设计相对位置即可,不再需要计算每个点的位置。网格系统还可以进行自适应,可以根据缩放或者设备实际屏幕尺寸大小,进行布局,达到无论怎么调整,都可以布满整个画面的效果。棒棒哒!如果有看到这里的入门小白,也要走我老路(找绝对位置)的朋友们,大家可以看看这个,事半功倍!
若依系统(一款基于SpringBoot+Bootstrap的极速后台开发框架) RuoYi 若依官方网站 |后台管理系统|权限管理系统|快速开发框架|企业管理系统|开源框架|微服务框架|前后端分离框架|开源后台系统|RuoYi|RuoYi-Vue|RuoYi-Cloud|RuoYi框架|RuoYi开源|RuoYi视频|若依视频|RuoYi开发文档|若依开发文档|Java开源框架|Java|SpringBoot|SrpingBoot2.0|SrpingCloud|Alibaba|MyBatis|Shiro|OAuth2.0|Thymeleaf|BootStrap|Vue|Element-UI||www.ruoyi.vip
以上介绍的所有,都是从这个系统延申出来的,也就是说,这个系统包含了之前提到过的api。
(以下从官网摘抄)
RuoYi 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Apache Shiro、MyBatis、Thymeleaf、Bootstrap),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、通知公告等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务。
主要特性
完全响应式布局(支持电脑、平板、手机等所有主流设备)强大的一键生成功能(包括控制器、模型、视图、菜单等)支持多数据源,简单配置即可实现切换。支持按钮及数据权限,可自定义部门数据权限。对常用js插件进行二次封装,使js代码变得简洁,更加易维护完善的XSS防范及脚本过滤,彻底杜绝XSS攻击Maven多项目依赖,模块及插件分项目,尽量松耦合,方便模块升级、增减模块。国际化支持,服务端及客户端支持完善的日志记录体系简单注解即可实现支持服务监控,数据监控,缓存监控功能。 技术选型
系统环境:Java EE 8、Servlet 3.0、Apache Maven 3
主框架:Spring Boot 2.2.x、Spring Framework 5.
目录
前言
1、数据表介绍
2、初始化(创建表并插入测试数据)
SQL习题
1、统计各科成绩>=70 de 人数:课程编号,课程名称, 人数及所占百分比
2、查询各科成绩前三名的记录
3、查询每门课程被选修的学生数
4、查询出只选修两门课程的学生学号和姓名
5、查询男生女生人数
6、查询名字中含有「风」字的学生信息
7、查询同名学生名单,并统计同名人数
8、查询 1990 年出生的学生名单
9、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
10、查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
11、查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
12、查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
13、查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
14、查询不及格的课程
15、查询课程编号为 01 且课程成绩在 80(含80) 分以上的学生的学号和姓名
16、求每门课程的学生人数
17、查询选修「张老师」所授课程的学生中,成绩最高的学生信息及其成绩
18、查询不同课程 但成绩相同的 学生的学生编号、课程编号、学生成绩
19、查询每门功课成绩最好的前两名
20、统计每门课程的学生选修人数(超过 5 人的课程才统计)
21、检索至少选修三门课程的学生的学生信息
24、按照出生日期来算
25、查询本周过生日的学生
实验小结
1、to_char(datetime/interval [, fmt]) 函数
2、获取系统当前的时间(日期)
3、TIMESTAMPDIFF 函数
4、age函数
5、EXTRACT函数
前言 数据库方向的研究和开发大致可以分为三个方向:一是数据库内核开发(自研等)、二是数据库系统管理(类似DBA的角色)、三是数据库应用开发(业务+SQL)。 内核开发可能需要有钻研创新的能力,比如一些数据库产品本身的自研工作等;DBA可能需要有系统架构、实施经验、以及整体管理的解决方案能力;应用开发则需要具有将业务快速转换成SQL的实现能力。所以说,以上三点纵贯“数据库的整个生命周期” 。
本文将在上一篇《SQL经典练习题(上)》 的基础上继续练习。 因为SQL的学习途径之一就是练习,俗话说,熟能生巧嘛!
1、数据表介绍 --学生表:Student(SId,Sname,Sage,Ssex) --SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别
打开磁盘管理对C盘进行压缩卷操作(可先清理磁盘并打开属性-工具,对驱动器进行碎片整理),出现可用压缩空间远小于可用空间的情况。
这是由于压缩卷只能压缩磁盘末尾未使用的空间,若在磁盘末尾出现文件时,便不能继续进行压缩操作。此时打开事件查看器选择左侧Windows日志中的应用程序,在此就能查看最后一个不可移动文件信息(可用右侧筛选文件功能,事件ID为259),显示“受保护的操作系统文件”后可以在文件资源管理器中看到。
因此若想获得更多的可压缩空间就需要将这些文件删除或移动至C盘更靠近首部的连续空间。以下为一些可能遇到的情况。
1. - 最后一个不可移动的文件显示为: \$Mft::$DATA
此文件一般为系统产生的MFT文件碎片,且不可删除。建议使用一些磁盘整理工具对其进行移动操作,此处推荐使用MyDefrag,免费且支持对Mft碎片的整理。
下载地址为:MyDefragGUI。
2. - 最后一个不可移动的文件显示为: \pagefile.sys::$DATA。
此文件为虚拟内存页面文件,一般不建议将其删除,但可以通过修改储存位置的方法将其移动到其他磁盘以腾出此处空间。方法为Win+X选择系统,进入高级系统设置-性能-设置-高级-虚拟内存-更改,取消“自动管理所有驱动器的分页文件大小”,选中C盘并改为“无分页文件”,点击设置,之后选中一个其他磁盘用作暂存此文件,改为“系统管理的大小”,点击设置,确认之后重启电脑,此时便可以继续压缩部分C盘空间。压缩完后回到上述页面,开启“自动管理所有驱动器的分页文件大小”便可将此文件移动回C盘。
3. - 最后一个不可移动的文件显示为: \hiberfil.sys::$DATA
此文件为电脑开启休眠模式后,内存文件保存在硬盘的具体位置,可以删除,但不能手动删除,只能通过关闭系统休眠模式来删除。关闭方法为:
以管理员权限打开Powershell,输入powercfg -h off,回车后系统会自动删除此文件。压缩卷后输入powercfg -h on重新打开休眠模式。
在公司和别人协同合作时,作为开发需要向架构或者负责人提交mr以合并代码,为了提高review效率,有些负责人会要求一个mr仅保留一条commit记录方便代码比对review的观看,但是开发常常是很多需求和bug混合着写,不可能每个分支都暂存一下去其他分支查看吧,因此总会多几条commit出来保存一下写完的代码。
常规可以用rebase去删除或者合并分支上的commit,但是咱rebase玩的不是很转等研究透了再发篇帖子记录一下。这里记录一种简易的方法去修改一个分支上的commit。
首先先将本地分支切换的需要合并的开发分支git checkout -b 新分支 基于开发分支新新建一个新分支git merge --squash 需要提交的分支 将提要提交的分支合并到当前的新分支中 squash的意思是,将合并分支所有的commit修改作用到合并分支中,不会保留仍和commit记录,此时新分支就有了之前分支的所有修改,提交一个新的commit即可达到合并commit的作用,然后将原来的分支删掉,将现在的分支名修改一下强制提交就可以覆盖原来的分支让mr更清爽~
如何制作生成GIF?在我们日常的工作或者沟通中,通常都会使用到GIF动图,一个好的动图可以为沟通增色不少。我们除了收藏别人制作好的动图之外,其实我们也可以将自己拍摄的视频或者日常的截屏制作成动图。这里小编就给大家带来好用的生成制作动图的方法。
如何制作生成GIF?
GIF是一种图片交互格式,它本质上还是属于图片的一种。那么我们在制作生成GIF的时候,首先就是需要准备好一段制作GIF的视频文件,然后在相应的系统中上传文件,系统会对文件进行分析处理,进而生成GIF格式。
具体操作步骤:
第一步 打开手机上的“书单视频助手”软件,咋软件的工具页面滑动找到“制作GIF”的操作,找到之后,点击上传提前准备好的视频文件。
第二步 上传好视频文件之后接下来就进入到制作页面,我们可以在视频的下方看到我们上传的视频文件的缩略图,点击选择一个合适的分辨率,点击完成即可。
第三步 点击完成之后,等待系统生成GIF动图,在弹出的完成页面中可以预览生成的动图,我们可以直接点击下方的按钮,将其保存到相册。
以上就是小编今天给大家分享的制作GIF的具体操作方法了,三步就可以完成。有想要制作自己的专属表情包的小伙伴们可以动手试一试哦!那么今天的分享就到这里啦,关注我给大家介绍更多的办公技巧。
👨🎓作者简介:一位喜欢写作,计科专业大三菜鸟
🏡个人主页:starry陆离
如果文章有帮到你的话记得点赞👍+收藏💗支持一下哦
Toolbar+DrawerLayout+NavigationView实现类似QQ侧边栏效果 1.自定义主题颜色2.使用Toolbar3.结合滑动菜单4.结合NavigationViewmenuheaderLayout 5.添加响应6.优化1:不遮挡菜单锚点7.总结8.参考资料 为什么默认的Android应用跑出来都是紫色的主题?
可在看到原来默认给我们设置了主题的颜色
Material Theme 可以定义为以下 3 种
Theme.Material(深色版本)Theme.Material.Light(浅色版本)Theme.Material.Light.DarkActionBar(浅色版本,深色 Action Bar) 1.自定义主题颜色 2.使用Toolbar ToolBar是Android 5.0推出的一个新的导航控件用于取代之前的ActionBar。
虽然这样看上去好像和ActionBar外观上没什么两样,不过是我们还没用到Material Design中的特性,Toolbar的强大之处在于它可和其它控件联动实现强大的效果,之后再慢慢体验。
3.结合滑动菜单 在Activity中添加一个事件唤出滑动控件
注意这里是android.R.id.home,它默认指代ToolBar左边的图标,这里默认有一个不会显示返回按钮,作用是返回上一个Activity。我们通过setDisplayHomeAsUpEnabled(true);方法将其显示,除此之外我还通过setHomeAsUpIndicator(R.drawable.ic_menu);修改了它的默认样式,ic_menu是我放在drawable文件夹下的一个png图片
然后为android.R.id.home添加响应,调用drawerLayout.openDrawer()方法将滑动菜单展示出来。其中的参数是指代滑出的方向,start是左边滑出
4.结合NavigationView NavigationView是应用程序的标准导航菜单。菜单内容可以通过菜单资源文件填充。导航视图通常放置在 .DrawerLayout搭配着一起使用
使用NavigationView之前先要准备menu和headerLayout
menu:显示具体的菜单项headerLayout:显示头部布局 menu checkableBehavior="single"指定group中的菜单项都只能单选
headerLayout 回到activity_main.xml中,用NavigationView替换掉原来的Button,其中的两个属性正是我们刚刚创建的资源
app:menu="@menu/nav_menu" app:headerLayout="@layout/nav_header" 稍作美化,这里用到了一个开源库
implementation 'de.hdodenhof:circleimageview:3.0.1' 5.添加响应 navView=findViewById(R.id.navView); // 添加NavigationView的事件监听 navView.setCheckedItem(R.id.navCall);//默认选中navCall子项 navView.setNavigationItemSelectedListener(item -> { //此处省略具体的逻辑操作 //用户在点击对应的菜单子项应该调用对应的逻辑代码,然后关闭滑动窗口 drawerLayout.closeDrawer(GravityCompat.START); return true; }); 6.优化1:不遮挡菜单锚点 设置toolbar的popup_theme属性中的overlapAnchor为false
<style name="popup_theme" parent="@style/Theme.MaterialComponents.Light"> <!--设置背景--> <item name="android:background">@android:color/white</item> <!--设置字体颜色--> <item name="android:textColor">@android:color/black</item> <!--设置不覆盖锚点--> <item name="overlapAnchor">false</item> </style> 记得在toolbar控件中使用这个样式
将你安装的proxy 或者是 createProxyMiddleware重新安装一遍 可能是因为 版本过低的原因重新 npm
npm install --save-dev proxy npm install --save-dev http-proxy-middleware
背景:
Linux的文件能否找到文件的创建时间取决于文件系统类型,在ext4之前的早期文件系统中(ext、ext2、ext3),文件的元数据不会记录文件的创建时间,它只会记录访问时间、修改时间、更改时间(状态更改时间)。
stat命令用于显示文件的状态信息。stat命令的输出信息比ls命令的输出信息要更详细。stat命令可以查看的信息包括:
File:显示文件名
Size:显示文件大小
Blocks:文件使用的数据块总数
IO Block:IO块大小
regular file:文件类型(常规文件)
Device:设备编号
Inode:Inode号
Links:链接数
Access:文件的权限
Gid、Uid:文件所有权的Gid和Uid
access time:表示我们最后一次访问(仅仅是访问,没有改动)文件的时间
modify time:表示我们最后一次修改文件的时间
change time:表示我们最后一次对文件属性改变的时间,包括权限,大小,属性等等
Birth time : 文件创建时间,crtime,不过据查此属性linux已废弃,目前状态显示结果均为-
1、获取文件inode号
stat filename 2、查找文件所在的磁盘路径
df -h 3、使用debugfs查看文件的创建时间
debugfs -R 'stat <4980825>' /dev/vdb1
java-并发编程
Kali 安装软件失败后,无法进入桌面系统 在给自己的Kali安装一个虚拟机软件,重启后黑屏,只能输入命令~
之后安装软件只会出现 dpkg@@@@@@(菱形块乱码) sudo dpkg --configure -a@@@@
网上搜索后,觉得应该是
dpkg 被中断,您必须手工运行 sudo dpkg --configure -a解决此问题
在百度上找了一些解决方法,可还是没有搞定,最后在Ubuntu的论坛里面找到了解决方法。
dpkg 被中断,您必须手工运行 sudo dpkg --configure -a解决此问题
运行下面的命令即可解决
sudo rm /var/lib/dpkg/updates/*
sudo apt-get update
sudo apt-get upgrade
主要原因应该是/var/lib/dpkg/updates 文件夹里面的资料有错误,使得更新软件的程序出现错误,所以得把它们完全删除,通过sudo apt-get update这个指令会重新建立这些资料,使用sudo apt-get upgrade更新你的电脑里面已安装的软件的明细,根据软件的明细更新软件到最新版。
功能快捷键 撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
一、Maven的详解 What is Maven? Maven是一个项目管理工具,它包含了一个项目对象模型,一组标准集合,一个项目生命周期,一个依赖管理系统,和用来运行定义在生命周期中插件目标的逻辑。Maven的核心功能合理叙述项目间的依赖关系。
如今,我们在构建一个Java的Web项目时,就要导入大量的jar包。一个项目的jar包数量就很多很多,而且每个jar包之间的关系就错综复杂,每一个jar包又不能缺少,一旦缺少一个jar包就会导致整个项目无法编译成功。因此,在开发项目的过程中,若是通过程序员手动的方式引入jar包,就会导致程序员在引入jar包这一块配置中就耗费大量的精力和时间,使得整个开发效率变低。
而Maven的出现大大方便了程序员构建项目,程序员只需要在Maven中的pom.xml配置文件中,告诉它要导入哪儿些jar包,Maven就会自动帮助我们下载并导入所有需要的jar包,大大提高了开发项目的效率。
Maven生命周期 Maven构建项目生命周期的描述是一次构建过程经历了多少个事件Maven对项目创建的生命周期划分为3套 -->clean:清理工作-->default:核心工作,例如编译,测试,打包,安装等-->site:产生报告,发布站点等 同一套生命周期内,执行后边的命令,前边的所有命令会自动执行。
Maven的目录结构 main文件夹:
java:存放项目的源代码
resources:存放项目资源文件
test文件夹:
java:存放单元测试源代码
resources:存放单元测试资源文件
target文件夹:存放打包产生后的文件
pom.xml:maven项目中的配置文件
Maven的常用命令 1、mvn -v 用于查看maven是否安装成功,并且可以查看maven的版本号信息。
2、mvn install 将项目安装到本地的仓库中,提供给别的项目使用。
3、mvn clean 发现在安装过程中出问题时,可以利用这个命令先清除干净,再进行重新安装。若项目已经经过打包处理,会清理掉target文件夹。
4、mvn compile 进行编译,将java源文件编译成class文件
5、mvn test 执行test目录下的测试案例
6、mvn package 将项目打包成一个jar包,方便使用,并且生成target目录。打包的过程中,就相当于将前面的编译测试都执行力一遍。
7、mvn run 启动服务
Maven仓库 Maven的仓库用来存放Maven管理的jar包,又分为本地仓库,中央仓库和远程仓库。
本地仓库:存放Maven本地管理的一些jar包。中央仓库:由Maven团队维护的全球唯一的仓库,地址为:https://repo1.maven.org/maven2/远程仓库:又称私服。一般由公司团队搭建的私有仓库。 一般先将中央仓库中存放的jar包下载导入到本地仓库中,这样子可以在用到本地仓库中提供的jar包时,导入速度快,效率高。
当项目中使用坐标引入对应依赖jar包后,首先会查找本地仓库中是否有对应的jar包。如果有,则在项目中直接引用;如果没有,则去中央仓库下载对应的jar包到本地仓库。还可以搭建远程仓库。jar包的查找顺序为:本地仓库->远程仓库->中央仓库
Maven的坐标 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.32</version> </dependency> 每个jar包在Maven都有它独一无二的坐标,Maven仓库通过坐标找到对应的jar包。如上述代码,就是mysql的jar包对应的一个坐标。
groupId:jar包的项目名称artifactId:jar包的模块名version:jar包的版本号 Maven坐标的依赖范围 通过设置坐标的依赖范围(scope),可以设置对应jar包的作用范围分为3个:编译环境、测试环境 <scope>test</scope> <scope> 默认值:compile 二、Maven的配置与安装 1、安装本地的Maven 选择你需要的maven版本下载:Maven – Download Apache Maven
二、下载安装 把下载好的Maven压缩包解压到一个不含中文,空格或者特殊字符的文件夹中。
在ZYNQ7010上跑littleVGL。
前一段时间想移植LittleVGL到ZYNQ7010开发板上,参考正点原子移植到STM32的教程,搞了三四天也没搞定。于是,又试了B站上一个老哥的开源LVGL7.0.2+ZYNQ7010。他的这个是可以的,但是我想搞个中文字体。这个版本(7.0.2)的相关接口我不会用,网上也找不到这个版本关于中文字体的教程。于是,就在这个老哥开源工程的基础上,又瞎改了移植成功了LittleVGL6.0那个版本(和正点原子教程一样的那个)。
具体原理还没研究明白,反正是可以用了。
PL端还是B站老哥的工程,PS是在老哥的基础上移植LittleVGL6.0库。
下面简述移植过程:
开发板:正点原子领航者ZYNQ7010
显示屏:ALIENTEK 7寸 RGB TFTLCD
参考工程:来源B站up 涛哥哥Plus 开源
软件版本:Vivado2018.3
1.在vivado更改硬件引脚定义
2. 移植LittleVGL6.0库(正点原子教程版本)
2.1驱动文件用B站老哥那个
2.2 lv_conf.h里要改的除了教程里的那些外,还有下面这个地方
2.3如果有#include"../xx/xx.h"文件编译出错,修改为相对路径即可。
3. 移植完成后,即可参考正点原子教程编写自己的LittleVGL代码。
总结:有开源的我绝不自己移植,太痛苦了,不懂原理在那瞎搞也学不到东西。
其他的细节记不清晰了,如果需要移植完的工程,评论私信都可。
本文用到的美国房屋数据,数据介绍详见我的上一篇文章:
链接:https://pan.baidu.com/s/1wrkzFF87A_Emgid_s7K3aA
提取码:2j77 内含两个文件:
data_train.csv:训练集数据,包含房价等81个指标;
data_test.csv:测试集数据,不包含房价;
文章目录 前言
一、数据预处理
1. 删除异常值
2. 填补缺失值
3. 转换数据类型
4. 建立值与类别的映射 二、对房价进行正态分布化处理:
第一步:在原数据的柱状图上添加正态分布概率密度曲线和核密度估计曲线;
第二步:对房价进行正态分布化处理;
第三步:添加一列总面积并计算偏度;
第四步:随后对偏度大的列数据进行BOX-COX转换,改善数据的正态性和对称性;
第五步:对数据进行独热编码;
三、使用多个回归预测算法进行房价预测
1. 导入包和数据
2. 定义模型
3. 定义训练数据和计算模型均方根误差的方法
4. 通过均方误差评估各模型效果
5. 模型应用(预测)
前言 紧接上一篇文章,本文针对数据进行了正态化处理,应用了Lasso、KernelRidge、ElasticNet、GradientBoostingRegressor、XGBRegressor等回归模型进行房价预测。
数据长这样,数据集的具体解释和分析详见我的上一篇文章:
一、数据预处理
导入包:
#不显示警告 import warnings warnings.filterwarnings('ignore') #数据处理,数据分析 import numpy as np import pandas as pd #统计计算相关的工具包 import math from scipy import stats from scipy.stats import norm #画图相关的工具包 import seaborn import matplotlib.pyplot as plt from matplotlib.
<script type="text/javascript" src="/js/crypto-js.min.js"></script> crypto-js.min.js
!function(t, e) { "object" == typeof exports ? module.exports = exports = e() : "function" == typeof define && define.amd ? define([], e) : t.CryptoJS = e() }(this, function() { var n, o, s, a, h, t, e, l, r, i, c, f, d, u, p, S, x, b, A, H, z, _, v, g, y, B, w, k, m, C, D, E, R, M, F, P, W, O, I, U = U || function(h) { var i; if ("
Homebrew 是 MacOS 的一个流行的软件包管理器。可从 Homebrew 的仓库中安装RabbitMQ 。
首先,确保你已经安装了Homebrew。在终端上,运行
brew --version 1 安装 用以下方法安装 RabbitMQ 服务器:
brew install rabbitmq Homebrew会自动安装 RabbitMQ相关的关键依赖包,比如:Erlang。
2 RabbitMQ服务 也可以使用 launchd 在后台启动RabbitMQ进程,这样macOS启动时候就可以自动启动RabbitMQ服务:
brew services start rabbitmq 你可以通过运行以下内容来检查 launchd 管理的 RabbitMQ 的状态:
brew services info rabbitmq 要停止该服务,请运行:
brew services stop rabbitmq 3 连接到RabbitMQ 打开浏览器访问地址:http://localhost:15672/
输入默认用户名gueat和密码guest,就可以登录到RabbitMQ。
4 配置环境变量PATH 如果为了方便使用,需要配置环境变量,M1 芯片的MacOS和Intel芯片的MacOS略有不同:
M1芯片MacOS:
test -r ~/.bash_profile && echo 'export PATH=$PATH:/opt/homebrew/opt/rabbitmq/sbin' >> ~/.bash_profile test -r ~/.zprofile && echo 'export PATH=$PATH:/opt/homebrew/opt/rabbitmq/sbin' >> ~/.
格式说明重要度 %C
除以100并截断为整数(00-99)
%j一年中的一天 (001-366)%n换行符%t水平制表符%pAM或PM指定%Q季度(1-4)%d月中的一天,零填充(01-31)√%e月中的一天,空格填充( 1-31)%m月份为十进制数(01-12)√%y年份,最后两位数字(00-99)√%Y年份%D相当于%m/%d/%y%F相当于%Y-%m-%d√√√%H24小时格式(00-23)√%I12小时格式(01-12)%M分钟(00-59)√%R相当于%H:%M√√%S秒 (00-59)√%T相当于%H:%M:%S√√√%u工作日,周日为7(1-7)%w工作日,周日为0(0-6) 示例 select * from ( select formatDateTime(now(),'%Y') value , 1 num union all select formatDateTime(now(),'%m') vlaue,2 num union all select formatDateTime(now(),'%d') vlaue,3 num union all select formatDateTime(now(),'%H') vlaue,4 num union all select formatDateTime(now(),'%M') vlaue,5 num union all select formatDateTime(now(),'%S') vlaue,6 num union all select formatDateTime(now(),'%Y-%m-%d') vlaue,7 num union all select formatDateTime(now(),'%F') vlaue,8 num union all select formatDateTime(now(),'%H:%M:%S') vlaue,9 num union all select formatDateTime(now(),'%R') vlaue,11 num union all select formatDateTime(now(),'%T') vlaue,12 num union all select formatDateTime(now(),'%F %T') vlaue,13 num ) t order by num asc;
正确打开的页面是上面这样的,我来说说我遇到的一些问题:
1.首先我执行npm run dev时候出现了下面这些error:
2.后来听同学说是我下载的nodejs版本太低的问题,于是我下载了一个更高的版本,后来运行是这样的:
3.最后我是如何解决的,我删除了renrenfast-vue中的node_moudle
然后记得删除C:\Users\86189\AppData\Roaming里面的npm和npm-cache
但是我的npm-cache在C:\Users\86189\AppData\Local里面,下面附上图片
删除了之后并不代表你删除完了!!!
执行指令:npm install -g cnpm,这条指令执行出来就是删除完成了,接下来再进行正常的下载安装即可,下面这个是我相关的版本:查看自己的方法:win+R输入cmd并输入命令:cnmp -v
以下为下载安装的相关代码命令:
npm install cnpm@7.1.0 -g --registry=https://registry.npm.taobao.org
cnpm install
npm run dev
这是我遇到的问题以及解决方法,报错的时候很难受,饭不香睡不好就连做梦都是报错,幸亏最后解决啦,用文章的方式激励自己的这次错误,如果我哪里写错了,也希望大家指教,祝大家都能解决掉错误。
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
Release Train Version: Hoxton.SR12 Supported Boot Version: 2.3.12.RELEASE 毕业版本依赖关系(推荐使用) 由于 Spring Boot 2.4+ 和以下版本之间变化较大,目前企业级客户老项目相关 Spring Boot 版本仍停留在 Spring Boot 2.4 以下,为了同时满足存量用户和新用户不同需求,社区以 Spring Boot 2.4 为分界线,同时维护 2.2.x 和 2021.x 两个分支迭代。
2021.x 分支 适配 Spring Boot 2.4,Spring Cloud 2021.x 版本及以上的 Spring Cloud Alibaba 版本按从新到旧排列如下表(最新版本用*标记): (注意,该分支 Spring Cloud Alibaba 版本命名方式进行了调整,未来将对应 Spring Cloud 版本,前三位为 Spring Cloud 版本,最后一位为扩展版本,比如适配 Spring Cloud 2021.0.1 版本对应的 Spring Cloud Alibaba 第一个版本为:2021.0.1.0,第个二版本为:2021.0.1.1,依此类推)
Spring Cloud Alibaba VersionSpring Cloud VersionSpring Boot Version2021.
北斗/RTK高精度定位系统能提供厘米级/毫米级高精度位置服务,逐渐成为智能社会高精度定位的趋势和理想选择。
北斗/RTK高精度定位系统的出现是信息化时代发展的产物。从移动互联到物联网,位置是一个基础的不可或缺的信息,但是从精细化的行业应用需求来说,只有更高精度的定位信息才能带来更高的价值。目前常用的人员定位技术有ZigBee、RFID、蓝牙、WiFi、GPS等,其中又以北斗/RTK高精度定位技术最为突出,本文主要讲北斗/RTK高精度定位系统的优势及其适用场景。
北斗/RTK高精度定位系统 北斗/RTK高精度定位系统由四大部分构成,即固定不动的基准站部分、负责数据处理的控制中心部分、负责数据通信的线路部分以及接受信息的用户部分。这四部分中,数据的处理承担着最为重要的角色,对数据的传输和接收起到了非常重要的作用。数据处理中心和基准站以及流动站之间通过数据通信线路进行联系,通信线路可以为有线线路或无线链接。
北斗/RTK技术实现精准定位的过程 首先,确定基准站的个数及设定位置,再以设定的基准站作为数据处理的基础来计算定位的准确度,然后将误差改正数据发送给系统,最后,由用户部分对得到的定位信息进行实时的误差改正,并获得准确的定位信息。该技术中涉及差分定位技术,使用北斗双频接收机,通过同步观测法得以实现。它的测量中间站间距的有效距离最大可达到上百千米,定位精度可达到厘米级,已具备非常高的定位准确度。另外,该技术智能程度高、使用范围广、效率高、费用低,并且还能大大减弱由诸多原因引起的系统误差。
北斗/RTK高精度定位系统的优势 01、定位精度高
只要满足RTK的基本工作条件,在一定的作业半径范围内(一般为4km),RTK的平面精度和高程精度都能达到厘米级,完全可以满足一般工程测量的精度。一体化差分接收机同时接收多系统多频率信号,全面支持北斗三号卫星新信号体制,支持RTCM3.x 原始观测量输出、毫米级GNSS解算精度、RTK算法,定位精度高,数据安全可靠,没有误差积累。
02、作业效率高
在定位的过程中,对于20km以内的静态定位,只需要约20分钟;在对快速静态相对定位测量的过程中,流动站与基准站间距为15km以内的情况下,流动站观测时间大约为两分钟,并且在此基础上还能够进行一次定位,其定位时间只需要几秒钟时间,定位速度较快,作业效率高。
03、灵活度更高
8通道并发设计(我司为国内唯一一家突破此技术的公司),卡容量更大,系统更强大;同时,软件同步支持公有云、私有云、混合云、本地化,各种环境均可轻松应对。
随着技术的发展与创新,各种定位手段在精度方面都在不断进步,不仅为高精度定位的实现提供了基础,同时也让用户对定位精度提出了更高的要求。如今,普通的北斗、GPS等卫星定位手段,精度几米到十多米,已经不足以满足很多特殊场景的应用需求,亚米级定位正在悄然普及。
北斗/RTK适用场景 一、港口、货场、工地、石化等场景人员高精度定位需求
随着经济的快速发展和竞争的日益激烈,港口、货场、工地、石化等区域规模日益扩大,厂区面积广阔、环境复杂、作业人员和车辆众多,由于管理不科学、不完善等诸多原因,极易发生重大安全生产事故。如存在无法掌握工作人员及外来人员的位置、外来车辆在厂区内长时间逗留存在安全隐患等问题。
我司自主研发的人员、车辆RTK防爆定位工卡,可实时、准确地掌握人车位置和分布情况,通过加强对工作或来访人员、车辆的管控,可减少甚至杜绝重大事故发生,在危险事故中提升脱险或者救援的效率,极大提升厂区的安全、智慧管理水平,也有助于精细化生产过程管控,进一步提高生产效率。
解决方案 针对港口、货场、工地、石化等场景开发的人员、车辆RTK防爆定位工卡,在普通卫星导航定位技术基础上,使用了能接收差分/RTK数据的高精度卫导芯片,在使用区域内选取合适位置部署RTK参考基站或者使用RTK服务,定位工卡通过4G网络接收差分数据(RTCM数据),结合接收的卫星信号解算输出高精度定位结果。定位工卡采用高集成度芯片、低功耗算法以及卡片式设计,小巧实用、操作简便、功耗较低,可实现SOS一键报警、低电量报警、电子围栏报警、剩余电量指示等功能,可扩展支持RFID打卡、蓝牙室内定位等功能,产品防水、防尘、防爆,提供详细、可定制的数据协议。
功能及特点 1、工卡内置BDS/GPS双系统厘米级导航定位模块,支持接收、解算差分数据,定位精度优于普通卫导定位;
2、RTK参考基站部署方便、使用外接电源供电,外形小巧、结构坚固、覆盖广,覆盖半径可达10公里;
3、工卡和RTK参考基站间使用4G网络通信,覆盖广、数据延迟低;
4、可输出人员、车辆的位置、速度、运动姿态以及工卡电量等信息,实现剩余电量指示、SOS一键报警、低电量报警、电子围栏报警等功能,可扩展支持RFID打卡、蓝牙室内定位功能;
5、采用高集成度芯片、低功耗算法以及超薄卡片式设计,小巧实用、操作简便,产品防水、防尘、防爆,可定制为安全帽、头盔形态
6、提供详细、可定制的数据协议。
软件功能 1.实时定位 实时位置、动态、分布热力图皆可随时获知,便于管理人员及时掌握相关信息,确保人员安全。
2.历史轨迹 此功能可用于追踪人员历史位置记录和每个时间段的行为轨迹。管理人员通过输入人员姓名/ID、起止时间进行相关位置信息的查询,可查看其行走路线、在某区域停留时长等数据,有助于管理者对人员活动状态进行监控,完善管理体系。
3.电子围栏 在危险或重要区域设置电子围栏,人员未经授权进入该区域或者超时滞留、人员长时间静止不动,系统会立即报警(可实现越界报警、超时滞留报警、静止告警),提醒管理人员关注,防止发生意外安全事故。通过电子围栏可防止外来人员进入危险区域,实现越界告警、滞留告警,减少人力管理成本。
4.一键报警 一旦人员遇到危险或者需要援助,可使用随身佩戴的定位终端进行一键求助,后台将展示求救人员的基本信息与所在位置,管理人员可依据求助位置进行救援,提高抢险救灾、安全救护的效率。
5.统计分析 可进行全面数据统计,图表化直观呈现。查看区域累计人数、当前实时人员及设备数量、热力分布、实时围栏状况等信息,经大数据分析后,可以用以优化管理,提高管理效率,实现数字化管理。
ECharts如何自定义省、市、县区地图(各省市直辖区的map地图),ECharts如何在地图上自定义图片、图标,根据经纬度显示自定义建筑图片、添加自定义覆盖物 前言 最近在做一个项目中,需求是:要显示中国某个省份下,某个市的地图,而地图还要有块级效果,自定义地图颜色,还要在地图上显示不同的建筑物图片,还要每隔几秒后(数据是从后端用ws实时推送过来的,要根据推送过来的数据,动态切换显示对应建筑物的相关信息)。
之前Echarts我也用得挺多的,但是没做过要在地图上显示自定义图片,因为echarts的地图用canvas渲染出来的,而且自定义的图片位置是要根据要求出显示,还要不间断来回切换显示。
刚开始有点懵,在网上一阵狂搜,然而结果并无卵用,都是参差不齐,最多显示一个小圆点之类的,更没什么实例代码。所以,那两天就有点头大,看Echarts官网也不知从那里看起。
最后,还是搞定了,相信在当你看到这篇文章之前,你和我之前的感受应该差不多,都有点头大吧!哈哈,开个玩笑哈!!
好吧,话就说到这里,先来看一下效果图:这里以贵州遵义为例!!
这是中国地图数据图形:
怎么样?
和你现在的项目需求差不多吗,哈哈,又浪了一下?现在来看看实现代码吧!
代码 HTML用来渲染地图用的,宽度和高度自己定义,我这里是以1440 * 916 为例。
<div id="map-box" style="width:1440px; height:916px"></div> CSS用于在地图上自动切换时,显示建筑地址及相关信息的样式。
body{background:url(../img/body-bg.jpg) no-repeat;background-size:cover;} .map-box{border:1px solid #fff;} #map-box{margin:auto;} .map-hover-box{position:relative;margin-top:-160px;padding:12px 16px;min-width:200px;border-radius:20px 0 20px 0;background:rgba(11,21,50,.8);box-shadow:0 0 12px 1px #ec7d0f;word-wrap:break-word;} .map-hover-box::before{position:absolute;top:-1px;right:-1px;width:73px;height:38px;background:url(../img/map-href-rt.png) no-repeat;background-size:contain;content:"";} .map-hover-box::after{position:absolute;bottom:-1px;left:-1px;width:73px;height:38px;background:url(../img/map-href-lb.png) no-repeat;background-size:contain;content:"";} .map-hover-box h3{font-size:18px;} .map-hover-box p{padding-top:12px;font-size:16px;} .map-hover-box i{position:absolute;bottom:-108px;left:-75px;display:block;width:100px;height:108px;background:url(../img/map-href-zb.png) no-repeat;background-size:contain;} JavaScript 引用文件
//echarts.min.js 这个就不用说了 <script src="./js/echarts.min.js"></script> //zunyi.js 是指定让echarts显示的地图(这里是贵州省 遵义市 的地图数据) <script src="./js/zunyi.js"></script> //zunyi-data.js 是要在地图上显示的内容(建筑地址、名称、图片、经纬度等,这里一般是从后端传过来的,这里是演示用的哈!!) <script src="./js/zunyi-data.js"></script> zunyi-data.js 数据结构如下: const zunyiData = [ { "
系列文章目录 文章目录 系列文章目录springmvc注解的使用@RequestMapping@PathVariable@RequestParam@RequestHeader@CookieValue@SessionAttribute@ModelAttribute方法上参数上 springmvc注解的使用 原文链接 https://zhhll.icu/2021/框架/springmvc/基础/7.springmvc注解的使用/
@RequestMapping 地址映射,可以用在类和方法上
@PathVariable 基于REST风格的API,可以在URI地址上拼接参数
如:get/{id}
@PathVariable中的value值要设置为和地址栏中一致,如@PathVariable(“id”)
@RequestParam 可以接收拼接在地址栏中的参数
如: get?id=1&name=张三
@RequestParam("id") int id,@RequestParam("name") String name @RequestHeader 可以获取请求头参数
@CookieValue 可以绑定请求中的cookie值
@CookieValue(“JSESSIONID”) String sessionId
@SessionAttribute 默认情况下Spring MVC将模型中的数据存储到request域中,当一个请求结束后,数据就失效了,如果要跨页面使用,那么需要使用到session,而@SessionAttributes注解就可以使得模型中的数据存储一份到session域中
@ModelAttribute 可以放到方法上或者参数上,它将方法参数或方法返回值绑定到命名中的Model属性中,然后将其公开给Web视图。如果我们在方法级别使用它,则表明该方法的目的是添加一个或多个模型属性。另一方面,当用作方法参数时,它表示应从模型中检索参数。如果不存在,我们应该首先实例化它,然后将其添加到Model中。一旦出现在模型中,我们应该填充所有具有匹配名称的请求参数的参数字段
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ModelAttribute 方法上 标记在方法上,会在每一个@RequestMapping标注的方法前执行,如果有返回值,则自动将该返回值加入到ModelMap中
@ModelAttribute public void before(@RequestParam("id") String id, Model model){ // 方法返回值为void,所以需要手动添加到model中 model.addAttribute("id",id); } @ModelAttribute("name") public String beforeWith(@RequestParam("name") String name, Model model){ // 将返回结果放入到model中 return name; } @RequestMapping("/modelAttributeTest") public String test(Model model){ Map<String, Object> stringObjectMap = model.
前言 最近在公司的一个WebH5项目中,有个生成二维码 和 识别二维码的需求(要脱离微信环境、微信JS-SDK,微信小程序、微信受权,[就是可以在普通的浏览器中运行]),要求可以在PC端、移动端。
关于二维码生成:相信大家做过,直接用的 qrcode.js、vue-qr 等前端库就可以实现比较简单。
关于二维码识别:之前都是在微信环境中开发的,一旦脱离微信环境就用不了,所以现在正好项目有这个需求,经过一翻折腾实现了在PC端,移动端的二维码识别解析功能。
该Demo功能共分为:HTML版 和 Vue版 两个版本,可满足在不同的项目需求场景中使用,Demo原代码已推到GitHub上了,有需要的小伙伴可以看看。
纯前端 HTML / Vue :二维码:生成、扫描、识别、解析、扫一扫 该Demo功能共分为:HTML版 和 Vue版 两个版本!
不依赖任何关于微信环境、微信JS-SDK,微信小程序、微信受权等!
支持二维码生成,实时动态生成和渲染!
支持扫一扫识别,从相册选择二维码识别!
支持PC端,手机移动端等!
HTML版 Demo实例效果: Vue.js版 实例效果: 实例效果 Demo:https://demo.muguilin.com/二维码生成与识别
实例代码 GitHub:https://github.com/MuGuiLin/QRCode
项目运行
环境配置:
Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。
项目技术:
SSM + mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;
5.是否Maven项目: 否;查看源码目录中是否包含pom.xml;若包含,则为maven项目,否则为非maven项目 6.数据库:MySql 5.7/8.0等版本均可;
毕设帮助,指导,本源码分享,调试部署(见文末)
3.1可行性分析 在开发系统之前要进行系统可行性分析,目的是在用最简单的方法去解决最大的问题,程序一旦开发出来满足了用户的需要,所带来的利益也很多。下面我们将从技术、操作、经济等方面来选择这个系统最终是否开发。
3.1.1技术可行性 本系统开发选择java技术,java是一个完全面向对象的语言,java为开发者提供了丰富的类库,大大减少了使用windows编程的难度,减少开发人员在设计算法上的难度,作为java开发 Visual Studio更是一个必不可少的角色,它友好的界面,以及强大的功能,给程序开发人员带来了很多方便,加上环境简单,转移方便,无疑使此系统最佳的选择。所以后台设计选择使用MySQL数据库主要用来的建立和维护信息。对于前台开发要求应具备功能完善、易于操作等优点,后台数据库的要求则是能够建立和维护数据信息的统一性和完整性。
依据上述目标来分析本系统的硬件如下:
奔腾3的处理器;
内存是 2G;
硬盘是50G;
操作系统是Window 10;
在软件方面的话,安装了Visul Studio 0 和MySQL数据库开发工具。根据以上的软件与硬件要求,得到这个系统的技术是可行的。
3.1.2经济可行性 基于ssm的开放式实验室预约系统,该系统软件开发仅需要一台普通的计算机便可完成实现开发,其成本很低。另外,作为毕业设计作品来讲,开发成本基本上可以忽略不计,且该系统软件的投入使用,可以实现更加快速高效的开放式实验室预约系统,同时还能实现对人力资源和管理资源的有效节约,该开放式实验室预约系统在经济上完全可行。
3.1.3操作可行性 现在随着科技的飞速发展,计算机早已经进入了人们的日常生活中,人们的工作环境也不像以前有那么多的要求,需要员工一定要到公司办公,有的工作在家也可以完成。这使得人们的工作效益有了很大的提高。操作的多样性也变高了。因此,管理的计算机化,智能化是社会发展而带来的必然趋势,各种智能的软件层出不穷,不同的软件能完成用户不同的需求,这不仅提高了工作效率还能完成一些客户特定的一些需求。本系统不仅界面简洁明了还采用可视化界面,用户只要用鼠标和键盘就可以完成对相关信息的修改,删除,添加等操作。因为这个系统的操作十分简单,方便上手,对于第一次使用系统的人,只需要很少的时间就可以上手操作。由此可见,本系统在操作上是可行的。
3.2系统性能需求分析 对系统性能进行分析,可对系统反应度、界面简洁清晰度、储存能性、易学性和稳定性进行分析;
系统反应度:同时上万人在线时反应时间应该在两三秒以内,。
界面简洁清晰:系统界面要求简单明了,操作简单,用户操作容易上手。
储存性能高:开放式实验室中需要存储的信息有很多,所以对系统的存储量要求很高,因此数据库就应该很强大,才能保证信息能安全稳定的进行存储;
易学性:该系统在操作上必须简单好上手,没有很多复杂的操作,只需要简单的进行学习就能操作该系统。
稳定性:要求开放式实验室预约运行要稳定,界面清楚、字体清晰等。
3.3系统功能分析 考虑到实际生活中在开放式实验室预约方面的需要以及对该系统认真的分析,将系统权限按管理员和用户这两类涉及用户划分。
项目运行
环境配置:
Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。
项目技术:
SSM + mybatis + Maven + Vue 等等组成,B/S模式 + Maven管理等等。
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;
5.是否Maven项目: 否;查看源码目录中是否包含pom.xml;若包含,则为maven项目,否则为非maven项目 6.数据库:MySql 5.7/8.0等版本均可;
毕设帮助,指导,本源码分享,调试部署(见文末)
3.2业务流程分析 按照设计过程中信息的流动,业务流程分析时则需要全面的检查每一个的环节。本设计互联网在线笔记管理系统的业务流程分析图如图3-1所示。
图3-1业务流程图
3.3数据流图 下面是管理员对添加用户流程如图3-2所示:
图3-2用户添加流程图
管理员添加笔记信息流程图如图3-3所示:
图3-3添加笔记信息流程图
互联网在线笔记管理系统功能模块的结构图,如图4-1所示:
图4-1互联网在线笔记管理系统结构图
4.2数据库设计 4.2.1概念结构设计 根据分析系统的数据需求,得到系统的实体属性图。
(1)回收站信息E-R图,如图4-2所示:
图4-2回收站信息E-R图
(2)笔记本信息E-R图,如图4-3所示:
图4-3笔记本信息E-R图
(3)用户信息E-R图,如图4-4所示:
图4-4用户信息E-R图
(4)笔记信息E-R图,如图4-5所示:
图4-5笔记信息E-R图
5.1用户功能模块 用户登录进入互联网在线笔记管理系统可以查看首页、个人中心、笔记本信息管理、笔记信息管理、回收站管理等内容,如图5-1所示。
图5-1用户功能界面图
个人中心:用户通过自己的个人中心,可进行密码修改,也可对个人信息进行编辑账号、姓名、性别、手机、地址、头像等内容,进行修改操作,如图5-2所示。
图5-2个人中心界面图
笔记本信息管理:用户通过笔记本信息管理页面可以查看笔记本名称、笔记本分类、创建时间、笔记本封面、账号等内容,进行详情、修改、删除等操作,如图5-3所示。
图5-3笔记本信息管理界面图
笔记信息管理:用户通过笔记信息管理页面查看笔记本名称、笔记本分类、笔记名称、发布时间、笔记图片、账号等内容,进行修改、删除等操作,如图5-4所示。
图5-4笔记信息管理界面图
项目场景: 使用 System.Text.Encoding.Default.GetString (参数1)时,传入的参数1未填满空间大小,后面仍需添加字符串或字符。
问题描述 当参数1未填满空间, System.Text.Encoding.Default.GetString (参数1)后面添加任意字符都不生效,如:
byte[] temp = new byte[7]; temp[0] = (byte)'a'; temp[1] = (byte)'b'; temp[2] = (byte)'c'; temp[3] = (byte)'A'; temp[4] = (byte)'B'; temp[5] = (byte)'C'; string anyStr = "任意字符"; string result = System.Text.Encoding.Default.GetString(temp) + anyStr; 结构 result 的输出都不包含字符串 anyStr 。
原因分析: 当 temp 设置的长度且未填满时, System.Text.Encoding.Default.GetString() 会在生成的字符串之后添加 “\0” 结束符,此时再添加任何字符串或者字符都是无效的。
解决方案: 总结了以下几个方法:
将参数1 temp 的长度全部填满 byte[] temp = new byte[6]; temp[0] = (byte)'a'; temp[1] = (byte)'b'; temp[2] = (byte)'c'; temp[3] = (byte)'A'; temp[4] = (byte)'B'; temp[5] = (byte)'C'; string anyStr = "
目录 时间概述Linux 中两个时钟date --> 系统时钟hwclock --> 硬件时钟 如何查看和设置时区查看时区设置时区tzselect timedatectl cal 日期 时间概述 如何表示时间其实是一个比较复杂的问题,因为在地球环绕太阳旋转的24小时中,世界各地日出日落的时间是不同的,因此有划分时区(timezone)的必要,也就是把全球划分成24个不同的时区。我们可以把时间的定义理解为一个时间的值加上所在地的时区值(注意这个所在地可以精确到城市)。
在地理课上,我们学过格林威治时间(GMT),它就是 0 时区时间。但是我们在计算机中经常看到的是 UTC(Coordinated Universal Time 的简写,协调世界时,又称世界统一时间、世界标准时间、国际协调时间),UTC 是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,使UTC与地球自转周期一致。所以 UTC 的本质强调的是比GMT更为精确的世界时间标准。
如果中国当地时间是晚上8点钟整,我们可以使用以下两种表示方式:
20:00 CST #或 12:00 UTC 这里的 CST 是 Chinse Standard Time(中国标准时间),也就是我们通常所说的北京时间了。因为中国处在 UTC+8 时区,即所谓的东 8 区,从而推断 UTC 为 12:00了。
虽然电脑中可以显示不同的时区的时间,其实电脑中只保留了一个时间值,那就是 UTC+0 的时间,想要得到不同时区的时间,只能通过设置不同的时区来获得。另外,还有一个称为夏令时 DST 概念,那是因为夏季太阳出来早,为了充分利用阳光,把时间拨快一定时间,到秋天拨慢回时间。
Linux 中两个时钟 Linux 有两个时钟,一个是 System Clock(系统时钟),另一个是 Hardware Clock(硬件时钟)。而在windows中只有一个硬件时钟。可以使用 date 和 hwclock 分别查看系统时钟和硬件时钟。
硬件时钟也称为实时时钟(RTC,real time clock)或 CMOS 时钟,它独立于任何软件,在电脑关机后仍然在运行,个人电脑上是依靠主板上的纽扣电池供电。
系统时钟:由 Linux Kernel(内核)维护,系统时钟在开机时会和硬件时钟同步,然后由计时器中断驱动。系统时钟记录的是自 1970-01-01 00:00:00经过的总秒数,它并不是一个整数,其精度是虚拟无穷的。
linux删除ip地址的命令是“ip addr”,该命令用于查看并操作ip地址;想要删除指定ip地址可使用“ip addr del ip地址 dev 接口”语句,清空指定网卡的所有ip可使用“ip addr flush dev 接口”语句。
1、删除指定IP
ip addr del ip地址 dev 接口 2、清空指定网卡的所有IP
ip addr flush dev 接口 扩展知识:“ip addr”的其他用法
1、使用“ip addr”查看指定网卡的信息
ip addr show device 比如查看网卡接口的信息,就是ip addr show eth0
2、增加ip
ip addr add ip/netmask dev 接口 比如给eth0增加一个172.25.21.1/24 地址
3、给网卡起别名,起别名相当于给网卡多绑定了一个ip
用法: 比如给网卡eth0增加别名
ip addr add 172.25.21.1/32 dev eth0 label eth0:1 删除别名
ip addr del ip/netmask dev eth0
目录 一、经典递归二、尾递归优化 一、经典递归 (注:本文例子只用于探讨,不考虑n<=0 等复杂情况。)
int factorial(int n){ if(n==1){ return 1; }else{ return n*factorial(n-1); } } 执行过程如下:
factorial(1)= 1 factorial(2)= 2*factorial(1)= 2*1 = 2 factorial(3)= 3*factorial(2)= 3*2 = 6 factorial(4)= 4*factorial(3)= 4*6 = 24 …… 结论:这种递归方式实际是利用了大量的栈帧(每个栈帧都是一次函数计算),存放中间值,直到完成递归(递归必须保证有终止条件哦)。由于使用大量栈帧,因此空间消耗是比较大的。
二、尾递归优化 int factorial(int n,int result){ if(n==1){ return result; }else{ return factorial(n-1,n*result); } } 执行过程如下:
factorial(4,1) = factorial(3,4*1) = factorial(2,3*4*1) = factorial(1,2*3*4*1) = factorial(1,24) = 24 结论:这种递归方式一般称为尾递归,实际只使用了一个栈帧,不停的进行返回值的计算,直到完成递归(递归必须保证有终止条件哦)。尾递归的好处是,复用了栈帧,空间消耗相对较小。
在使用django+vue完成平台功能开发登录功能,实现后,写这个文章进行记载!!欢迎交流
因为做的是内部使用平台,手动创建账号形式,没用到注册功能,无需实现
一、登录的功能逻辑设计 1、前端页面输入用户电话和密码点击登录
2、后端验证是否登录成功,返回token,存储到localstorage中
3、后端控制token是否过期
二、django后端实现 1、登录接口
接受前端访问请求,验证传递过来的用户是否正确,返回token 以及用户的基础信息
@csrf_exempt def login(request): try: if request.method == 'POST': phone = request.POST.get('username') password = request.POST.get('password') passwd = password + '{' + phone + '}' auth = Blogin().auth_user(phone, psd) if auth ['code'] == '000000': if not request.session.session_key: request.session.save() print(str(phone)+"新会话") # request.session.set_expiry(3600*4) md5 = hashlib.md5() md5.update((phone+passwd+"1258"+str(time.time())).encode()) token = md5.hexdigest() request.session['token'] = token request.session['id'] = auth['data'][0]['id'] request.session['name'] = auth ['data'][0]['user_name'] request.session.save() response = auth ['data'][0] response['password'] = token return JsonResponse('登录成功', response, '000000') else: return Response('登录失败', auth["
一、实验要求 1,定义slave与MCDF之间的接口为chnl_intf,并在接口中定义时钟块消除可能存在的竞争问题
2,用类实现
激励产生器:chnl_generator
激励发送器:chnl_initiator;调用 chnl_iniaitor中的方法来完成接口的传递
发送数据的类:chnl_trans
3,用类实现测试 chnl_basic_test 实现三个 chnl_initiator 同时发送数据的要求,能结束测试;
chnl_burst_test 实现每个 chnl_initiator 的idle_cycles设置为0,同时发送 500 个数据,最后结束测试;
chnl_basic_test 实现在三个 channel 都拉低过 ready 时(不必要同时拉低, 先后拉低即可),可以立即结束测试。
4, 将各个类封装到package chnl_pkg 中
package chnl_pkg;
endpackge: chnl_pkg
二、代码分析 时间单位
`timescale 1ns/1ps// 单位/精度 1
信号 每个通道的数据通过实现的接口输入到dut中
logic clk; logic rstn; logic [31:0] mcdt_data;//DUT输出当前输出的数据 logic mcdt_val; //DUT输出当前输出的有效信号 logic [ 1:0] mcdt_id; //DUT输出当前输出的通道号 例化 将tb的信号与dut的端口相连
mcdt dut( .clk_i (clk ) ,.rstn_i (rstn ) ,.ch0_data_i (chnl0_if.ch_data ) ,.
例1:反转一个3位整数 1. 问题描述 反转一个只有3位数的整数
2. 问题示例 输入number=123,输出321;输入number=900,输出9
3. 代码实现 # 定义一个类 class Solution: def __init__(self, number): self.number = number # number为一个3位数整数 def reverseInteger(self, number): h = int(number / 100) # 百位数 t = int(number % 100 / 10) # 十位数 z = int(number % 10) # 个位数 return (100 * z + 10 * t + 1 * h) # 主函数 number=input("请输入一个3位数的整数数字:") number=int(number) solution=Solution(number) ans=solution.reverseInteger(number) print("结果是:",str(ans))
选择简单的一键部署 一、准备工作: 安装nginx安装PHP(要能支持WordPress)安装MYSQL 二、开始添加站点 点击“网站”;点击“添加站点”选“一键部署”;在域名处选择你已经拥有备案的域名,或者直接使用IP,形如xxx.xxx.xxx.xxx:port修改其他配置,如修改数据库账号、密码等;之后“提交”; 三、点击提交后 记录数据库名、用户、密码点击访问站点 四、部署成功后 下拉选择列表,选择简体中文,点击“继续” 接着点击操作 数据库名、用户名、密码这些在前面成功部署WordPress弹出来的数据库账号资料信息;数据库是和WordPress都是在这台服务器上的,我们直接选择localhost就行;如果在同一个数据库里安装多个WordPress,修改不同表前缀;提交 接着设置个人博客的基本信息即可
安装完成之后,用户名、密码登录:
登录成功之后 ,就可写自己的博客了
之后,其他人就能访问到你的博客。访问网址:http://xxx.xxx.xxx.xxx:port
五、注意事项:如果显示连接时间超时,有可能是你的相应端口没有开放 解决:
云服务器使用的安全组,在入方向上开放相应端口(我用的88端口):
同时宝塔面板的防火墙也要开放相应端口
开放端口,之后即可正常访问。
一、官网下载Apache 官网地址:https://httpd.apache.org/
点击Download--->点击Files for Microsoft Windows--->点击ApacheHaus--->选择版本(点击Apache 2.4 VC11)----->解压下载好的压缩包文件,移动文件夹Apache24到你想要的位置。
二、安装Apache 1.移动文件Apache到E:\WAMP\Apache2.4。【解压路径最好不要用中文。】
2.命令行到Apache下面的bin目录,录入命令[ httpd -k install ]安装。
注:如果提示错误计算机中丢失 msvcr110.dll文件,请到http://www.microsoft.com/zh-CN/download/details.aspx?id=30679 这个网址来进行相关程序的下载
报错的大概意思:在启动Apache服务之前必须修正一个错误,在E:\WAMP\Apache2.4\conf 的httpd.conf文件的第39行,ServerRoot必须是有效的。
报错原因:httpd.conf里面配置的ServerRoot路径跟实际路径不一致,导致路径无效。
3.修改httpd.conf文件
4.启动Apache服务命令启动Apache服务:【 httpd -k start 】
5、安装成功验证
开始-->运行-->services.msc-->确定(或回车键Enter)--->服务列表中查看Apache服务,存在说明安装成功。
补充:了解Apache文件夹里的相关目录和文件
bin目录(主程序文件)/httpd.exe 图标(羽毛)conf目录(配置文件目录)/httpd.conf(主配置文件)和extra文件夹(扩展配置目录)/httpd-vhosts.conf(虚拟主机配置文件)htdocs目录(站点根目录)-----域名对应的目录 6.参考文章:
Apache服务器的下载与安装
Apache 下载+安装
三、Apache相关配置------主机配置 1.httpd.conf------conf目录下
SRVROOT安装位置(通过在顶端定义了一个常量,在下面引用该常量来访问,好处不用多说了,之后改动只要改这一个即可,其他的都是相对路径了)
Listen 监听端口号,默认80
ServerAdmin 用于用户设置管理员邮箱(用于客户端的用户联系管理员,现在很少使用)
ServerName 域名
DocumentRoot用于设置基站点根目录(网站根目录就是存放网站文件的最顶层目录,通过URL中域名后面的第一个斜线对应映射的就是网站根目录)
Directory配置段 2.hosts文件----位置一般在C:\WINDOWS\system32\drivers\etc
注:127.0.0.1永远代表本地ip
3.httpd.exe-----bin目录下
cmd里dir可以查看当前目录的内容,cd可以更改目录的位置httpd.exe文件可以进行Apache服务的启动(httpd.exe - k start),停止(httpd.exe - k stop)和重新启动(httpd.exe - k restart)httpd.exe文件可以对配置文件进行语法检查(httpd -t) 注:在win10系统中,需要用管理员的身份运行
4.window环境变量:window的环境变量记录了很多的路径,当在cmd窗口执行一个命令时,如果当前的目录找不到我们要执行的文件时,window会找到环境变量中所记录的位置,依次进行查找,找到了就运行,找不到则报错
.“计算机”右键 → “高级系统设置” → “高级” → “环境变量” .
为了高效率的工作,我们在使用vScode的是时候,经常会用到一些好用的插件;现在就个人喜欢的插件分享给大家,欢迎点赞加收藏;
1、JavaScript(ES6) code snippets ES6 语法智能提示及快速输入,不仅仅支持 .js,还支持.ts,.jsx,.tsx,.html,.vue
2、Auto Close Tag 自动闭合 HTML / XML 标签,非常快速的编写 HTML 代码
3、Auto Rename Tag 自动完成 HTML / XML 另一侧标签的同步修改,非常方便
4、Color Info 提供你在 CSS 中使用颜色的相关信息,悬停光标,就可以预览色块中色彩模型
5、HTML CSS Support 智能提示 CSS 类名以及 id 名
6、npm Intellisense npm 装包后,require 时的包智能提示,import 语句中自动填充 npm 模块
7、Terminal 编辑器中内嵌一个似 cmd 终端程序,直接在编辑器中运行终端命令
8、Vetur Vue 多功能集成插件,包括:语法高亮,智能提示,emmet,错误提示,格式化,自动补全,debugger
9、ES7 React/Redux/GraphQL/React-Native snippets 语法智能提示,React 开发者必备
10、Markdown Preview Enhanced 实时预览 Markdown
11、code spell checker 检查你的英文单词拼写是否有误
12、ESLint javaScript 语法纠错
一、简介 Spring 是非常流行和成功的 Java 应用开发框架,Spring Security 正是 Spring 家族中的成员。Spring Security 基于 Spring 框架,提供了一套 Web 应用安全性的完整解决方案。正如你可能知道的关于安全方面的两个主要区域是“认证”和“授权”(或者访问控制),一般来说,Web 应用的安全性包括用户认证(Authentication)和用户授权(Authorization)两个部分,这两点也是 Spring Security 重要核心功能。
(1)用户认证指的是:验证某个用户是否为系统中的合法主体,也就是说用户能否访问该系统。用户认证一般要求用户提供用户名和密码。系统通过校验用户名和密码来完成认证过程。通俗点说就是系统认为用户是否能登录。
(2)用户授权指的是验证某个用户是否有权限执行某个操作。在一个系统中,不同用户所具有的权限是不同的。比如对一个文件来说,有的用户只能进行读取,而有的用户可以进行修改。一般来说,系统会为不同的用户分配不同的角色,而每个角色则对应一系列的权限。通俗点讲就是系统判断用户是否有权限去做某些事情。
SpringSecurity本质上是过滤器链 二、UserDetailService接口 当什么也没有配置的时候,账号和密码是由 Spring Security 定义生成的。而在实际项目中账号和密码都是从数据库中查询出来的。 所以我们要通过自定义逻辑控制认证逻辑。该类中编写查询数据库中用户名和密码的过程
三、PasswordEncoder接口 // 表示把参数按照特定的解析规则进行解析 String encode(CharSequence rawPassword); // 表示验证从存储中获取的编码密码与编码后提交的原始密码是否匹配。如果密码匹 配,则返回 true;如果不匹配,则返回 false。第一个参数表示需要被解析的密码。第二个 参数表示存储的密码。 boolean matches(CharSequence rawPassword, String encodedPassword); // 表示如果解析的密码能够再次进行解析且达到更安全的结果则返回 true,否则返回 false。默认返回 false。 default boolean upgradeEncoding(String encodedPassword) { return false; } 四、修改用户名和密码 1、配置文件修改
2、通过配置类
@Configuration public class UserNamePasswordConfig extends WebSecurityConfigurerAdapter { /** * 设置用户名和密码 * @param auth * @throws Exception */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { // 对密码进行加密 BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); String password = bCryptPasswordEncoder.
文章目录 vue-cli1. vue-cli2. 安装 vue-cli2.1 解决 Windows PowerShell 不识别 vue 命令的问题 3. 创建项目4. 基于 vue ui 创建 vue 项目步骤1:在终端下运行 vue ui 命令,自动在浏览器中打开创建项目的可视化面板步骤2:在详情页面填写项目名称步骤3:在预设页面选择手动配置项目步骤4:在功能页面勾选需要安装的功能步骤5:在配置页面勾选 vue 的版本和需要的预处理器步骤6:将刚才所有的配置保存为预设(模板),方便下一次创建项目时直接复用之前的配置vue ui 的本质:项目创建完成后,自动进入项目仪表盘 5. 基于命令行创建 vue 项目步骤1:在终端下运行 vue create demo2 命令,基于交互式的命令行创建 vue 的项目步骤2:选择要安装的功能步骤3:使用上下箭头选择 vue 的版本,并使用回车键确认选择路由是否使用历史模式(由选中路由才需要选中,根据需求选择)步骤4:使用上下箭头选择要使用的 css 预处理器,并使用回车键确认选择步骤5:使用上下箭头选择如何存储插件的配置信息,并使用回车键确认选择步骤6:是否将刚才的配置保存为预设开始创建项目并自动安装依赖包项目创建完成运行项目 vue-cli 1. vue-cli vue-cli(俗称:vue 脚手架)是 vue 官方提供的、快速生成 vue 工程化项目的工具。
特点:
① 开箱即用
② 基于 webpack
③ 功能丰富且易于扩展
④ 支持创建 vue2 和 vue3 的项目
vue-cli 的中文官网首页:
2. 安装 vue-cli vue-cli 是基于 Node.
1、下载mysql(当前最新版本为5.7.38):
https://downloads.mysql.com/archives/community/
2、创建mysql安装目录:mkdir -p /data/app/
将mysql安装包移动到/data/app
3、解压mysql安装包,并将解压后的名称改为mysql。
4、创建用户组、用户、文件夹、赋权
groupadd mysql #创建用户组
useradd -r -g mysql mysql #创建用户 -r:建立系统账号 -g:指定用户组
cd /data/app/mysql #切换到安装目录
mkdir data #创建数据存放目录
mkdir mysql-log #创建日志存放目录
mkdir mysql-log/err-log
mkdir mysql-log/slow-log
mkdir mysql-log/bin-log #主机需要此目录
chown -R root:mysql . #将当前目录以及字母里,所有者改变为 mysql,所属组修改为 mysql
chown -R mysql:mysql data
chown -R mysql:mysql mysql-log
5、配置 /etc/my.cnf。
5.1、主机配置文件:vi /etc/my.cnf
[mysqld]
port = 3306 #端口
basedir = /data/app/mysql #mysql安装路径
datadir = /data/app/mysql/data/ #mysql数据存放路径
#日志设置
log-error = /data/app/mysql/mysql-log/err-log/db-err.
uniapp中uForm的setRules该放在哪里? 一般建议放在vue的生命周期函数mounted()中或uniapp页面的生命周期函数onReady()中
在onLoad或者created时页面可能还未渲染完毕,此时setRules可能会有问题,特别是对页面要根据数据渲染成不同的表单的情况,比如使用了v-if等判断的时候,会导致校验加的有问题。而在mounted和onReady中setRules可以避免这种情况,此时页面已经解析完成,真实的DOM元素已经挂载完毕。
mounted() { this.$refs.uForm.setRules(this.rules); } 或
onReady() { this.$refs.uForm.setRules(this.rules); }
延迟语句是什么? 编程的时候,经常需要申请一些资源,比如数据库连接、文件、锁等,这些资源需要在用完之后释放掉,否则会造成内存泄漏。但编程人员经常容易忘记释放这些资源,从而造成一些事故。语言直接在语言层面提供defer关键字,在申请资源语句的下一行,可以直接用defer语句来注册函数结束后执行释放资源的操作。因为这样一颗小小的语法糖,忘写关闭资源语句的情况就大大地减少了。
defer是Go语言提供的一种用于注册延迟调用的机制:让函数或语句可以在当前函数执行完毕后(包括通过return正常结束或者panic导致的异常结束)执行。在需要释放资源的场景非常有用,可以很方便地在函数结束前做一些清理操作。在打开资源语句的下一行,直接使用defer就可以在函数返回前释放资源,可谓相当有效。
defer通常用于一些成对操作的场景:打开连接/关闭连接、加锁/释放锁、打开文件/关闭文件等。使用非常简单:
func main() { f, err := os.Open("filename") if err != nil { panic(err) } if f != nil { defer f.Close() } } 在打开文件的语句附近,用defer语句关闭文件。这样,在函数结束之前,会自动执行defer后面的语句来关闭文件。注意,要先判断f是否为空,如果f不为空,再调用f.CloseO函数,避免出现异常情况。
当然,defer会有短暂延迟,对时间要求特别高的程序,可以避免使用它,其他情况一般可以忽略它带来的延迟。特别是Go1.14又对defer做了很大幅度的优化,效率提升了不少
我们可以来看一个反面例子:
r.mu.Lock() rand.Intn(param) r.mu.Unlock() 上面只有三行代码,看起来这里不用defer执行Unlock并没有什么问题。其实并不是这样,中间这行代码rand.Intn(param)其实是有可能发生panic的,更严重的情况是,这段代码很有可能被其他人修改,增加更多的逻辑,而这完全不可控。也就是说,在Lock和Unlock之间的代码一旦出现异常情况导致panic,就会形成死锁。因此这里的逻辑是,即使是看起来非常简单的代码,使用defer也是有必要的,因为需求总在变化,代码也总会被修改。
延迟语句的执行顺序是什么? 先看一下官方文档对defer的解释:
Each time a "defer"statement executes,the function value and parameters to the call are evaluated asusual and saved anew but the actual function is not invoked.Instead,deferred functions are invoked immediately before the surrounding function returns,in the reverse order they were deferred.
#include <stdio.h> struct Student{ int num; char name[20]; char sex; int age; }; struct Student stu[3]={{10101,"Li Lin",'M',18},{10102,"Zhang Fang",'M',19},{10104,"Wang Min",'F',20}}; int main(){ struct Student *p; printf("No. Name sex age\n"); for(p=stu;p<stu+3;p++) printf("%5d %-20s%2c%4d\n",p->num,p->name,p->sex,p->age); return 0; }
问题描述:上下滚动表格,表头有透明缝隙
解决方案:使用outline(轮廓),代码如下:
thead {
position:sticky;
top: 0;
left:0;
background-color:#fff;
tr>th,td {
border:none;
outline-color: #666;
outline-style:solid;
outline-width:1px;
border-top: 1px solid #666;
}
}
Linux安装下载mysql8.0版本实战详细教程 1.进入 /usr/local下,根据需要的版本下载mysql:wget https://cdn.mysql.com/archives/mysql-8.0/mysql-8.0.30-el7-x86_64.tar.gz,不通版本修改命令里的版本号
没有wget命令的可以安装此命令 sudo yum -y install wget
也可以下载完自己上传到linux里面
2.解压下载的包,tar zxvf mysql-8.0.30-el7-x86_64.tar.gz,解压完成后将文件夹重命名为 mysql(为了好看)
3.进入mysql文件夹,创建data文件夹用来存储文件
4.创建用户组以及用户和密码
groupadd mysql
useradd -g mysql mysql
用户组名以及用户名和密码为了方便记都用mysql就行,当然也可以自己叫什么都行
5.授权刚刚创建的 mysql 用户组对mysql文件夹的操作权限
chown -R mysql.mysql /usr/local/mysql
chmod 777 /usr/local/mysql/mysql/data
6.编辑 my.cnf 文件
vi /etc/my.cnf 或者 vim /etc/my.cnf (编辑命令的使用不用说了吧)
下面的配置为了防止出错,就按照这个写吧
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data/
socket=/tmp/mysql.sock
character-set-server=UTF8MB4
lower_case_table_names=1(注:设置数据库表名大小写不敏感,如果想要区分大小写,这个不加,默认是0,所以不用加)
sql_mode=‘STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION’(注:MySQL8.0 配置中 sql_mode 配置了 only_full_group,需要 GROUP BY中包含所有 在 SELECT 中出现的字段。因此需要在 MySQL 的配置中去掉这个配置)
7.保存后,进入mysql的bin目录下,执行下面命令
./mysqld --user=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --lower-case-table-names=1 --initialize
其中 --lower-case-table-names=1 这个参数依然根据是否需要数据库表名大小写敏感设置成 0 或者 1,默认是0,
创建一个console对象,实际就是console.info方法,为了能够使用console的log、warn等方法还是最好写个适用性强的,代码如下:
window.console = window.console || (function () { var c = {}; c.log = c.warn = c.debug = c.info = c.error = c.time = c.dir = c.profile= c.clear = c.exception = c.trace = c.assert = function () { }; return c; })(); 没有粉丝,没有评论,甚至连读者都没有。因为自己写的烂,因为自己水平有限,所以自己的作品一经发出就石沉大海了,得不到任何的回信,就好像自己写的东西是给自己看的。自己的作品怎么看都好像不够完美,全身的毛病,所以读者不喜欢也很正常对吧!
其实最让我开心的是有些读者们夸我文笔不错,或许是有人第一次这样夸我的缘故吧!又或许是我写的东西没什么人认可,我感受到了一种前所未有的激动,对于未来的憧憬,对自己写下去的动力。
因为有你们,我的写作之路才不孤独,因为有你们,我才能坚持到现在,如果有一天我真的写出圈了,或许我们可以整个交流会之类的,到时候促膝长谈。
“书山有路勤为径,学海无涯苦作舟。”写作苦是苦了点,整得我差点就想放弃了,不过还好有你们。我也不急着成功,因为没有个几十年如一日的坚持,哪能轻易成功?
茫茫文海无人意,天下有君识吾心。文海很孤独,但是有诸君,便足以令我至千里。
一、查看防火墙状态 1、首先查看防火墙是否开启,如未开启,需要先开启防火墙并作开机自启
systemctl status firewalld 开启防火墙并设置开机自启
systemctl start firewalld
systemctl enable firewalld
一般需要重启一下机器,不然后面做的设置可能不会生效
二、开放或限制端口 1、开放端口
(1)如我们需要开启XShell连接时需要使用的22端口
firewall-cmd --zone=public --add-port=22/tcp --permanent 其中--permanent的作用是使设置永久生效,不加的话机器重启之后失效
(2)重新载入一下防火墙设置,使设置生效
firewall-cmd --reload (3)可通过如下命令查看是否生效
firewall-cmd --zone=public --query-port=22/tcp (4)如下命令可查看当前系统打开的所有端口
firewall-cmd --zone=public --list-ports 2、限制端口
(1)比如我们现在需要关掉刚刚打开的22端口
firewall-cmd --zone=public --remove-port=22/tcp --permanent (2)重新载入一下防火墙设置,使设置生效
firewall-cmd --reload (3)再去查看系统所有开放的端口,已经看到没有22端口了
firewall-cmd --zone=public --list-ports 3、批量开放或限制端口
(1)批量开放端口,如从100到500这之间的端口我们全部要打开
firewall-cmd --zone=public --add-port=100-500/tcp --permanent (2)重新载入一下防火墙设置,使设置生效
firewall-cmd --reload (3)查看系统所有开放的端口,可以看到从100到500的端口已被全部开放
firewall-cmd --zone=public --list-ports (4)同理,批量限制端口为
firewall-cmd --zone=public --remove-port=100-500/tcp --permanent firewall-cmd --reload 三、开放或限制IP 1、限制IP地址访问
(1)比如限制IP为192.168.0.200的地址禁止访问80端口即禁止访问机器
firewall-cmd --permanent --add-rich-rule="
1、插件下载:打开GitHub搜索leeks即可
2、导入插件:Ctrl+Alt+S快捷键,找到Plugins,导入Leeks插件
3、使用插件:重启Idea,Ctrl+Alt+S快捷键打开面板,设置需要查看的股票以及基金代码
4、开始摸鱼 你们还有啥好的摸鱼插件,分享一下,留在评论区哈!
目录
boundValueOps(Key-Value)
BoundValueOperations
set(V value)
get()
set(V value, long timeout, TimeUnit unit)
getAndSet(V value)
increment(double delta)和increment(long delta)
boundHashOps(hash)
BoundHashOperations
put(HK key, HV value)
get(Object member)
getKey()
keys()
values()
entries()
putAll(Map m)
increment(HK key, long delta)
boundListOps(list)
BoundListOperations
leftPush(V value)
leftPop()
range(long start, long end)
index(long index)
boundSetOps(Set)
BoundSetOperations
绑定key的对象,我们可以通过这个对象来进行与key相关的操作
add(V… values)
members()
randomMember()、randomMembers(long count)
pop()
remove(Object… values)
boundZSetOps
BoundZSetOperations
add(V value, double score)
range(long start, long end)
remove(Object… values)
转自: Java代码中如何获取命令行参数呢?
Java命令行参数 一个程序开始于对函数main()的调用。在这样做的时候,有两个参数被送给main(),
其中的一个描述了命令行参数的个数,通常称为argc;另一个是命令行参数的数组,通常称为argv。
命令行参数都是字符串,所以argv的类型是char* [argc+1]。该程序的名字也作为argv[0]传进来,
所以argc的值至少是1。这个参数的表总以0结束,也就是说,argv[argc]==0
java命令行参数:指使用cmd运行Java程序时传入的参数信息,它们Java代码中如何接收cmd中输入的参数信息呢?
下文将一一道来,如下例所示:
例:java中的命令行参数 class testClass { public static void main(String args[]) { System.out.println("你一个参数: " + args[0]); } } 编译命令: javac testClass.java
执行命令: java testClass java265.com
-----以上代码,将输出以下信息----
你一个参数:java265.com 例2:遍历打印出所有参数信息 class testClass { public static void main(String args[]) { for (int i = 0; i < args.length; i++) System.out.println(args[i]); } } 编译命令: javac testClass.java
执行命令: java testClass java265.com a b c 1 ----运行以上代码,将输出以下信息----
【Java】统计字符出现次数 需求 键盘输入字符串,统计其中出现的字符,及其出现次数
运行效果 代码 方法一 package com.cxl.demo01; import java.util.Scanner; /*统计字符次数 键盘输入字符串,统计其中出现的字符,及其出现次数 */ public class CountChar { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("请输入字符串:"); String str = sc.nextLine(); //拆分字符串 char[] chars = str.toCharArray(); //设置标识,与其他字符比较有相同则为true,代表此字符无需再去比较,减少重复 boolean[] flag = new boolean[chars.length]; //系统自动为其赋默认值,为false for (int i = 0; i < chars.length ; i++) { if (flag[i] == false){ int count = 1; //首次计算次数 for (int j = i+1; j < chars.
一、Github Action简介 github Action (工作流),简单理解就是自动化部署、测试。也就是之前人工手动部署变为现在由机器(服务器)自动部署、测试了。
二、对github Action(工作流)的使用 首先需要有个人令牌,
教程:github个人令牌生成
将令牌配置到仓库
点击Actions
创建秘钥
配置秘钥
下图秘钥是配置个人令牌,这就是上面教程生成的个人令牌
效果如下:
它们之间的关联
github action工作流配置 name: docs on: # 每当 push 到 main 分支时触发部署 push: branches: - develop # 手动触发部署 workflow_dispatch: jobs: docs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: # “最近更新时间” 等 git 日志相关信息,需要拉取全部提交记录 fetch-depth: 0 - name: Setup Node.js uses: actions/setup-node@v1 with: # 选择要使用的 node 版本 node-version: '16' # 缓存 node_modules - name: Cache dependencies uses: actions/cache@v2 id: yarn-cache with: path: | **/node_modules key: ${{ runner.
树的重心:找到一个点,其所有的子树中最大的子树节点数最少.
给出节点为n的树
下面n-1行为点连接关系
如:
4
1 3
1 2
2 4
一,链式前向星: #include <iostream> const int N=2e5+5; using namespace std; int head[N],son[N],dp[N],n,k=0,mins=1e9; //son:某节点的子树节点数 //dp:某节点的最大子节点数 //mins:最小的最大子节点数 bool fa[N]; struct edge { int u,v,nxt; }e[N]; void add(int u,int v) { k++; e[k].v=v; e[k].nxt=head[u]; head[u]=k; } void dfs(int u,int f) { son[u]=1;//叶子节点初始为1 for(int i=head[u];i;i=e[i].nxt)//i=e[i].nxt取得前向 { int v=e[i].v; if(v!=f)//取得节点不是父节点 { dfs(v,u); son[u]+=son[v]; dp[u]=max(dp[u],son[v]);//与u的各个子树节点比较 } } dp[u]=max(dp[u],n-son[u]);//u最大的子树节点数与其父节点的子树节点数比较 mins=min(mins,dp[u]); } int main() { cin>>n; for(int i=1;i<n;i++) { int x,y; cin>>x>>y; add(x,y); add(y,x); } dfs(1,0); for(int i=1;i<=n;i++) { if(dp[i]==mins) { cout<<"
步骤一:创建.py文件 如果导入两个库pytesseract和PIL有问题去看我的这篇文章
python代码提取图片文字
打包不会的去看这篇
将python中的.py文件打包成.exe
import pytesseract from PIL import Image def demo(): # 打开要识别的图片 print("进入成功") i = 0 #保证程序持续的运行 while i < 100: a = input("请输入数字,1进入提取中文,否则进入提取英文:") if a == '1': inpt1 = input("请输入路径:") image = Image.open(inpt1) text = pytesseract.image_to_string(image, lang='chi_sim') print(text) else : inpt = input('请输入路径:') image = Image.open(inpt) text = pytesseract.image_to_string(image, lang='eng') print(text) i = i + 1 # 路径测试../selfLesson/test.png成功 # 路径测试F:\pycharm\selfStudy\selfLesson\test.png成功,图片的绝对路径 # F:\pycharm\selfStudy\selfLesson\3.png 测试成功 # C:\Users\chaojixingyun\Pictures\QQ浏览器截图\1.png 测试成功 # 使用pytesseract调用image_to_string方法进行识别,传入要识别的图片,lang='chi_sim'是设置为中文识别, #识别英文设置为eng if __name__ == '__main__': demo() 步骤二找到.
2022图像翻译/扩散模型:UNIT-DDPM: UNpaired Image Translation with Denoising Diffusion Probabilistic Models. UNIT-DDPM:无配对图像翻译与去噪扩散概率模型 0.摘要1.概述2.相关工作2.1.Image-to-Image翻译2.1.1成对图像间翻译2.1.2未配对的图像间翻译 2.2. 扩散概率模型去噪 3.方法3.1.模型训练3.2. 图像翻译推理 4.评估4.1.基线4.2.数据集4.3.通过UNIT-DDPM的图像到图像翻译4.4.结果4.5.消融实验4.6.局限 5.结论参考文献 0.摘要 我们提出了一种新的无配对图像间翻译方法,该方法使用去噪扩散概率模型而不需要对抗训练。我们的方法,UNpaired Image Translation with Denoising Diffusion Probabilistic Models(UNIT-DDPM),训练一个生成模型,通过最小化另一个域条件下的去噪分数匹配目标,推断图像在两个域上的联合分布作为马尔可夫链。特别地,我们同时更新两个域转换模型,并基于Langevin dynamics,以输入源域图像为条件,通过去噪马尔可夫链蒙特卡罗方法生成目标域图像。我们的方法为图像到图像的转换提供了稳定的模型训练,并生成高质量的图像输出。这使得在若干公共数据集(包括彩色图像和多光谱图像)上的先进技术初始距离(FID)性能显著优于同时代的对抗性图像对图像翻译方法
1.概述 合成真实的图像是计算机视觉长期以来的目标,因为它能够实现有益和广泛的应用,如机器学习任务中的数据增强,隐私保护和数据采集中的成本降低。虽然有各种各样的替代方法用于图像合成,如物理模拟[7],分形景观[31],和图像编辑[30],随机生成建模[46]的使用继续提供显著的有效性,在特定领域中制作相似但不同的图像,而不需要任何特定领域的知识。值得注意的是,最近对生成建模的研究集中在深度神经网络(DNN)[10],即深度生成模型(DGNN),因为它们具有对真实世界数据模式的潜在建模能力。生成对抗网络(GAN)[11],自回归模型[12],基于流的模型如NICE[3],图1:使用去噪扩散概率模型的小说图像到图像翻译方法的概念说明。RealNVP[4]和Glow[22],变分自编码器(VAE)[32]和图像转换器[29]已经合成了非常合理的图像。类似地,在迭代生成模型中也有显著的进步,如去噪扩散概率模型(DDPM)[15]和噪声条件评分网络(NCSN)[38],它们已经证明了产生与其他当代方法相媲美的更高质量合成图像的能力,但不必执行(潜在的问题)对抗训练。为了实现这一目标,许多去噪自编码模型被训练去噪被不同级别的高斯噪声破坏的样本。然后通过马尔可夫链蒙特卡罗(MCMC)过程产生样本,从白噪声开始,逐步去噪并转换为有意义的高质量图像。生成马尔可夫链过程基于Langevin dynamics[36],通过反转前向扩散过程逐步将图像转换为噪声
DGNN在图像到图像(I2I)的翻译中也引起了极大的关注[8][20][19][44]。图像到图像是一项计算机视觉任务,用于建模不同视觉域之间的映射,如风格转换[8],着色[5],超分辨率[23],照片真实感图像合成[2],域适应[26]。对于样式转移,提出了样式转移网络[8]作为dnn,训练它将样式从一个图像转移到另一个图像,同时保留其语义内容。此外,样式传输网络用于图像样式[20]的随机化。对于一般用途,Pix2Pix[19]使用GAN使用成对训练数据对映射函数建模。为了降低配对训练的依赖性,提出了周期一致性GAN (CycleGAN)[44],利用周期一致性对训练进行正则化。然而,这种基于gan的方法需要在优化和架构上非常具体的选择来稳定训练,并且很容易无法覆盖所有数据分布模式[9]。
图1:使用去噪扩散概率模型的四种新的图像转换方法的概念说明
本文提出了一种新的I2I翻译方法,使用DDPM作为后端,而不是对抗网络,以缓解不稳定训练的限制,提高生成图像的质量(图1)。本文的主要贡献是:
基于双域马尔可夫链的生成视频模型——引入了一种马尔可夫链I2I翻译方法,近似源域和目标域的数据分布,使它们相互关联(第3节)。稳定的基于非gan的图像对图像翻译训练——该方法不需要对抗训练,然而,该模型生成了真实的输出,根据不同级别噪声的扰动捕获了高频变化(第3.1节)。马尔可夫链蒙特卡罗抽样(Markov Chain Monte Carlo Sampling)的新应用。提出的采样算法可以以未配对的源域图像为条件来合成目标域图像(章节3.2)。的标准数据集(Facade[39],照片-地图[44],夏季-冬季[44],和rgb - thermal[17])(表1和图5),详见第4节。 2.相关工作 我们回顾了两个相关主题的之前工作:图像对图像的翻译和去噪扩散概率模型
2.1.Image-to-Image翻译 I2I翻译的目标是学习来自源域的图像和来自目标域的图像之间的映射,I2I翻译通常分为两种方法:成对和非成对。
2.1.1成对图像间翻译 有监督I2I方法的目的是学习输入图像和输出图像之间的映射,通过训练一组对齐的图像对。早期的工作提出使用预先训练的CNN和Gram矩阵来获得图像[6]的感知分解。这分离了图像内容和风格,在保留语义内容的同时支持风格变化。最近的许多I2I方法都是使用GAN[11]进行对抗训练的,这是一个生成模型,设计为具有一个生成器和一个鉴别器组件,它们彼此竞争。该生成器经过训练,通过鉴别器输出将随机值映射到真实数据示例。该鉴别器同时被训练来鉴别由生成器产生的真实和虚假数据示例。Pix2Pix[19]提供了一个通用的对抗框架,将图像从一个域转换到另一个域。使用U-Net[34]代替自动编码器,在输入和输出之间共享底层信息。BicycleGAN[45]结合了条件VAE-GAN(CVAE-GAN)和一种恢复潜伏代码的方法,这提高了性能,其中CVAE-GAN重构特定类别的图像[1]。
2.1.2未配对的图像间翻译 配对I2I翻译需要源域和目标域的对齐图像对,而非配对方法学习的源和目标图像集是完全独立的,没有两个域之间的成对例子。CycleGAN[44]是一种使用GAN的未配对I2I翻译方法。CycleGAN修改生成器G和鉴别器D,使其从源图像 x s ∈ X s x_s∈X_s xs∈Xs传输到目标图像 x t ∈ X t x_t∈X_t xt∈Xt。这不仅学习了横向变换G,还学习了双向变换路径 G t ( x s ) G_t(x_s) Gt(xs), G s ( x t ) G_s(x_t) Gs(xt)。此外,这采用了一个新的损失度量,命名为循环一致性损失 L c y c ( G s , G t ) L_{cyc}(G_s,G_t) Lcyc(Gs,Gt):
本篇参考其它csdn文章有https://blog.csdn.net/weixin_53095382/article/details/125613314
https://blog.csdn.net/qq_42818011/article/details/122730663
感谢伙伴的教导,写下这片文章只为以后做参考
首先我遇到的错误展示 错误一:pip : 无法将“pip”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 通常出现这种情况是因为cmd(终端)无法识别pip指令,环境变量中缺失pip程序路径,因此需要手动将pip所在路径添加到环境变量。
解决 查看在设置–》项目:pythonProject–》python解释器中是否安装pip
没有的话,点击左边的加号,在里面搜索pip之后就安装软件包就行了
安装好之后最重要的是
配置pip的运行环境 找到pip.exe的路径复制包括script的那个(我的是F:\pycharm\pythonProject\venv\Scripts)
进入系统高级设置,找到环境变量,再找到path,最后将复制的路径新建添加进去就可以了
最后重启电脑就行了 测试 点击下方的终端(terminal)进入后输入pip,出现信息表示环境配置成功
然后输入pip install pyinstaller
在下面的输入框输入pyinstaller -w -F XXX.py Pyinstaller可以通过简单的命令进行python代码的打包工作,其基本的命令为:
pyinstaller -option xxx.py
-D 生成一个文件目录包含可执行文件和相关动态链接库和资源文件等;
-F 仅生成一个可执行文件
-w:表示希望在生成的.exe程序运行过程中,不要出现cmd黑框(就是图中的黑框)(注意:小写!)
对于打包结果较大的项目,选用-D生成目录相比单可执行文件的打包方式,执行速度更快,但包含更加多的文件
错误二:出现了文件not found 的错误(我没有解决但我绕过它) 解决 找到你.py文件放置的位置
在这个输入框输入cmd后回车打开提示符
在命令提示符中输入pyinstaller -w -F me.py(最后这个是你要打包成.exe文件的名)
成功后最后一行会出现successful提示
成功之后会生成这些文件,在dist文件夹中就是.exe文件
欢迎来到矽芯硬翌的科技主义教室! 害,如今已经十六届智能车啦也是我最后一次参赛了。第十五届充满了遗憾,如今也只能总结失败继续向前啦,接下来就在这里持续更新这次十六届智能车制作的实况吧,主要从硬件设计,程序设计,赛道元素,车模处理这几个方面出发,期待十六届的到来 加油UPUPUP!
@Author: 精神小🔥君!
👇 想要我的财宝吗?想要的话可以全部给你,去找出来吧,这世上所有的一切都在那里! 👇
ONE PIECE地址: ✨ 矽芯硬翌的博客✨
文章目录 欢迎来到矽芯硬翌的科技主义教室! 前言一、总体介绍二、电机介绍三、硬件电路设计3.1 电源部分3.2 H桥硬件电路设计3.3 PWM输入电路 三、总结 前言 第十五届时四轮组用的是C车模,我们电机驱动选择的是MOS管双电机驱动。由于这次换了B车模所以我在原有的基础上将MOS管双电机驱动改为单电机驱动。关于硬件的设计我想说的是要站在巨人的肩膀上,我也不是自己造电路的,大多数都是对比模仿他人的方案,这里我重点讲一下元器件的PCB与原理图的绘制方面的问题 。 那现在我们就开始吧! 以下是介绍电机驱动的各个组成部分,仅供参考。 上一篇已经介绍过TC264主板的设计啦,有兴趣的多多支持哦 关于TC264主板设计的内容看这里:👉智能车四轮组打工日记(一)—TC264主板硬件设计👈
一、总体介绍 在电机驱动电路的选型上,有很多选择和选型。 相比较常用的 BTN7971,MOS 导通电阻小、 响应快, 为想要发挥 B 车的性能, 同时 B 车电机满转的电流很大,为了达到软件控制的要求,我们最后经过比较,最终选择了来自英飞凌经典的驱动组合 IR2104 和 IRLR7843,搭建两个 H 桥驱动电路来驱动电机。
二、电机介绍 第十六届的新B车模采用的是RS-540伺服电机,其实物图如下。
RS-540电机实物图:
直流伺服电机具有优良的速度控制性能,它输出较大的转矩,直接拖动负载运行,同时它又受控制信号的直接控制进行转速调节。在很多方面有优越性,具体来说,它具有以下优点:
具有较大的转矩,以克服传动装置的摩擦转矩和负载转矩。调速范围宽,高精度,机械特性及调节特性线性好,且运行速度平稳。具有快速响应能力,可以适应复杂的速度变化。电机的负载特性硬,有较大的过载能力,确保运行速度不受负载冲击的影响。可以长时间地处于停转状态而不会烧毁电机,一般电机不能长时间运行于停转状态,电机长时间停转时,稳定温升不超过允许值时输出的最大堵转转矩称为连续堵转转矩,相应的电枢电流为连续堵转电流。 RS-540电机具体参数: 三、硬件电路设计 3.1 电源部分 电源部分采用的是1117-5。AMS1117是一个低漏失电压调整器,它的稳压调整管是由一个PNP驱动的NPN管组成的,漏失电压定义为:VDROP=VBE+VSAT。AMS1117有固定和可调两个版本可用,输出电压可以是:1.2V,1.5V,1.8V,2.5V,2.85V,3.0V,3.3V,和5.0V。片内过热切断电路提供了过载和过热保护,以防环境温度造成过高的结温。
为了确保AMS1117的稳定性,对可调电压版本,输出需要连接一个至少22μF的钽电容。对于固定电压版本,可采用更小的电容,具体可以根据实际应用确定。通常,线性调整器的稳定性随着输出电流增加而降低。
AM1117-5的电路图部分:
升压电路采用的是MC34603,MC34063是一单片双极型线性集成电路,专用于直流-直流变换器控制部分。片内包含有温度补偿带隙基准源、一个占空比周期控制振荡器、驱动器和大电流输出开关,能输出1.5A的开关电流。它能使用最少的外接元件构成开关式升压变换器、降压式变换器和电源反向器
MC34063升压电路:从5V升到12V:
电源部分小结:通过AMS1117-5模块将电池的电压稳定在5V,并输送给MC34063用于升压。MC34063输出的12V电压用于提供给后面的H桥电路。
3.2 H桥硬件电路设计 关于H桥电路的设计主要用到了IR2104半桥驱动芯片和IR7843MOS管。
H桥电路整体原理图如下:
1. IR7843MOS管
在H桥中一般使用4个N型MOS管来搭建。对于NMOS,当外部给的栅源极Vgs电压大于芯片的Vgs阈值(大部分在2V-10V之间)时,漏极D和源极S之间直接导通。如果外部给的Vgs电压小于阈值,漏极D和源极S之间截止。
所以简单的来说,NMOS管就是一个由栅极G电压控制的一个开关。就是通过Vgs来控制NMOS管的通断。
NMOS管的原理图如下:
2.IR2104半桥驱动芯片
所谓半桥驱动芯片,便是一块驱动芯片只能用于控制H桥一侧的2个MOS管。因此采用半桥驱动芯片时,需要两块该芯片才能控制一个完整的H桥。
GO创建数组 func main() { var numbers1[5] int = [5]int {1,2,3,4,5} fmt.Println(numbers1[2]) numbers2 := [5]int{1,2} fmt.Println(numbers2[4]) numbers3 := [5]int{2:4,4:10} fmt.Println(numbers3[4]) numbers4 := [...]int{7,8,9} fmt.Println(len(numbers4)) fmt.Println(numbers4[2]) var numbers5[7] int numbers5[3] = 100 numbers5[4] = 200 fmt.Println(len(numbers5)) fmt.Println(numbers5[2]) }
简单使用:
(1)定义:
struct delayed_work test_delaywork;
(2)初始化
INIT_DELAYED_WORK(&test_delaywork , test_delaywork_func);
(3)实现回调函数
static void test_delaywork_func(struct work_struct *work)
{
printk("delaywork running\n");
}
(4)调用delaywork
schedule_delayed_work(&test_delaywork , msecs_to_jiffies(200));
(5)取消delaywork
cancel_delayed_work_sync(&test_delaywork );
INIT_DELAYED_WORK() 函数剖析 INIT_DELAYED_WORK()是一个宏,我们给它传递了两个参数.&hub->leds和led_work.对设备驱动熟悉的人不会觉得INIT_DELAYED_WORK()很陌生,其实鸦片战争那会儿就有这个宏了,只不过从2.6.20的内核开始这个宏做了改变,原来这个宏是三个参数,后来改成了两个参数,所以经常在网上看见一些同志抱怨说最近某个模块编译失败了,说什么make的时候遇见这么一个错误:
error: macro “INIT_DELAYED_WORK” passed 3 arguments, but takes just 2
当然更为普遍的看到下面这个错误:
error: macro “INIT_WORK” passed 3 arguments, but takes just 2
于是就让我们来仔细看看INIT_WORK和INIT_DELAYED_WORK.其实前者是后者的一个特例,它们涉及到的就是传说中的工作队列.这两个宏都定义于include/Linux/workqueue.h中:
#define INIT_WORK(_work, _func) / do { / (_work)->data = (atomic_long_t) WORK_DATA_INIT(); / INIT_LIST_HEAD(&(_work)->entry); / PREPARE_WORK((_work), (_func)); / } while (0) #define INIT_DELAYED_WORK(_work, _func) / do { / INIT_WORK(&(_work)->work, (_func)); / init_timer(&(_work)->timer); / } while (0) 有时候特怀念谭浩强那本书里的那些例子程序,因为那些程序都特简单,不像现在看到的这些,动不动就是些复杂的函数复杂的数据结构复杂的宏,严重挫伤了我这样的有志青年的自信心.
JS采用的是单线程机制,所有的任务只能在一个线程上完成,前面的任务没有完成就只能等待。随着计算机计算能力的增强,多核处理器的出现,单线程已不能充分的发挥计算机的算力,WebWorker就是给主线程创建多线程的环境,实现主线程运行时,WebWorker线程在后台运行,两者互不干扰,待WebWorker线程任务完成后,将结果返回给主线程。
JS主线程和Worker线程的相同点和不同点
功能展示
假设主线程有三个任务需要执行 1000万次 3个任务就是3000万次,js都是单线程的,如果放在一个js里面执行必然会导致后面代码卡顿。
开启Worker 加载执行js解决问题
主线程代码 index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <button onclick="click_w()">点击</button> <body> <script> //假设这里有三个任务 每一个任务要执行2千次数 let list = ["第一个任务", "第二个任务", "第三个任务"]; //记录线程回来的数据 let rw_is = []; function click_w() { console.log("点击开始执行函数", new Date().getSeconds()); for (let item in list) { //执行第一个任务 let worker1 = new Worker('demo_workers.js'); //循环执行添加子任务 worker1.postMessage(list[item]); worker1.onmessage = function (e) { rw_is.push(e.data); worker1.terminate(); // 终止通信 }; } //添加监听线程处理结果 let set_t = setInterval(() => { if (rw_is.