先来了解一下跨域请求 使用CORS解决跨域请求
SpringBoot的跨域请求配置,在项目中添加以下配置类即可。
package com.example.util; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; /**配置全局跨域 * @author SMILE */ @Configuration public class CorsConfig { private CorsConfiguration buildConfig() { System.out.println("跨域配置。。。"); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用 corsConfiguration.addAllowedHeader("*"); // 2允许任何头 corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等) return corsConfiguration; } @Bean public CorsFilter corsFilter() { System.out.println("启动跨域方法。。。。。"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); // 4 return new CorsFilter(source); } }
打开以后发现别人打开的是完完整整的文字,自己打开确实很多乱码。解决方法如下:
1、打开控制面板,点击区域:设置为中文简体
2、打开管理,按以下步骤操作
3、重新开机
比赛题目训练系列18 (NWERC 2020) Atomic Energy
Atomic Energy 一个原子核在裂变
让原子核放出的能量最少. 现在给 t ( t ≤ 1 0 5 ) t(t \le 10^5) t(t≤105) 个测试, 每次询问的原子核的大小是 k ( k ≤ 1 0 9 ) k(k \le 10^9) k(k≤109).这个题和之前小米那个不一样。小米的是01背包。一开始优先选择性价比最优的,到达一定范围的时候,就开始跑暴力。因此暴力可以预处理,至于暴力的范围,可以猜一猜,至少这个题预处理出 n 2 n^2 n2 即可.这样做的原理是,前面跑暴力之后,后面会形成一个等差序列,然后找到最优的起点即可. #include<bits/stdc++.h> using namespace std; const int N = 21000; typedef long long ll; ll f[N], a[N]; int n, q; int main() { scanf("%d%d", &n, &q); for(int i = 1; i <= n; i++) scanf("
文章目录 具体需求建造者模式的四个角色建造者模式在JDK中的源码分析建造者模式的注意事项和细节抽象工厂VS建造者模式 具体需求 盖房子的需求:
需要建房子:这一过程为打桩、砌墙、封顶房子有各种各样的,比如普通房子,高楼,别墅,各种房子的过程虽然一样,但是要求不相同。 传统方式解决问题:
传统方式解决盖房需求问题分析:
设计的程序结构,过于简单,没有设计缓存层对象,程序的扩展和维护不好. 也就 是说,这种设计方案,把产品(即:房子) 和 创建产品的过程(即:建房子流程) 封 装在一起,耦合性增强了。解决方案:将产品和产品建造过程解耦 => 建造者模式. 建造者模式的四个角色 Product(产品角色):一个具体的产品对象Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类。CuncreteBuilder(具体建造者):实现接口,构建和装配各个部件Diector(指挥者):构建一个使用Builder接口的对象。他主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。 建造者模式盖房改进
指挥者
public class HouseDirector { Builder builder = null; //构造器传入 public HouseDirector(Builder builder) { this.builder = builder; } //通过Set方法传入 public void setBuilder(Builder builder) { this.builder = builder; } //如何处理建造房子的流程,交给指挥者 public House constructHouse(){ builder.buildBasic(); builder.buildWalls(); builder.roofed(); return builder.buildHouse(); } } 抽象建造者
public abstract class Builder { protected House house = new House(); //将建造的流程写好,抽象的方法 public abstract void buildBasic(); public abstract void buildWalls(); public abstract void roofed(); //建造房子,将产品返回 public House buildHouse(){ return house; } } 具体建造者
现在都还不知道有没有成功,因为网速变化莫测,不知端倪。查看了很多资料,基本上各种问题都出现了,因为作者们或漏了这个没讲或漏了那个没讲,一乱都乱更乱了。
好在这不是什么超级难题,面包总会有的。不急着用,上传又能怎么样。归纳一下几个要点。第一步,先要在github上面注册,有人说qq 邮箱可能收不到发来的信息,我反正是没遇到,就顺利用qq邮箱注册成功了,从邮箱点击连接,就这么注册了 。拖了一段时间,第二步,安装git,这个好像不难,随便就装了最新的版本。第三步,在上面创建一个项目,没有内容,只要名字和相关信息。说实在我是怕时间久了不去逛,给废了。第四步,加密钥。使用ssh,也成了。第五步,按照说明讲解上传,就是不行,因为提示说不能确定身份,大抵知道是没有验证好。第六步,学会输入邮箱和用户名的情况下产生密钥,并复制到自己的git账户上。之前的密钥无效,删除重来。第七步,还是不行,老是说已经有了源,那就删除那个东西。第八步,没看到有坏消息,好像就是好消息的意思,只是我现在还不能登录进去看到底成功了没有。感觉已经成功了。
这些问题在我收藏的资料里都有。其实无所谓,不成功,继续弄,就一件一件消掉它。
这个问题经常在各类面试中看到。一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
我们知道如果要写递归代码,那一定要先找到递归公式,这个找法,一个是画执行时的栈结构图来看,一个是从小到大来分析。我们看一下从小到大的过程:
从这里我们可以归纳出,递推公式是f(n)=f(n-1)+f(n-2),然后就可以根据三步走策略来写代码了:
1、确定递归函数功能
假设 f(n) 的功能是求青蛙跳上一个n级的台阶总共有多少种跳法,代码如下:
int f(int n){ } 2、找出递归结束的条件
求递归结束的条件,直接把 n 压缩到很小很小就行了,因为 n 越小,我们就越容易直观着算出 f(n) 的多少,所以当 n = 1时,你知道 f(1) 为多少吧?够直观吧?即 f(1) = 1。代码如下:
int f(int n){ if(n == 1){ return 1; } } 3.找出函数的等价关系式
每次跳的时候,青蛙可以跳一个台阶,也可以跳两个台阶,也就是每次跳的时候,小青蛙有两种跳法。
第一种跳法:第一次我跳了一个台阶,那么还剩下n-1个台阶还没跳,剩下的n-1个台阶的跳法有f(n-1)种。
第二种跳法:第一次跳了两个台阶,那么还剩下n-2个台阶还没,剩下的n-2个台阶的跳法有f(n-2)种。
所以,小青蛙的全部跳法就是这两种跳法之和了,即 f(n) = f(n-1) + f(n-2)。至此,等价关系式就求出来了。于是写出代码:
int f(int n){ if(n <=2 ){ return n; } return f(n-1) + f(n-2); } 代码看上去没问题对不对?其实是有和斐波那契数列一样的问题的,当 n = 2 时,显然会有 f(2) = f(1) + f(0)。我们知道,f(0) = 0,按道理是递归结束,不用继续往下调用的,但我们上面的代码逻辑中,会继续调用 f(0) = f(-1) + f(-2)。这会导致无限调用,进入死循环。
1. 问题概述 最近在git中使用commit,将文件暂存到本地库时,有时候会报下面的错误
$ git commit -v '第一次提交' error: pathspec '第一次提交' did not match any file(s) known to git 而通过 ‘git status’ 进程状态的查看是没有问题的,可以发现 git add xx 是成功的。
$ git status On branch master No commits yet Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: test1.c new file: test2.c new file: test3.c new file: test4.c 而我的git版本如下:
$ git version git version 2.31.1.windows.1 2. 问题解决方法 通过在论坛和百度上进行搜索,都没有得到一个有效的解决方式,但是我出现这个error的原因应该是在于:当前目录下的文件和前一个版本下的文件不同(即删除了一部分上一个版本中的部分文件),此时commit的时候就会报这个错。
hi 大家好,今天给大家推荐一些值得学习的开源项目,包括C, C++,Golang,Java等后台开发主流语言的项目,大家工作之余,可以花点时间学习和研究这些项目的优秀设计和实现,提高自己。
学习开源项目好处 首先是提升编程技能。对计算机专业相关的学生而言,在学习编程后,能验证能力的只是一些简单项目,但通过阅读开源项目的源码,你不仅可以学习顶级项目的设计思路,还可以学习顶级开发者的编程思路,比如通过学习提升代码的可读性和简洁性。同时,你也可以提交PR、注释,而社区里的资深工程师会给出直接反馈,这比你自己摸索要成长得更快。
其次能帮你找到满意的工作。如果你在开源项目上留下印记,无论是贡献代码、技术文档、应用案例等等,这些都能证明个人能力,甚至,有时你的简历只需放上GitHub个人账号链接就已足够:)
最后,开源也许会成为你热衷的事业。处在这样一个开源崛起的时代,尤其在国内很多顶级项目不断催生,现在正是那些热爱开源理念和开源软件的开发者大展鸿图的时候,他们有的在学生时代就已学习和贡献开源,开源世界为他们带来了荣誉和快乐,而他们在未来也致力于开发和运营开源软件。
总之,对于高校学生或者已经工作几年同学,只要你能通过开源项目的代码证明自己的实力,这无疑像是拿到了观看球赛的前排门票,你不会再因为“内卷”而发愁,因为你的前方视野足够辽阔。
想学习开源的同学,欢迎加入极客星球,让我们一起来学习开源项目,提高自己。
详细参考:极客星球
如何学习开源项目 首先了解整体架构
查找和阅读该项目的博客和资料,通过google你能找到某个项目大体介绍的博客,快速阅读一下就能对项目的目的、功能、基本使用有个大概的了解。
先把项目跑起来
如果该项目有提供现成的example工程,首先尝试按照开始文档的介绍运行example,如果运行顺利,那么恭喜你顺利开了个好头;如果遇到问题,首先尝试在项目的FAQ等文档里查找答案,再次,可以将问题(例如异常信息)当成关键词去搜索,查找相关的解决办法,你遇到了,别人一般也会遇到,热心的朋友会记录下解决的过程;最后,可以将问题提交到项目的邮件列表,请大家帮你看看。在没有成功运行example之前,不要尝试修改example。
如果时间允许,尝试从源码构建该项目。通常开源项目都会提供一份构建指南,指导你如何搭建一个用于开发、调试和构建的环境。尝试构建一个版本。
阅读源码建议
(1)阅读源码之前,查看该项目是否提供架构和设计文档,阅读这些文档可以了解该项目的大体设计和结构,读源码的时候不会无从下手。
(2)阅读源码之前,一定要能构建并运行该项目,有个直观感受。
(3)阅读源码的第一步是抓主干,尝试理清一次正常运行的代码调用路径,这可以通过debug来观察运行时的变量和行为。修改源码加入日志和打印可以帮助你更好的理解源码。
(4)适当画图来帮助你理解源码,在理清主干后,可以将整个流程画成一张流程图或者标准的UML图,帮助记忆和下一步的阅读。
(5)挑选感兴趣的“枝干”代码来阅读,比如你对网络通讯感兴趣,就阅读网络层的代码,深入到实现细节,如它用了什么库,采用了什么设计模式,为什么这样做等。如果可以,debug细节代码。
(6)阅读源码的时候,重视单元测试,尝试去运行单元测试,基本上一个好的单元测试会将该代码的功能和边界描述清楚。
(7)在熟悉源码后,发现有可以改进的地方,有精力、有意愿可以向该项目的开发者提出改进的意见或者issue,甚至帮他修复和实现,参与该项目的发展。
开启自己的开源项目
通常在阅读文档和源码之后,你能对该项目有比较深入的了解了,但是该项目所在领域,你可能还想搜索相关的项目和资料,看看有没有其他的更好的项目或者解决方案。在广度和深度之间权衡。
C经典开源项目 1.Libev
libev是一个全功能和高性能的事件驱动库,基于epoll,kqueue等OS提供的基础设施。其以高效出名,它可以将IO事件,定时器,和信号统一起来,统一放在事件处理这一套框架下处理。基于Reactor模式,效率较高,并且代码精简(4.15版本8000多行),是学习事件驱动编程的很好的资源。
特点
不使用全局变量,而是每个函数都有一个循环上下文。
对每种事件类型使用小的观察器(一个I/O观察器在x86_64机器上使用56字节,而用libevent的话使用136字节)。
没有http库等组件。libev的功能非常少。
允许更多事件类型,例如基于wall clock或者单调时间的定时器、线程间中断等等。
更简单地说,libev的设计遵循UNIX工具箱的哲学,尽可能好地只做一件事。
整体架构:
开源地址:
https://github.com/enki/libev
2. Redis
Redis 是一种经典的开源内存Key-Value数据结构存储,用作数据库、缓存和消息代理。Redis 提供了数据结构,例如字符串、散列、列表、集合、带有范围查询的排序集合、位图、超级日志、地理空间索引和流。Redis 内置复制、Lua 脚本、LRU 驱逐、事务和不同级别的磁盘持久化,并通过 Redis Sentinel 和 Redis Cluster 自动分区提供高可用性。
代码架构:
开源地址:
https://github.com/redis/redis
3. Nginx
Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。
特点:
Nginx可以部署在网络上使用FastCGI脚本、SCGI处理程序、WSGI应用服务器或Phusion Passenger模块的动态HTTP内容,并可作为软件负载均衡器。
Nginx使用异步事件驱动的方法来处理请求。Nginx的模块化事件驱动架构可以在高负载下提供更可预测的性能。
Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(≤2.2)的Apache不同,Nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑从而削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。在Linux操作系统下,Nginx使用epoll事件模型,得益于此,Nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue。
整体架构:
开源地址:
https://github.com/nginx/nginx
4.SQLite
SQLite是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。其特点是高度便携、使用方便、结构紧凑、高效、可靠。足够小,大致3万行C代码,250K。
说明:此次演示基于windows10系统
第一步:在任务管理器中关闭oracle的所有服务
第二步:找到卸载程序
第三步:点击“卸载产品”
第四步:勾选目录(注意:第一个没勾选,在这里卸载不了)
第五步:点击“删除”
第六步:点击“是”
第七步:等待即可
第八步:关闭对话框
第九步:关闭窗口
第十步:点击“是”
第十一步:打开注册表
第十二步:找到指定目录
第十三步:删除ORACLE目录
第十四步:找到指定目录
第十五步:删除所有以oracle开头的
第十六步:找到指定目录
第十七步:找到指定目录
第十八步:删除所有以oracle开头的
第十九步:删除所有以oracle开头的
第二十步:重启电脑
第二十一步:删除安装目录
第二十二步:验证
在cmd中输入sqlplus即可,不能登录,即出现错误信息,说明oracle11g卸载成功。
下一篇博客:手把手教你安装oracle11g
一、矩阵操作用于计算余弦相似度 余弦相似度:
我们知道,分子是矩阵的乘法,分母是两个标量的乘积。分母好办,关键是如何在计算分子?很简单,我们可以将公式变变形:
那么我们只需在矩阵乘法前,使其归一化,乘法之后就是余弦相似度了,来看一下代码(参考:https://zhuanlan.zhihu.com/p/383675457)
import torch ##计算两个特征的余弦相似度 def normalize(x, axis=-1): x = 1. * x / (torch.norm(x, 2, axis, keepdim=True).expand_as(x) + 1e-12) return x ##特征向量a a=torch.rand(4,512) ##特征向量b b=torch.rand(6,512) ##特征向量进行归一化 a,b=normalize(a),normalize(b) ##矩阵乘法求余弦相似度 cos=1-torch.mm(a,b.permute(1,0)) cos.shape #输出 torch.Size([4, 6]) 我们来逐行解析一下这段代码吧。
x = 1. * x / (torch.norm(x, 2, axis, keepdim=True).expand_as(x) + 1e-12) 这是归一化的公式,为什么是这个公式,我也不太明白。不过不妨碍我们解析。看到 torch.norm(x, 2, axis, keepdim=True) ,这是一个非常重要的知识点:torch.norm( input, p, din, out = None, keepdim = False )该函数的功能是求指定维度上的范数;其次看到 expand_as(tensor)函数,这是将张量scale扩展为参数tensor的大小。我这么说可能不太明白?那就糊涂着吧。
##特征向量a a=torch.rand(4,512) ##特征向量b b=torch.
SpringBoot+Mybatis集成neo4j 1 maven依赖 <dependency> <groupId>org.neo4j</groupId> <artifactId>neo4j-jdbc-driver</artifactId> <version>3.4.0</version> </dependency> 2 配置文件 spring: datasource: druid: driver-class-name: org.neo4j.jdbc.http.HttpDriver url: jdbc:neo4j:http://localhost:7474 username: neo4j password: 123456 validation-query: MATCH (n) RETURN COUNT(n) 3 在SpringBoot的启动类的入口中添加配置 public static void main(String[] args) { // BoltConnector DruidConnectionHolder.holdabilityUnsupported = true; SpringApplication.run(Neo4jProjectPlusApplication.class, args); } 4 创建dao层文件 <mapper namespace="io.renren.dao.Neo4jPlusBaseDao"> <select id="getTripleList" resultType="java.lang.Object"> START n1= node(*) MATCH p = (n1)-[r]->(n2) WHERE 1 = 1 RETURN p </select> </mapper> @Mapper public interface Neo4jPlusBaseDao { List<Object[]> getTripleList(); } 5 创建service public interface Neo4jPlusBaseService { Map<String, Object> getTripleList(); } @Service public class Neo4jPlusBaseServiceImpl implements Neo4jPlusBaseService { // @Autowired // protected M baseDao; @Autowired private Neo4jPlusBaseDao neo4jPlusBaseDao; public Map<String, Object> getTripleList() { List<Map<String, Object>> triples = new ArrayList<>(); List<Object[]> list = neo4jPlusBaseDao.
在我们的前端开发中,使用CSS的原生滚动条在移动端响应效果非常差,我们需要使用其它工具来设置它的滚动效果。better-scroll就是很好用的一个移动端滚动插件。
先附better-scroll的官方文档 点击这里
目录 linux下启动nacos报错:报错信息:解决方案 linux下启动nacos报错: Error: Could not find or load main class Caused by: java.lang.ClassNotFoundException 我的环境为centos7+jdk17+nacos2.0.3,原本以为是jdk版本太高的缘故。百度了以下大多数这样的问题都与jdk版本无关。
报错信息: 启动nacos:
在nacos/bin目录下输入下面命令
sh startup.sh -m standalone 报错信息:
输入启动命令后,没有见到熟悉的nacos启动界面,反而出现的的是
让我看/logs/start.out的日志
解决方案 日志是这样的,仔细看下日志的前半部分,不就是启动命令嘛。
java -Xms512m -Xmx512m -Xmn256m -Dnacos.standalone=true -Dnacos.member.list= -Xlog:gc*:file=/usr/software/nacos/nacos/logs/nacos_gc.log:time,tags:filecount=10,filesize=102400 -Dloader.path=/usr/software/nacos/nacos/plugins/health,/usr/software/nacos/nacos/plugins/cmdb -Dnacos.home=/usr/software/nacos/nacos -jar /usr/software/nacos/nacos/target/nacos-server.jar --spring.config.additional-location=file:/usr/software/nacos/nacos/conf/ --logging.config=/usr/software/nacos/nacos/conf/nacos-logback.xml --server.max-http-header-size=524288 把命令复制以下,使用这个命令在bin目录下启动nacos
可以看到nacos已经成功启动了。
如果已经暴露了端口就可以通过Ip访问了,如果没有暴露端口通过以下命令暴露端口:
firewall-cmd --permanent --add-port=8848/tcp firewall-cmd --reload
文章目录 1.基本概念1.1.B树的引进1.2.B树的定义1.3.B树的举例 2.B+树3.B*树4.总结 1.基本概念 1.1.B树的引进 我们发现,之前的二叉树、AVL,2-3树…这些树每一个节点所存储的数值量就只有一个,而这个数据量(键值)的目的是进行比较的,因为结合了数组和链表的操作,所以在进行排序的时候非常的方便。但是这种数据结构在数据库中查找数据或者是说对大容量设备,比如磁盘,SD卡,并不起作用。因此,B树诞生了。B 树是为了磁盘或其它存储设备而设计的一种多叉平衡查找树。也就是说B树中每一个节点所包含的键值数量比较多, 而它的作用不仅仅是为了比较大小,而是当作索引,用作方向标,一层一层地递推指向数据最后的数据存储位置。也可以把B树当做是2-3树的加强版!
你会发现B树的实现确实是将B树中的键值用作比大小的对象,但是实际上远远不至于比大小,像文件系统的分类,磁盘设备的管理都可以用B树以及变种,那么B树中的键值可以把它当作方向标,当作索引来看。
1.2.B树的定义 定义任意非叶子节点最多可以有M个儿子节点,且M>2根节点的儿子数为:[2,M]除根节点为的非叶子节点的儿子数为[M/2,M]每个结点存放至少M/2 - 1 (去上整)且至多M -1 个关键字,(至少为2)非叶子结点的关键字个数 = 指向子节点的指针数 -1非叶子节点的关键字:K[1],K[2],K[3],…,K[M-1],且K[i] < K[i +1] (升序排列)非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树所有叶子结点位于同一层 B-树就是B树(可能有部分人会习惯上把B-树读为B减树,其实并不存在B减树,只是读法上的不同而已),B就是balanced,平衡的意思。B-树就是指的B树,特此说明一下。
1.3.B树的举例 上图所示就是一副M等于3的B树。
B-树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果
命中则结束,否则进入查询关键字所属范围的儿子结点。重复,直到所对应的儿子指针为
空,或已经是叶子结点;
B-树的特性:
关键字集合分布在整颗树中任何一个关键字出现且只出现在一个结点中搜索有可能在非叶子结点结束其搜索性能等价于在关键字全集内做一次二分查找自动层次控制; 2.B+树 B+树是B-树的变体,也是一种多路搜索树:其定义基本与B-树相同,除了:
非叶子结点的子树指针与关键字个数相同
非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树(B-树是开区间)
为所有叶子结点增加一个链指针
所有关键字都在叶子结点出现
B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在
非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;
B+树的特性:
所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的
不可能在非叶子结点命中
非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层
B+树的意图非常的明显,直接就是把键值当作成方向标
3.B*树 B*树是B+树一种变形,它是在B+树的基础上,将索引层以指针连接起来,使搜索取值更加快捷。
B*树的作用我觉得就是在相邻节点中有一个索引方向,方向也是按照升序的方式,这样的话对数据的操作灵活性更强了。
4.总结 B(B-)树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键字范围的子结点, 所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中
B+树:在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点
中出现,非叶子结点作为叶子结点的索引,B+树总是到叶子结点才命中
B*树:在B+树基础上,为非叶子结点也增加链表指针,将结点的最低利用率
从1/2提高到2/3
文章目录 1.基本概念1.1. 2-3树引进1.2. 2-3树定义1.3. 2-3举例 2.2-3树的性质3.2-3树的操作3.1.数的遍历3.2.树的插入3.2.1.向2-节点中插入元素;3.2.2.向一颗只含有一个3-节点的树中插入元素;3.2.3.向一个父节点为2-节点的3-节点中插入元素;3.2.4.向一个父节点为3-节点的3-节点中插入元素。 3.3.树的删除 总结 1.基本概念 1.1. 2-3树引进 二叉搜索树在最好的情况下搜索的时间复杂度为 O(logn) ,但如果插入节点时,插入元素序列本身就是有序的,那么BST树就退化成一个线性表了,搜索的时间复杂度为 O(n)。
如果想要减少比较次数,就需要降低树的高度。在插入和删除节点时,要保证插入节点后不能使叶子节点之间的深度之差大于 1,这样就能保证整棵树的深度最小,这就是AVL 树解决 BST 搜索性能降低的策略。
但由于每次插入或删除节点后,都可能会破坏 AVL 的平衡,而要动态保证 AVL 的平衡需要很多操作,这些操作会影响整个数据结构的性能,除非是在树的结构变化特别少的情形下,否则 AVL 树平衡带来的搜索性能提升有可能还不足为了平衡树所带来的性能损耗。
2-3树是为了解决平衡二叉树插入删除的过程中为了维护平衡因子而消耗大量计算资源的问题 1.2. 2-3树定义 2-3 树要么为空要么具有以下性质:
对于 2节点,和普通的 BST 节点一样,有一个数据域和两个子节点指针,两个子节点要么为空,要么也是一个2-3树,当前节点的数据的值要大于左子树中所有节点的数据,要小于右子树中所有节点的数据对于3节点,有两个数据域 a 和 b 和三个子节点指针,左子树中所有的节点数据要小于a,中子树中所有节点数据要大于 a 而小于 b ,右子树中所有节点数据要大于 b 对于一棵2-3树而言,树中节点可以分为2节点和3节点。这里的节点是指该节点的儿子节点的个数!
1.3. 2-3举例 如上图所示就是一棵2-3树。
在这棵树中既有2节点又有3节点!
2.2-3树的性质 对于每一个结点有 1 或者 2 个关键码键值当节点有一个关键码的时,节点有 2 个子树当节点有 2 个关键码时,节点有 3 个子树所有叶子点都在树的同一层在树种没有相同的值 上图就是一颗典型的2-3树。
3.2-3树的操作 3.1.数的遍历 2-3树的查找类似二分搜索树的查找,根据元素的大小来决定查找的方向。要判断一个元素是否存在,我们先将待查找元素和根节点比较,如果它和其中任意一个相等,那查找命中,否则根据比较的结果来选择查找的方向。
2-3树的遍历和二叉搜索树的遍历是相同的。
在查找的过程中,只有递推,没有回溯!
也就是说终止条件为NULL。如果向下递归的过程中找到了NULL,那么就说明没有命中,待查找的树中并没有待查找的元素。
如今的社会已经从IT时代过渡到了DT时代,数据的重要性不言而喻。将数据安全快速的传输给对方是一件非常重要的事情,如今诞生了很多不同的传输技术,每一种传输技术都是为了和对方进行数据交互。BLE技术也是这样,它的最终目的就是为了在两个设备间进行数据交互。我们从BLE的本质出发,搞清楚它是如何实现数据交互的,也就真正搞清楚了BLE的工作原理。
下面从3个方面,逐步讲解BLE的数据收发过程。
本文结合nordic的代码和蓝牙核心规范5.2来进行介绍。本文认为你对BLE协议栈的各个层已经有了一个大概认识,对BLE协议栈还不太熟悉的朋友可以参看拙作:蓝牙低功耗(BLE)协议栈
一 广播 1.1 从设备 从设备想要别人能够发现自己就需要不停的进行广播。
Host层通过HCI层定义的接口来设置广播数据。
HCI层的命令格式如下图:
设置广播数据的命令格式如下图:
指令详细介绍参看:蓝牙核心卷 5.2 , Vol 4, Part E, 7.8.7
OpCode,0x0008,两个字节parameter Total Length,一个字节,也就是Advertising_Data_Length,根据Advertising_Data计算得来Advertising_Data, 由HCI 以上层传下来 事实上只有Advertising_Data会通过空中发送。Advertising_Data的格式如下:
详细介绍参看:蓝牙核心卷 5.2 , Vol 3, Part C, 11
可以看到广播数据可能有多个元素:AD Structure 1,AD Structure 2 … AD Structure N,每一个AD Structure的格式为,1个字节长度,一个字节AD Type,n个字节的AD Data。广播数据包也遵循一定的格式,广播包的数据格式参看:AD Type和Core Specification Supplement
LL层定义的广播报文的格式如下图:
详细介绍参看:蓝牙核心卷 5.2 , Vol 6, Part B, 2.3
用户设置广播参数和广播内容
ble_gap.h //设置广播参数,以及广播类容 uint32_t sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params) 设置广播参数,ocf=0x006,ogf=0x08
const a = [1,2,3,4]; const b = [5,6,7]; a.push(...b);//...b是数组解构的一种语法,它用于将组件b中的元素挨个取出来。最终结果相当于a.push(5,6,7) console.log(a);
打包vue项目 npm run build / yarn build 此时工程根目录下多出一个 dist 文件夹, 其它项目也可以只要打包好静态文件就行Nginx 是一个高性能的 HTTP 和反向代理服务器,此处我们选用 Nginx 镜像作为基础来构建我们的vue应用镜像。在项目根目录下创建 nginx 文件夹,该文件夹下新建文件 default.conf, 写入如下配置proxy_pass 需改成请求的地址,如果请求地址没有api就重写为空,否则不用 rewrite server { listen 80; server_name localhost; #charset koi8-r; access_log /var/log/nginx/host.access.log main; error_log /var/log/nginx/error.log error; location / { root /usr/share/nginx/html; index index.html index.htm; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } location /api/ { proxy_pass http://192.
post请求出现 "status": 400, "error": "Bad Request" 1、出错信息2、springboot代码3、解决方法 1、出错信息 post:http://localhost:8080/stu/create
"timestamp": "2021-12-28T09:56:13.741+00:00", "status": 400, "error": "Bad Request", "path": "/stu/create" 2、springboot代码 @PostMapping("create") public String createStu(@RequestBody Map<String, Object> map,@RequestHeader("token") String token, @CookieValue("clientId") String clientId, HttpServletRequest request) { log.info("map = " + map.toString()); log.info("clientId = " + clientId); log.info("token = " + token); String header = request.getHeader("token"); log.info("header = " + header); return "新增Stu"; } 3、解决方法 在保证代码没有出错的情况下,排查出的问题是cookie,在postman中添加cookie时,发现名字错误,将名字改为localhost,问题解决。
使用EasyExcel生产excel时,如果使用动态头当头部单元格的值相同时会产生单元格自动合并的问题,有可能我们是不需要去做自动合并的,但是EasyExcel官网又没有提供如何防止自动头合并的解决措施。那就只有从代码当中去找了。
测试代码如下 public class Test { @org.junit.Test public void dynamicHeadWrite() { String fileName ="dynamicHeadWrite" + System.currentTimeMillis() + ".xlsx"; EasyExcel.write(fileName) // 这里放入动态头 .head(head()).sheet("模板") // 当然这里数据也可以用 List<List<String>> 去传入 .doWrite(data()); } private List data() { return new ArrayList(); } private List<List<String>> head() { List<List<String>> list = new ArrayList<List<String>>(); List<String> head0 = new ArrayList<String>(); head0.add("字符串"); List<String> head1 = new ArrayList<String>(); head1.add("字符串"); List<String> head2 = new ArrayList<String>(); head2.add("日期" + System.currentTimeMillis()); list.add(head0); list.add(head1); list.add(head2); return list; } } 运行效果如图,可以看到已经做了自动合并了
邮箱发送 要在网上实现邮件功能,需有专门的邮件服务器。
这些邮件服务器类似生活中的邮局,主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中。
SMTP服务器地址:一般是smtp.xxx.com,比如163邮箱是smtp.163.com,qq邮箱是smtp.qq.com
电子邮箱(E-Mail地址)的获得需要在邮件服务器上进行申请。比如我们要使用QQ邮箱,就需要开通邮箱功能。
邮件发送原理图 下载依赖 mail-1.4.7.jaractivation-1.1.1.jar <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.activation/activation --> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> 授权码的获取 设置 -> 账户 -> POP3/SMTP服务 -> 开启 -> 密保手机验证即可->开启成功
简易文本邮件发送实现 由上图我们可以确定几个必须步骤
1.创建session对象
2.创建Transport对象
3.使用邮箱的用户名和授权码连上邮件服务器
4.创建一个Message对象(需要传递session)
message需要指明发件人、收件人以及文件内容
5.发送邮件
6.关闭连接
编码 package com.hopeful.mail; import com.sun.mail.util.MailSSLSocketFactory; import javax.mail.*; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.security.GeneralSecurityException; import java.util.Properties; /** * MailDemo1 * kigdmdfveaymgfac * @author : yl * @version : [v1.
nacos 注册中心 部署安装nacos 我这里做的云服务器的nacos
直接用docker进行部署
这里使用的是nacos 1.4.2
*(使用nacos 2.的话,需要多开放两个端口,且开放端口要和8848对应端口偏移量1000和1001)
首先拉取nacos 1.4.2,要指定版本,不然拉取的最新版本是2版本
docker pull nacos/nacos-server:1.4.2 docker run --env MODE=standalone --name nacos -d -p 8848:8848 nacos/nacos-server:1.4.2 这样就完成安装nacos,这里没有做过多的配置
浏览器输入ip:port/nacos即可访问
账户密码
nacos/nacos
项目配置 我用的springcloud和springcloud alibaba以及springboot版本如下
<!-- 指定SpringBoot版本 --> <spring-boot.version>2.3.2.RELEASE</spring-boot.version> <!-- 指定SpringCloud版本 --> <spring-cloud.version>Hoxton.SR9</spring-cloud.version> <!-- 指定SpringCloudAlibaba版本 --> <spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version> 创建一个微服务模块
这里省略创建过程
在微服务模块需要引入依赖
<!-- 该依赖是确保bootstrap配置文件生效 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> </dependency> <!-- nacos客户端依赖包 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> 然后在配置文件中配置nacos的地址即可
spring: application: name: order-service cloud: nacos: discovery: server-addr: ip:port 这样就完成nacos注册中心的配置
Vue本地存储(3种) ① localStorage(长期存储)
存:localStorage.setitem('key',data)
取:localStorage.getitem('key')
② sessionStorage(临时存储)
存:sessionStorage.setitem('key',data)
取:sessionStorage.getitem('key')
③ cookie(有时效性)
一、共同点: ①都可以存储,并且存储只跟域名走、只存储在当前域名下。 二、不同点: ▶存储大小不同 ①localStoage/sessionStorage /5M ②cookie /4K 有时效性 如果没有设置时间会话关闭自动失效 ③localStorage/不主动删除,数据一直在。 ④sessionStorage/在浏览器打开期间存在,关闭当前会话即清空(刷新不清除) sessionStorage和localStorage用法基本一致,引用类型的值需要转换成Json,我这里用localstorage来举例。
vue介绍: vuex是专门为Vue.js应用程序开发的状态管理模式。它采用集中式存储,管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 一、Vuex的五个属性 state:存放公共数据
getters:vuex的计算属性,对state里的变量进行过滤。
mutations:唯一可以改变state数据的工具,相当于vue里的methods。
使用commit调用
actives:异步操作
使用dispath调用
modules:模块化
防止我们在state里写的东西太多,不好进行查找和维护,所以我们可以在modules里面定义一个模块,里面也有我们vuex的五个属性,操作方式也一样。
修改配置文件,加上参数:server.port=8014
或者: server:
port: 8014
启动后可发现tomcat运行在端口8014上了。
实现原因可看以下链接:
【转载】SpringBoot修改默认端口号 - 空の彼方 - 博客园
项目场景: ArcGIS JavaScript API 基于dojo框架,在dojo中,除了沿用Dom结点, dojo 还自定义了一类结点用“dojoType" 进行标识。dojo 称这些结点为widget。我们在向地图中添加一些控件时,这些控件其实就是widget.
问题描述: 这样在程序中有时候注册ID的时候,我们注册的widget,在第二次重复使用的时候,会出现如下错误:
Tried to register widget with id==“measurementDiv” but that id is already registered
修改前代码:
var measurement = new Measurement({ map: map, defaultAreaUnit: Units.SQUARE_METERS,//测面积 defaultLengthUnit: Units.METERS//测距离 }, dom.byId("measurementDiv")); measurement.startup(); 解决方案: 先把注册的销毁,然后再创建一个相同id的容器
修改后代码:
if(registry.byId("measurementDiv")){ registry.byId("measurementDiv").destroy(); } var measurement = new Measurement({ map: map, defaultAreaUnit: Units.SQUARE_METERS,//测面积 defaultLengthUnit: Units.METERS//测距离 }, dom.byId("measurementDiv")); measurement.startup();
我们能够通过网络进行一些前奏性的学习,但是深入的学习,还是要书本和系统化的深入。就图像而论,如下的基本问题是我们展开深入学习研究的出发点:
一,一般来说一张适宜的图片的像素是3000-5000,过小会不清晰,过大会造成资源的浪费。我习惯于使用4976*3508的标准图片。
二,理论上说,任何图像的处理都可以建立在对标准图片的全部像素的遍历上。既然我们能遍历每一个像素,那么所有的问题都应该是基于这个遍历能操作的。例如我们要求图像的某个区域的边界,只要描述清楚条件,就可以分出这些点。分出这些点,就可以赋给它们某种rgb值,也就是画出这条边界。我们可以试验,一般单张图片上 的处理,好像就是用python的逐点循环也是可行的,大约分吧钟而已。这使得我们基本上能对任何问题进行测试研究了。但是从实际上要面对大量复杂的计算看,还是要讲效率。例如遍历,就应该用Numpy的np.where。能用numpy的一定要用Numpy,几乎很多复杂的关于大量点的操作都是可以用Numpy表达的,例如方差计算。我们不能直接计算,而是要使用Numpy的算法。这就告诉我们,必须耐心学习基本的Numpy知识。Numpy是人们已经研究清楚的优化成果,比我们学过的一般性的矩阵运算更有实用的价值。
三,除了Numpy的优化,另有一个天然的优化法则就是压缩像素到更小的图片。这样就自然地抓到了关键点。例如,图像上的一段边界曲线,我们不需要记录所有点,而应该先把握其中最关键的几个点,由其中几个点再把握局部区域的几个关键点,逐渐用少量的点控制大量的点。就跟人的领导原则一样,金字塔原则控制所有点。获得这些关键点的自然的办法就是先压缩到较小像素,逐级获得相关于不同整体层次的关键点,以关键点控制所有点。
四,还有,同一层级,即同一压缩图像的不同区域,是不相同的。我们未必要对每个区域进行同样复杂的计算分析,而是要对其中的主要的关键区域进行分析,这样我们实际上不是机械的一个一个来找它们,而是按照整体的需要找到最重要 的几个拟合。如果精度不够,那就还要增加一些考察的对象,但是我们不需要对每个对象都同等分析。好比我们去找一个学术泰斗,首先要把小孩和一般的市井之人去掉,将目光放在大学上,然后对大学又进行分类分析,这样就能更快地搜索到该目标点。相比之下,一个一个地在各行各业去筛选就很low了。
五,一般来说,pillow适合处理通常的情况,cv2适合很精确的情况。为了建立离散和连续的稳固可靠的联系,可以设想将它们和CAD结合起来。因为后者对于连续函数和三维空间的操作有着极强的适应性。python的厉害就在于它能将各种软件串起来无缝衔接。如果我们要研究人体的标准数据,难以想象前面说的pillow和cv2能够胜任。我们甚至能将图像投射到CAD中,从而每条连续函数曲线都自然地对应了。
六,让我们自己来试验研究各种相关的最基本的问题。例如图像的边界,图像中出现的杂色点怎么清除,怎么分出内外。理清最基本的事实更有助于学习各种软件的相关命令。
存储过程 1. 创建存储过程 ''' delimiter 自定义结束符号 create procedure 储存名([ in ,out ,inout ] 参数名 数据类形...) begin sql语句 end 自定义的结束符合 delimiter ; ''' delimiter $$ create procedure proc01() begin select empno,ename from emp; end $$ delimiter ; -- 调用存储过程 call proc01(); 2. 变量定义 2.1 局部变量 用户自定义,在begin/end块中有效
''' 语法: 声明变量 declare var_name type [default var_value]; 举例:declare nickname varchar(32); ''' delimiter $$ create procedure proc02() begin declare var_name01 varchar(20) default ‘aaa’; -- 定义局部变量 set var_name01 = ‘zhangsan’; select var_name01; end $$ delimiter ; -- 调用存储过程 call proc02(); MySQL 中还可以使用 SELECT…INTO 语句为变量赋值。其基本语法如下:
#include <Powrprof.h> #pragma comment(lib,"PowrProf.lib")
DWORD lockTime = 0;
void SetPowerPolicy()
{
SYSTEM_POWER_POLICY spp = { 0 };
CallNtPowerInformation(SystemPowerPolicyAc, NULL, 0, &spp, sizeof(spp)); //get power information
spp.IdleTimeout = 600;
spp.VideoTimeout = 600;
CallNtPowerInformation(SystemPowerPolicyAc, &spp, sizeof(spp), NULL, 0); //set new power information
}
事情由来 我司需要对接google支付来实现订阅机制,这时候购买了订阅产品的用户是需要维护订阅的状态的, google 提供了两个解决方案: 1. 通过定时任务调用查询api去查询订阅用户的状态,但是google对这些api做了每天6000次的 频控,这样就在请求数上掐脖子了。 2. 通过GCP的sub/pub机制去回调servier的api去维护订阅用户的状态 那么大家一眼就可以看出了肯定是选择第二种解决方案,因为这种解决方案没有任何限制而且将这种 任务交给google帮你去维护何乐而不为呢? 废话不多说现在看是步骤: 先打开google play console 点记设置里面的api 权限
点击授予访问权限
点击应用权限,把需要权限的应用添加进来
给应用添加相对应的权限, 我比较懒就直接管理员权限了。😊
点击账号权限赋予该账号相应的权限, 我比较懒就直接管理员权限了。😊 6. 打开google cloud platform(GCP),点击Pub/Sub
7. 在google play console developer 下面创建主题和订阅
8. 给主题和订阅设置权限,设置GP的账号权限和google-play-developer-notifications@system.gserviceaccount.com的权限
9. 打开google play选择app,打击创收设置。
10. 设置主题名称后点击测试
没有报错说明你的设置是成功的,如果报错说明权限设置的有问题。
测试订阅和主题发送消息 打开GCP 的主题的message,点击发送消息,订阅选择创建好的订阅
输入消息体点击发布
点击订阅里面消息,点拉取看看可否拉取到消息
如果收到消息,说明订阅和主题是通了,那么如果需要走推送只需要将订阅的pull 模式改成push模式即可。
在磁盘管理中,您可以删除和调整分区大小以实现此目标。但是,为了保证数据安全,在采取进一步步骤之前,需要执行分区卷备份或文件备份。接下来,删除该分区以生成未分配的空间,然后,将体积扩展到该空间。下面是合并C和D驱动器的详细步骤。
1. 备份或复制D盘上的文件到安全的地方。
2. 按“Win + R”打开运行对话框,输入“diskmgmt.msc”并按“Enter”键打开磁盘管理。
3. 右键单击D盘并选择“删除卷”,分区上的所有数据都将被擦除。
4. 您将获得一个未分配的空间。右键单击C盘并选择“扩展卷”,按照向导完成扩展。
5. 分区扩展完成后。现在,您可以将原来D盘中的文件还原到C盘。
注意:您只能合并同一物理硬盘上的两个相邻分区。C盘不能合并到D盘,因为它包含操作系统。
这种不删除数据合并分区方法虽然这有点迂回,但仍然可以实现合并分区。当然,如果您觉得麻烦,您可以使用其他更简单的方法来解决。
这个报错是因为我的char[] hexArray数组只有15个元素,加1个到16个就好了
public class MD5Util { /** * 加密 * @param origin * @return * @date 2021-12-27 16:24:50 */ public static String getMd5(String origin){ //自定义数组,相当于盐 char[] hexArray={ '5','2','2','1','2', '9','a','b','3','e', 'f','7','c','4','6' }; try { //把origin转换为为数组 byte[] originBytes = origin.getBytes(); MessageDigest md5 = MessageDigest.getInstance("MD5"); md5.update(originBytes); //加密后的数组 byte[] digest = md5.digest(); //定义返回加盐后的数组,*2是要确定能够放得下 char[] str=new char[digest.length*2]; int k =0; //对加密后的数组加盐 //首先判断加密后的数组长度,遍历数组,对每个元素进行以为运算 for (int i = 0; i < digest.length; i++) { byte b = digest[i]; str[k++]=hexArray[b>>>4&0xf];//对b进行移位运算,0xf表示16进制的15 str[k++]=hexArray[b&0xf]; } return new String(str); }catch (Exception e){ e.
写在前面 最近想根据自己平时的工作笔记和学习笔记,整理出一些JAVA专题类的系列文章。平时自己的笔记比较散,趁着这个机会进行系统化的整合一下,同时看到网上能形成体系化的知识点比较少,所以也趁着这个机会,整理、归纳、分享一下给大家。
专题的内容主要采用对话的形式,一个是学习热情高涨,爱好提问的小陈;一个是知识储备丰厚,工作多年且经验丰富的老王;文章的知识讲解主要是通过两人的对话展开。
工作以来和同事交谈过不少,也面试过不少人;但是感觉对于JAVA并发这块的整体知识,很难有人能形成一个比较完整的体系和脉络,比如JAVA并发工具类体系、线程池体系、AtomicInteger体系、Synchronized、volatile底层、内存模型等,很多兄弟都只是了解其中的某个点。
所以我根据之前自己对JAVA并发底层原理的学习、以及之前源码分析的笔记、流程图等,整理出一套比较完善的学习笔记,希望能对你学习并发有所帮助。
专题文章内容 我的笔记中对JAVA并发的学习路线按照修炼层次划分了几个阶段哈,分别为:筑基、炼气、结丹、金丹、元神、飞升等六大阶段哈,从最开始慢慢打好基础,然后逐步修炼,最终成为高手。嘿嘿,我废话不多说了,看一下下面的阶段内容介绍哈:
筑基 最开始的阶段当然是打好基础啦,所以啊我会从多核CPU多级缓存架构、JAVA内存模型、并发的可见性、有序性、原子性、MESI一致性等开始分析底层原理,以及带来了并发安全的什么问题?等先讲解和介绍一些基础的概念,这个阶段就是打基础用的。
练气 有了基础的概念之后,再来分析什么是volatile?什么是内存屏障?内存屏障怎么解决可见性和有序性的问题,以及volatile是怎么使用内存屏障的?
带你来分析一下Synchronized的底层原理是怎么样的?什么是对象头,对象头里面有什么信息?怎么通过对象头和Synchronized进行关联的?synchronized是怎么是加锁的?怎么保证并发安全的?怎么进行锁升级和优化的?
学好了这个阶段,相当在基础之上,并发的一些理解和功力慢慢变得深厚了。
结丹 有了上面筑基、练气的修炼之后,并发的功力慢慢变得深厚,随着修为的提升,进入并发的结丹境界。
在这个阶段会重点介绍JDK底层的unsafe类提供操作系统底层的功能,包括从内存级别CAS操作数据、从操作系统级别分配和释放内存、从操作系统级别阻塞和唤醒线程等功能。
还会从底层源码、实现机制讲解Atomic体系中非常常用的原子类,包括:AtomicInteger、AtomicBoolean是怎么通过volatile和cas机制实现的?从源码级别去分析同时画图理解。
介绍AtomicInteger、AtomicBoolean等简单原子类的缺点,存在ABA问题、高并发竞争导致大量线程自旋问题、无法做到多个变量同时更新的原子性问题等。
然后讲解AtomicReference 是怎么解决多变量更新的原子性问题的?AtomicStampReference怎么解决ABA问题的?LongAdder怎么使用分段解决高并发导致大量线程自旋问题的?等等....
学到这里,恭喜你,CAS操作的底层原理,Atomic体系的原子类底层的实现原理,你都一一了解了,并发修行进入了结丹境界,哈哈。
金丹 有了上面筑基、练气的底层知识基础,通过CAS底层原理、Atomic体系剖析进入结丹境界之后,下一阶段的修行就会非常重要了,那就是金丹期。在这个阶段我们会介绍JUC提供的JAVA并发工具的底层原理。
包括JAVA并发的核心AQS是个什么东西?AQS作为底层的一个并发框架到底实现了什么功能和机制,才能作为并发框架?
基于AQS实现的各种各样的并发工具ReentrantLock、CountDownLatch、Semaphore、ReentrantReadWriteLock等等,它们是怎么基于AQS来实现各种各样的功能的?上面的东西我们都会一个一个的进行源码级别的剖析、画图讲解。
学完了这一章节之后,JAVA并发工具的实现机制和底层原理对你来说已经不成问题了,你的并发功力也是十分深厚了,这一篇并发工具的底层原理是很多修炼者的瓶颈,学完这一章,直接让你的并发功力大增。
元神 学完了上面的篇章,并发功力大增之后;我们逐步开始修炼元神。
这一篇会讲解JUC中非常重要的一些并发安全的数据结构、包括CopyOnWriteArrayList底层是怎么是实现的,怎么通过写时复制提升并发性能?
ConcurrentLinkedQueue是怎么通过CAS无锁化操作提升并发性能的?
最经常讨论的ConcurrentHashMap是怎么通过分段锁机制提升并发性能的?
ArrayBlockedQueue、LinkedBlockedQueue等是怎么基于之前的ReentrantLock锁 + Condition机制实现阻塞唤醒的?
DelayQueue、SynchronousQueue等其它阻塞队列的剖析等
学完这一章节,相信你对JAVA并发的理解变得更加深入了,怎么通过之前的锁、CAS、volatile、synchronized等知识实现我们功能,这些并发安全的数据结构怎么通过之前的知识设计出来的?如果我们要实现并发安全的系统设计应该怎么做?到了这一阶段,好好学习,肯定会对你并发的设用和设计能力提升一大截。
飞升 修炼完上面的境界,相信你的JAVA并发的功力已经非常深厚,这个时候就能进入飞升境界了。
这一篇我们看看线程池底层是怎么设计和实现的?看看一些非常牛逼的人,是怎么运用并发知识设计出线程池这么一个牛逼的东西的?
包括线程池构造函数、每个参数的深入分析,每个参数是什么意思?一个32位的变量怎么使用不同的二进制位表示线程池数量和线程池状态的,对状态和数量的操控对应哪些方法?
往线程池提交任务的整体流程源码是怎么样的?
线程数量未达到核心数量时提交任务会怎么样?
达到核心数量会怎么样?阻塞队列满了会怎么样?线程数量达到最大数量会怎么样?
有哪些拒绝策略,怎么触发线程拒绝策略?
线程池中的Worker(工作者)的概念是什么?
当线程数量大于核心线程数的时候,怎么通过线程最大存活时间移除多余的线程的?
看看为啥不推荐使用Executors提供的创建线程池方式?
这一篇我们主要是来分析一下线程池底层实现原理是什么?看看顶尖的大佬是怎么设计出这么牛逼的线程池的?这一篇对你线程池原理的理解大有帮助,同时借鉴人家的设计思路,如果让你来实现可以做到吗?学完这一片相信你对JAVA并发的整体运用和理解能更加深入,设计思路和能力也很有帮助
最后,加油,修炼无止尽,继续努力,继续进步,祝各位道友修炼有得、不断进步。
关注小陈,公众号上更新更多的java并发文章
JAVA并发文章目录(公众号) JAVA并发专题 《筑基篇》 1.什么是CPU多级缓存模型?
2.什么是JAVA内存模型?
3.线程安全之可见性、有序性、原子性是什么?
4.什么是MESI缓存一致性协议?怎么解决并发的可见性问题?
JAVA并发专题《练气篇》 5.volatile怎么保证可见性?
6.什么是内存屏障?具有什么作用?
7.volatile怎么通过内存屏障保证可见性和有序性?
8.volatile为啥不能保证原子性?
9.synchronized 是个啥东西?应该怎
9.synchronized 是个啥东西?应该怎么使用?
10.synchronized底层之monitor、对象头、Mark Word?
11.synchronized底层是怎么通过monitor进行加锁的?
node执行js代码时同步获取用户通过键盘输入的值 安装 readline-sync模块
npm install readline-sync // 例:
const readline = require('readline-sync'); let name = readline.question("你叫什么名字?"); console.log("嗨"+name+",很高兴见到你。");
目的 想检测apriltag相较于棋盘格的位姿识别效果,便于手眼标定
安装环境
系统:ubuntu 18.04 内核
ROS: melodic
相机:intel realsense d435i
已安装相机驱动 librealsense 以及相机ROS Wrapper,相机能够正常工作
#1. 安装时需要将realsense相机拔掉 #2. 打开终端,依次输入以下命令行(见到Y/n,输入y即可) sudo apt-get update && sudo apt-get upgrade && sudo apt-get dist-upgrade sudo apt-get install git libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev sudo apt-get install libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev git clone https://github.com/IntelRealSense/librealsense.git cd librealsense/ sudo cp config/99-realsense-libusb.rules /etc/udev/rules.d/ sudo udevadm control --reload-rules && udevadm trigger ./scripts/patch-realsense-ubuntu-lts.sh echo 'hid_sensor_custom' | sudo tee -a /etc/modules mkdir build && cd build cmake .
pytorch实践中,有时提取出的层结构并不够,还需要对里面的参数进行初始化,那么如何提取出网络的参数并对其初始化呢?
有时候提取出的层结构并不够,还需要对里面的参数进行初始化,那么如何提取出网络的参数并对其初始化呢?
首先 nn.Module 里面有两个特别重要的关于参数的属性,分别是 named_parameters()和 parameters()。named_parameters() 是给出网络层的名字和参数的迭代器,parameters()会给出一个网络的全部参数的选代器。
import os import torch import torch.nn as nn import torch.optim as optim import torch.backends.cudnn as cudnn import torch.nn.init as init import argparse import torch.autograd.variable as variable class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN,self).__init__() #b,3,32,32 layer1=nn.Sequential() layer1.add_module('conv1',nn.Conv2d(in_channels=3,out_channels=32,kernel_size=3,stride=1,padding=1)) #b,32,32,32 layer1.add_module('relu1',nn.ReLU(True)) layer1.add_module('pool1',nn.MaxPool2d(2,2)) #b,32,16,16 self.layer1=layer1 layer2=nn.Sequential() layer1.add_module('conv2',nn.Conv2d(in_channels=32,out_channels=64,kernel_size=3,stride=1,padding=1)) #b,64,16,16 layer2.add_module('relu2',nn.ReLU(True)) layer2.add_module('pool2',nn.MaxPool2d(2,2)) #b,64,8,8 self.layer2=layer2 layer3=nn.Sequential() layer3.add_module('conv3', nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3 ,stride=1, padding = 1)) #b,128,8,8 layer3.add_module('relu3', nn.ReLU(True)) layer3.add_module('poo13', nn.MaxPool2d(2, 2))#b,128,4,4 self.
package com.test; /** * @Author: zhh * @Date: 2021/12/8 20:32 * @Description: */ public class ThreadLocalTest { static ThreadLocal<String> localVar = new ThreadLocal<>(); static void print(String str) { //打印当前线程中本地内存中本地变量的值 System.out.println(str + " :" + localVar.get()); //清除本地内存中的本地变量 localVar.remove(); } public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { //设置线程1中本地变量的值 localVar.set("localVar1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("before remove : "
采用notepad++,查看相关的log信息。发现搜索结果框,独立出来。而不是跟文本结合在一起。
网上搜索了不上方法。用alt+space,再拖动,无效。
结果采用双击一下find result框,恢复到原来的模式。
开始 最近有个需求,需要将微信小程序中一些页面和功能改成h5,这次功能开发的时间有点紧,而且重新写一套有点来不及。考虑到微信小程序与uni-app有着一些共通之处,所以打算直接转成uni-app。uni-app官网上也有从微信小程序项目转uni-app的教程:https://github.com/zhangdaren/miniprogram-to-uniapp ,
不过我这里直接用上了大佬开源的miniprogram-to-uniapp转换工具。
github: https://github.com/zhangdaren/miniprogram-to-uniapp
教程:https://ask.dcloud.net.cn/article/36037
使用MINIPROGRAM-TO-UNIAPP 直接全局安装 npm install miniprogram-to-uniapp - g 因为工具更新的比较频繁,所以安装后建议更新 npm update miniprogram-to-uniapp -g 转换微信小程序项目,顺带将wx.xx转为uni.xxx。具体可以查看文档 wtu -i 'E:\project\miniprogram-project' -r 转换成功后,会在项目同级目录下生成一个miniprogram-project_uni的目录 转换后的一些问题 小程序的bingtap会转成@tap,问题不大,不过最好改成@click。组件上的动态props参数没有通过v-bind绑定小程序的自定义组件,props是可以在子组件内修改的, 但是转成uni-app是不能直接在子组件修改props。子组件内,工具转换后的this.setData的兼容方法,更新值的时候不会触发watch,要把this.setData改回vue的this.xxx=xxx;@catchtouchmove的防止触摸穿透,可以改成@touchmove.stop.prevent=“moveHandle”hidden="hidden"改成v-show图片的路径在转换中可能也会出错本地调试时调用接口会出现跨域。可以在manifest.json文件源码视图,配置h5的devServer: "h5": { "devServer": { "port" : 80, "disableHostCheck" : true, // 跳过host检查 "proxy" : { "/api" : { "target" : "https://abc.com", // 目标域名 "changeOrigin" : true, // 允许跨域 "secure" : false,// 设置支持https协议的代理 "ws" : false,//没有该配置将出现:WebSocket connection to ws 错误提示 "pathRewrite" : { //如果不希望传递/api,则需要重写路径 "
2021SC@SDUSC
ROS源代码阅读(13)
这篇我们主要看一下插件机制(Plugin)
使用Plugin可以更加方便对一个节点、功能包进行修改,添加功能,而无需修改此节点、功能包的源代码,大大提升了代码复用的能力。
官方的解释是:pluginlib是一个C++库,用于从ROS包中加载和卸载插件。插件是从运行库(即共享对象、动态链接库)加载的动态可加载类。使用 pluginlib 时,您不必显式将其应用程序与包含类的库关联起来——相反, pluginlib 可以在任何时候打开包含导出类的库,而应用程序无需事先意识到库或包含类定义的标头文件。插件可用于扩展/修改应用程序行为,而无需应用程序源代码
ROS中应用Plugin的一个例子是在 move_base 节点中,通过插件机制选择不同的 Global planner Local planner 和 Recovery behavior,为什么要选择不同的planner? 因为plan的算法有很多种,常见的规划算法就有A*、Dj等,所以需要使用插件机制方便不同算法下的planner进行切换。
我们可以看Plugin的实现:
#include <pluginlib>/class_list_macros.h PLUGINLIB_EXPORT_CLASS(plugin class, base class) 申明基类,确定接口,注意基类的构造函数的参数应为空,所以为了对基类进行初始化,应该使用 如 initialized()等函数进行类的初始化,若使用已有接口类,则省略此步骤,创建插件,插件多以类的形式出现,所以即创建插件类,该类需要继承基类,并覆盖基类的共有接口。插件注册,通过使用Pluginlib中的宏定义,对新创建的插件进行注册
include_directories(include) add_library(my_plugins_lib src/my_plugins.cpp) 这里修改CMakeList文件,添加内容,构建插件动态链接库
<library path="lib/libmy_plugins_lib"> <class name="{plugin class name}" type="{plugin class type}" base_class_type="{base class type}"> <description>This is an example.</description> </class> </library> 编译文件,在devel/lib中生成库文件libmy_plugins_lib
添加插件描述文件 my_plugins.xml
<export> <{base_class_package_name} plugin="${prefix}/my_plugins.xml"/> </export> 为了使Pluginlib在ROS的所有功能包中查询到plugin,需要在每个功能包中指出该功能包导出了哪些plugin和哪些功能包使用这些plugin
<build_depend>base_class_package_name</build_depend> <run_depend>base_class_package_name</run_depend> 在plugin所在功能包的package.xml中添加对基类的依赖
这样,一个plugin就实现了,下面我们看一下move_base对插件的使用
#include <pluginlib/class_loader.h> #include <nav_core/base_local_planner.h> //base class #include <nav_core/base_global_planner.
将ORB SLAM3修改成了Mac上能运行的版本,但是存在加载词库特别慢的问题。通常需要二十多分钟才加载完毕。一直卡在Loading ORB Vocabulary. This could take a while..阶段。
逐步排查发现主要是在循环中不停的申请用于存储描述子的动态内存这步比较耗时。
//System.cc中的 bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);//加载词库 //TemplatedVocabulary.h中的 F::fromString(m_nodes[nid].descriptor, ssd.str());//循环中调用这个 //FORB.cpp a.create(1, FORB::L, CV_8U);//fromString一直在申请内存,该句比较耗时 循环中申请比较耗时,改为开头统一申请,修改FORB.cpp文件中的内容fromString函数如下:
//统一申请 //FORB::TDescriptor其实就是cv::Mat结构 int nMaxNumDes = 1082174;//1082074 int nIndx = 0; vector<FORB::TDescriptor> vDes(nMaxNumDes,cv::Mat(1, FORB::L, CV_8U)); void FORB::fromString(FORB::TDescriptor &a, const std::string &s) { //a.create(1, FORB::L, CV_8U);//原先的逐个申请较慢,换成使用统一申请的内存 a=vDes[nIndx++]; unsigned char *p = a.ptr<unsigned char>(); stringstream ss(s); for(int i = 0; i < FORB::L; ++i, ++p) { int n; ss >> n; if(!
实验片内温度传感器 代码网上找的,然后自己琢磨了下。
/***********系统时钟初始化*********************************/ void InitClock(void) { CLKCONCMD &= ~0x40; //设置系统时钟源为 32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振稳定 CLKCONCMD &= ~0x47; //设置系统主时钟频率为 32MHZ } /***************定时器初始化**********************/ void InitT3(void) { T3CCTL0 = 0x44; //0100 0100 T3CCTL0 (0xCC),CH0 中断使能,CH0 比较模式 T3CC0 = 0xFA; //T3CC0设置为250 T3CTL |= 0x9A; //启动T3计数器,计数时钟为16分频。使用MODULO模式 IEN1 |= 0x08; IEN0 |= 0x80; //开总中断,开T3中断 } /****************温度传感器初始化函数*******************/ void InitSensor(void) { DISABLE_ALL_INTERRUPTS(); //关闭所有中断 InitClock(); //设置系统主时钟为 32M TR0=0x01; //设置为1来连接温度传感器到SOC_ADC ATEST=0x01; //使能温度传感 } /**************获取传感器温度值并返回***********************/ float GetTemperature(void) { uint value; ADCCON3 = (0x3E); //0011 1110 选择1.
文章目录 logback漏洞说明github地址总结 前两天因为log4j2的问题许多公司估计都通宵达旦的加班看版本改BUG了,但最近Logback也被发现相同问题。
logback漏洞说明 下面是一个漏洞检测机构搜集到的消息。
在 1.2.7 之前的 logback 中发现了一个归类为有问题的漏洞。受影响的是配置文件处理程序组件的未知功能。处理未知条目会导致扩展权限。该漏洞被标识为CVE-2021-42550。攻击可以从网络发起。此外,还有一个可用的探索。
CVE 摘要是:
在 logback 版本 1.2.7 和之前的版本中,具有编辑配置文件所需权限的攻击者可以制作恶意配置,允许执行从 LDAP 服务器加载的任意代码。
该漏洞被标识为CVE-2021-42550。CVE 的归属发生在 2021 年 10 月 15 日。攻击可以从网络发起。没有可用的技术细节。攻击的复杂性相当高。据说可利用性很困难。该漏洞并不为人所知。此外,还有一个可用的探索。该探索已向公众发布,可以使用。
英文
中文翻译
中文翻译
英文
github地址 这事一个触发logBack发生Bug的案例,里面有详细的漏洞分析,感兴趣的可以去看一看。
介绍:
该项目是SpringBoot编写的一个简单的漏洞Demo环境。在这里,我特意写了一个有任意文件上传的漏洞环境,然后利用loghack配置文件中的scan属性配合logback漏洞实现RCE。
想了解的点这里:传送门🐕🐕🐕🐕
总结 主要引起漏洞的原因和Log4j2相同,但是并没有像Log4j2那么的凶,因为这个漏洞不是百分百能触发的,需要特定的条件才可能出现安全问题。但是既然爆出来,还是防范于未然比较好。
触发条件:
logback的配置文件可以修改或覆盖能够使修改后的配置文件生效 主要影响的版本为:logback version < 1.2.9 和 logback version < 1.3.0-alpha11
ss命令 ss命令是 Socket Statistics 的缩写,用来统计 socket 连接的相关信息,它跟 netstat 差不多,但有着比 netstat 更强大的统计功能,能够显示更多更详细的连接信息。
常用命令 ss -l #列出当前监听的端口 ss -pl #列出其监听的端口以及对应进程 ss -a #列出所有的socket ss -at #显示所有tcp socket ss -au #显示所有UDP socket ss -o state established '( dport = :smtp or sport = :smtp )'# 显示所有已建立的SMTP连接 ss -o state established '( dport = :http or sport = :http )' #显示所有已建立的HTTP连接 ss -x src /tmp/.X11-unix/* #找出所有连接X服务器的进程 ss -s #列出当前socket详细信息 ss | more #socket连接太多的时候使用more命令查看 ss常用的state状态
1.vgdisplay 得到vg Name 为centos
[root@Linux122 guchenfei]# vgdisplay --- Volume group --- VG Name centos System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 5 VG Access read/write VG Status resizable MAX LV 0 Cur LV 2 Open LV 2 Max PV 0 Cur PV 1 Act PV 1 VG Size <19.00 GiB PE Size 4.00 MiB Total PE 4863 Alloc PE / Size 4863 / <19.00 GiB Free PE / Size 0 / 0 VG UUID 09i72y-vh64-9DvZ-m85B-MAU8-laD4-HvseBW 2.
文件查看命令more、less、cat 当linux文件太大,cat不好用的时候可以使用这两个命令进行内容查看、搜索,两个命令没有啥本质的区别,less功能比较多一点
cat cat 文件名 cat -n 文件名 //显示所有行号(包括空行) cat -b 文件名 //显示所有行号(不包括空行) less -i 忽略搜索时的大小写
-m 显示类似more命令的百分比
-N 显示每行的行号
/字符串:向下搜索“字符串”的功能
?字符串:向上搜索“字符串”的功能
n:重复前一个搜索(与 / 或 ? 有关)
N:反向重复前一个搜索(与 / 或 ? 有关)
翻页快捷键:
向后:f
向前:b
向后半页:d
向前半页:u
less 文件名 less -Nm 文件名 more Ctrl+F 向下滚动一屏
空格键 向下滚动一屏
Ctrl+B 返回上一屏
= 输出当前行的行号
more 文件名 结合管道命令进行查看 netstat -anp | more netstat -anp | less netstat -anp | less -Nm ps -ef | less
拯救者Y9000/Y7000系列 混合模式卡顿解决方案 拯救者显卡混合模式卡顿 解决方案第一步 BIOS 驱动更新第二步 卸载联想电脑管家以及应用商城第三步 下载并安装legion zone 控制中心 拯救者显卡混合模式卡顿 解决方案 好多小伙伴开开心心的买来电脑却被显卡混合模式的表现给蚌埠住了,**其主要原因:**就是电脑优化问题,新电脑驱动一般都是原厂旧版,还有就是设置管家属于通用行兼容性一般。那么现在我来给小伙伴们分享一个能优化这个问题的方案(不保完全修复,但可以达到99%的优化)
第一步 BIOS 驱动更新 首先,我们进入联想官网找到在服务界面找到对应的进行驱动下载页面(这里也可以通过下载联想的驱动管家更新)进行BIOS驱动下载。(这里注意安装好BIOS后,BIOS设置超频等会恢复默认状态,需要重新进入BIOS进行设置)
然后安装最新的BIOS驱动。
查看BIOS版本是否是最新的可以通过win搜索,【系统信息】进入页面查看。
第二步 卸载联想电脑管家以及应用商城 由于本人已卸载就多做赘述。
第三步 下载并安装legion zone 控制中心 官网:https://legionzone.lenovo.com
在下载前可以看自己的电脑型号BIOS驱动是否是最新的,然后下载安装BIOS驱动
下载定制管理软件,并安装。安装完成后便可以放心使用了
对于BIOS设置以及管理中心功能需要小伙伴自行探索
Java中java.swt.event包包含了不同事件的类和接口,每个事件类一般有对应于一个事件监听器接口
文章目录 前言一、事件监听器监听器的注册事件处理的具体步骤动作事件ActionEvent 二、适配器类使用内部类来进行监听鼠标事件 前言 提示:以下是本篇文章正文内容,下面案例可供参考
一、事件监听器 事件监听器是某个类的对象,我们将这个类称为监听器类
监听器必须要由监听和处理XXXEvent事件的能力,他所在的类必须要实现XXXListener接口
监听器的注册 所有组件都从Conponent类中继承了将事件处理授权给监听器的方法,又称为注册
component.addXXXListener(Listener);
取消注册
component.removeXXXListener(Listener);
事件处理的具体步骤 动作事件ActionEvent 动作事件是最常见的一类事件,当鼠标单击按钮,复选框,单选按钮或者菜单和文本框中输入回车时都会出发ActionEvent事件
负责处理ActionEvent事件的监听器必须实现ActionLister接口,实现接口里面的方法actionPerformed()的方法,事件处理代码就在这个方法里面
举例
package action; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class action_demo implements ActionListener { JFrame frame; JButton button; public action_demo() { // TODO Auto-generated constructor stub frame = new JFrame("动作事件"); button = new JButton("确定"); button.addActionListener(this); frame.add(button); frame.setSize(240,100); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub frame.
目录 一、dir(object)函数二、hasattr(object, name)函数三、Reference 一、dir(object)函数 语法:dir(object),列出object对象的所有属性和方法
功能:查看一个列表的所有属性和方法
例子:
li = [1,2,3,4] dir(li) 返回的结果:
可以看到有很多属性和方法
二、hasattr(object, name)函数 语法:hasattr(object, name) name 必须是字符串str,返回值是一个布尔变量True / False
功能:查看一个变量对象是否包含我们所寻找的属性
例子:
class User(object): """定义一个用户类""" def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender allen = User('Alen', 20, 'male') # 实例化类定义一个用户allen hasattr(allen, 'age') 结果是:
三、Reference https://www.cnblogs.com/klchang/p/7296058.html
https://www.runoob.com/python/python-func-hasattr.html
前言 业务线长期的积累产生了许许多多重复性的工具方法,业务功能模块等, 我们正好可以用 rollup 构建一个 npm 私服工具包,便于后期业务使用,减少重复性的代码编写。
项目配置 babel 引入依赖 首先运行以下命令安装babel相关:
yarn add @babel/core @babel/cli @babel/preset-env -D 配置babel.config.js module.exports = { presets: [ [ "@babel/preset-env", { targets: "> 0.25%, not dead" } ] ] }; 搭配@babel/plugin-transform-runtime和core-js:
yarn add core-js @babel/runtime yarn add @babel/plugin-transform-runtime -D 修改babel.config.js如下:
module.exports = { presets: [ [ "@babel/preset-env", { targets: "> 0.25%, not dead", useBuiltIns: "usage", corejs: "3.6.5" } ] ], plugins: ["@babel/plugin-transform-runtime"] }; 增加 npm scripts "
一条命令解决法: rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
//执行完上方命令之后就可yum下载了
若复制执行失败可试试手动输入,还不行的话进行以下操作
一、报错信息 报错的部分代码:
You have enabled checking of packages via GPG keys. This is a good thing. However, you do not have any GPG public keys installed. You need to download the keys for packages you wish to install and install them. You can do that by running the command: rpm --import public.gpg.key 翻译:
您已经通过GPG键启用了包检查。这是一件好事。
但是,您没有安装任何GPG公钥。您需要下载您想要安装的软件包的密钥并安装它们。
可以通过运行以下命令来实现:
rpm --import public.gpg.key
二、分析问题 然而,有时你运行该条命令后依旧会报错
大致翻译:
gpg公钥导入失败
文章目录 1. 简介1.1 编写目的1.2 参考资料 2. 测试概要2.1 测试时间2.2 测试范围功能测试兼容性测试 2.3 测试用例 3. 缺陷分析4. 风险预估5. 结论&建议5.2 建议 测试报告封面会表面版本号及审核人,批准日期等等, 下面我们先看下测试报告的封面及目录.
1. 简介 1.1 编写目的 本文档用于记录测试过程, 总结各轮次的测试情况, 分析测试数据, 归纳测试工作进行过程过程中暴露的问题与遗留的风险, 给出相应的测试建议以供后续项目参考.
1.2 参考资料 <<啊策策头条V1.2版本测试计划>>
各轮系统测试阶段总结
2. 测试概要 啊策策头条V1.2版本共经历2轮冒烟测试和2轮系统测试. 整个测试过程中累计执行用例xxx条, 发现缺陷xxx个. 截至V1.2第2系统测试及回归测试结束, 所发现严重缺陷已得到修复和验证.
2.1 测试时间 啊策策头条V1.2版本测试时间从20xx年12月1日开始, 到20xx年12月15日止, 期间各阶段工作情况如下:
2.2 测试范围 本次测试覆盖的范围包括: 功能测试, 兼容测试. 以下分别对功能测试, 兼容性测试进行说明
功能测试 啊策策头条V1.2在啊策策头条V1.xx基础上增加的主要功能如下:
兼容性测试 2.3 测试用例 根据需求文档, 测试人员编写和内审了测试用例, 为啊策策头条V1.2共编写用例xxx条, 累计执行用例xxx条.
3. 缺陷分析 每轮次个级别缺陷分布情况如下:
缺陷在各模块中的分布情况:
遗留缺陷情况:
到第二轮系统测试完成后, 项目目前遗留缺陷7个, 且这些缺陷均通过项目相关成员评估后确信可以遗留, 待后续版本规划处理. 具体缺陷信息此处略去.
在撰写论文后,一般需要插入图表清单,我们有时候会发现插入多个章节的图表清单时,每章之间会存在一个回车符,若我们直接删除就会出现排版错乱。解决方法很简单,直接删除每一章最后一行末尾的回车符即可,不要删除两章之间的回车符,比如:
图1.1 …回车符
…
图1.n…回车符(删掉这个即可)
回车符
图2.1…回车符
下载flink安装包解压
cd 到安装目录执行一下命令启动集群
./bin/start-cluster.sh 之后执行启动sql-client命令:
./bin/sql-client.sh embedded 默认情况下,这个sql-client上面所跑的任务,会提交到flink的standalone集群上,如果你没有bin/start-cluster.sh启动standalon集群,那么sql-client进程可以启动起来,但是在实际执行sql的时候,会连接拒绝的错误。
如果想要把任务提交给yarn,则需要启动一个yarn-session任务
yarn-session模式其实就是在yarn上生成一个standalone集群
./bin/yarn-session.sh -s 4 -nm cool -d 然后flink-sql客户端连接这个集群提交SQL任务
./bin/sql-client.sh embedded -s yarn-session 因为yarn-session模式默认会在/tmp/目录下维护一个会话信息,此时启动客户端指定yarn-session他会自动寻找到当前的session会话然后提交任务
本文首先发表在我的个人博客上,欢迎访问
https://sunguoqi.com/2021/12/25/christmas/
世上本没有圣诞老人,所有的礼物和惊喜都来自爱你的人!
文章目录 一、前言二、桌面应用程序三、Web 网页程序1、圣诞贺卡2、更好的我们3、流星圣诞树4、星球圣诞树6、Merry Christmas7、CodePen 四、Python Turtle 绘图1、Demo12、Demo23、Demo34、Demo45、将 python 程序打包成 exe 教程 五、C 语言控制台程序1、Demo12、Demo23、其他 C 语言代码 六、源码获取七、后记 一、前言 今天是圣诞节,不知道啥时候起,圣诞节也成撒狗粮的日子了。🙃
朋友圈各种秀对象画的圣诞树的狗粮也是吃够了(好酸臭哇)。
咱是没那福分,想要圣诞树看来是只有自己动手了!
二、桌面应用程序 记得前几年的圣诞节,在某个交流群里有人分享过这样一个程序,当时啥也不懂,只知道很酷。惊叹之后就没有然后了,今天追根溯源找到了这组桌面小摆件的出处。
网址:http://get-xmas.com/
这是一个国外的网站,目测应该是做桌面小部件的那种网站,在这个站点上选取你喜欢的程序,下载下来解压双击运行就可以显示在你的桌面上了。
下载下来的是exe可执行文件,支持多开,右键有一些工具选项卡,可以设置开机自启,显示在顶部等等。
因为是打包好的exe程序,直接分享给朋友,在朋友电脑上就可以打开了,非常的 Nice!
三、Web 网页程序 Web 开发是代码和艺术的结合,做 Web 开发真的是一件很酷的事情!
下面是我收集的一些圣诞网页,点击链接即可在线预览。
代码有点多,限于文章篇幅,没有在文章中展示,源码获取方式在文末。
1、圣诞贺卡 在线预览:https://box.sunguoqi.com/tree/demo1/
2、更好的我们 在线预览:https://box.sunguoqi.com/tree/demo2/
3、流星圣诞树 在线预览:https://box.sunguoqi.com/tree/demo3/
4、星球圣诞树 在线预览:https://box.sunguoqi.com/tree/demo4/
6、Merry Christmas 在线预览:https://box.sunguoqi.com/tree/demo5/
7、CodePen CodePen 网址:https://codepen.io/
授之以鱼,不如授之以渔。CodePen 是一款优秀的前端 demo 展示平台,里面有很多大佬的作品,在检索页面搜索Christmas Tree选择你喜欢的 demo 点进去,就可以白嫖他的前端代码了。
四、Python Turtle 绘图 后端语言我主要使用的是 python,毕竟人生苦短嘛。。。。。。当然我只会一点皮毛(狗头)。
众所周知,python 中的 Turtle 库(海龟库)是一个非常强大的绘图库,下面是利用 Turtle 制作出来的一些圣诞树作品。
目录 一、写在前面:本文仅为个人的理解,如有错误欢迎指正二、super().__init__()的含义三、代码实验四、理解super().__init__()五、Reference 一、写在前面:本文仅为个人的理解,如有错误欢迎指正 二、super().init()的含义 我们都知道是在定义子类的__init__方法的时候,由于需要继承父类的属性,则我们需要使用到super(),那么有些情况super().__init__()里面不带参数,有些时候要写成super().__init__(*wargs, **kwargs)这就让人有些迷惑了,这里写出一点自己的理解。
三、代码实验 首先我们定义一个车辆类
class Car(object): def __init__(self, owner, year, model): self.owner = owner self.year = year self.model = model def get_info(self): """打印车辆信息""" print(f'The owner of the car is {self.owner}\n' \ f'The model of the car is {self.year}-{self.model}') 查看一下这个类是否正常工作
ferrari = Car('Jarry', '2021', 'Roma') ferrari.get_info() 输出的结果:
The owner of the car is Jarry The model of the car is 2021-Roma 但这个时候我又想定义一个车类的子类,比如电动汽车类,那么我就应该继承Car类来减少代码量。但是为了使用Car类的属性和方法,我继承了Car类,那么我该如何初始化我的子类呢?
第一种方法:
我只需要写我子类所需要的属性,然后父类需要的属性我用*wargs来表示,然后在__init__函数中,首先初始化我的子类的属性,将父类需要的属性打包成*wargs送入super()中
class ElectricalCar(Car): def __init__(self, battery, *wargs): super().
每隔一段时间服务器磁盘空间总会被应用输出日志打满,导致应用出现服务异常等问题,故而需要配置自动清理日志文件脚本,配合crond定时任务实现自动化执行。
执行创建文件命令touch shell.sh,并编辑输入以下脚本:
#!/bin/bash # 日志文件存放路径 logPath=/data/logs # 截取根目录磁盘的占用率 disk=$(df -h|grep "/$"|awk '{print int($5)}') if [ $disk -gt 85 ]; then for i in `/usr/bin/ls -thr ${logPath} |grep '*.log' |head -12` do rm -rf ${logPath}/$i done; echo "成功清理日志文件" >> /data/log/nation/shell.txt else date >> ${logPath}/shell.txt && echo "磁盘空间占用率小于85%" >> ${logPath}/shell.txt fi 说明:
1.#!/bin/bash:声明shell命令解析器,否则使用系统默认的
2.以上脚本命令的意思为先获取磁盘空间占用率大小,若大于85,则列出时间倒序的以.log为后缀的前12个文件并遍历删除,并且打印日志到shell.txt文件。
因为是shell脚本,所以需要执行权限:
chmod -R 777 shell.sh 可以自测脚本是否正确:
bash -v shell.sh 接着配置crontab定时任务:
crontab -uroot -e 在最后编辑输入并保存退出(自行研究cron表达式,这里配置每两分钟执行一次):
*/2 * * * * /data/logs/shell.
制作APP分享二维码,后端生成base64图片,需要前端保存到相册,上代码
saveImgFile(base64) { //base64为base64图片值 const bitmap = new plus.nativeObj.Bitmap("test"); bitmap.loadBase64Data(base64, function() { const url = "_doc/" + new Date().getTime() + ".png"; // url为时间戳命名方式 console.log('saveHeadImgFile', url) bitmap.save(url, { overwrite: true, // 是否覆盖 // quality: 'quality' // 图片清晰度 }, (i) => { uni.saveImageToPhotosAlbum({ filePath: url, success: function() { uni.showToast({ title: '图片保存成功', icon: 'none' }) bitmap.clear() } }); }, (e) => { uni.showToast({ title: '图片保存失败', icon: 'none' }) bitmap.clear() }); }, (e) => { uni.
报错内容:
JSON parse error: Unexpected character ('/' (code 47)): maybe a (non-standard) comment? (not recognized as one since Feature 'ALLOW_COMMENTS' not enabled for parser); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('/' (code 47)): maybe a (non-standard) comment? (not recognized as one since Feature 'ALLOW_COMMENTS' not enabled for parser) at [Source: (PushbackInputStream); line: 5, column: 29] (through reference chain: com.akun.demo.model.boke.Comment["parentComment"]) postman 的数据格式:如下
解决办法:
1、把注解删掉就可以正常使用,不会报错
2、核实你的json文件中是否有类似//,# 添加的注释,json不支持注释,想要添加注释的话,可以使用 key : value 添加描述
Android是如何使用selinux来保护系统属性的 尝试获取Android设备的序列号SerialNo1 Build.SERIAL2 Build.getSerial()3 SystemProperties.get App读取属性流程分析跟踪读取属性的代码流程相关数据结构的初始化 Init初始化属性系统property_initCreateSerializedPropertyInfo__system_property_area_initproperty_info_area.LoadDefaultPath() export_kernel_boot_propsproperty_load_boot_defaults App读取属性是如何被拦截的总结相关源码 尝试获取Android设备的序列号SerialNo 因为业务需求, 我们需要获取到Android设备的序列号(SerialNo)。首先看一下Android提供的用于获取序列号的Api以及Api实现。
1 Build.SERIAL /** * A hardware serial number, if available. Alphanumeric only, case-insensitive. * This field is always set to {@link Build#UNKNOWN}. * * @deprecated Use {@link #getSerial()} instead. **/ @Deprecated // IMPORTANT: This field should be initialized via a function call to // prevent its value being inlined in the app during compilation because // we will later set it to the value based on the app's target SDK.
public class MarshalEndian { private readonly int ConstLength = 12; //最小包长 private List<byte> leftBytes = new List<byte>(); //历史遗留包数据 private readonly byte head1 = 0x1F; //自定义头1 private readonly byte head2 = 0xF2; //自定义头2 private readonly byte foot1 = 0x0A; //自定义尾1 private readonly byte foot2 = 0x0D; //自定义尾2 public byte[] Encode(SocketPackage msg) { var buffer = new List<byte>(); buffer.Add(head1); buffer.Add(head2); //将包类型 转换为 byte 数组 tobytes 需要自己编写 var arry = msg.toBytes(); buffer.AddRange(arry); buffer.
2021年12月24日亲测可用。
下载地址:下载地址
本篇文章的目的:在UE4中使用C++实现一个自己的行为树任务节点。该任务节点可以完成简单的朝向Actor移动的功能。
版本号:4.26
项目名:AITest
第一步,新建一个C++类,继承自BTTask_BlackboardBase,命名为BTTask_MyMoveTo。
出现提示:
需要在AITest.Build.cs中,修改下面这行代码,添加 “GameplayTasks”。
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "GameplayTasks" }); 第二步:编写代码
BTTask_MyMoveTo.h
// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "BehaviorTree/Tasks/BTTask_BlackboardBase.h" #include "BTTask_MyMoveTo.generated.h" /** * */ UCLASS() class AITEST_API UBTTask_MyMoveTo : public UBTTask_BlackboardBase { GENERATED_BODY() public: UBTTask_MyMoveTo(); virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory) override; #if WITH_EDITOR virtual FName GetNodeIconName() const override; #endif // WITH_EDITOR }; BTTask_MyMoveTo.
一、DOM的新增 1.innerHTML: innerHTML会把原来的内容先清空,然后再添加新的内容,原来的内容已经没有了。只不过是新添加的内容与原来的内容长得一样而已(原本具有的事件不具存在。innerHTML 只能解析字符串
<body> <div class="a"> <span>hello</span> </div> <script> var oDiv = document.querySelector('.a') ; oDiv.innerHTML = '<p>你好</p>' //此时页面会清空原来的内容hello,再添加 你好 </script> 2.DOM方法:appendChild() 创建一个文本节点:createTextNode()创建标签节点:createElement()在最后面插入 appendChild()或在指定的元素前面插入 insertBefore(要插入的元素 , 指定的元素) 注意:同一个标签只能操作一次 — 标签是对象,对象都有唯一的地址
appendChild:
概念:把要添加的节点添加到指定父级里面的最后面,所以也叫追加
用法:fatherdom.appendChild( insertdom )
兼容性:所有浏览器都支持此方法。
<body> <div class="a"> <span>hello</span> </div> <script> var oDiv = document.querySelector('.a') ; // 1.创建一个标签 createElement //oP在创建标签的时候是一个对象 var oP = document.createElement('p') ; // console.log(oP); // <p></p> //2.创建一个文本节点 var oText = document.createTextNode('今天天气好好啊!'); // console.log(oText) ; //今天天气好好啊! //3.
Petschkos RPG-Maker MV & MZ-File Decrypter
https://petschko.org/tools/mv_decrypter/#restore-images
打开VS 项目 -> 属性 -> 常规
问题就在windows SDK版本这里
也许并不为空,但都是找不到SDK了。
打开VS Installer,选择 “修改”,在右侧选上想要的Windows SDK版本,其他的不要动,修改后就解决这个问题了。
目录
1导入导出
2测试
2.1导入测试
2.1.1JSON导入
2.1.2对象导入
2.2导出测试
2.2.1导出模版
2.2.2导出用户表
3依赖
4工具包
1导入导出 UserImport
package com.excel.entity; import com.excel.utils.ExcelImport; import lombok.Data; @Data public class UserImport { // 获取此行的错误提示 private String rowTips; // 获取此时数据第几行 private int rowNum; // required非空 unique不能重复 @ExcelImport(value = "姓名",required = true,unique = true) private String name; @ExcelImport("年龄") private Integer age; @ExcelImport(value = "性别",kv="1-男;2-女") private Integer sex; @ExcelImport(value = "电话",maxLength = 11) private String tel; @ExcelImport("城市") private String city; @ExcelImport("
其实我们现在的cpu的形式太多了,具体他们是啥情况不知道,以下也是个人愚见
1.物理cpu数:主板上实际插入的cpu数量,可以数不重复的 physical id 有几个(physical id)
2.cpu核数:单块CPU上面能处理数据的芯片组的数量,如双核、四核等 (cpu cores)
3.逻辑cpu数:简单来说,它可使处理器中的1颗内核,如2颗内核那样在操作系统中发挥作用。
这样一来,操作系统可使用的执行资源扩大了一倍,大幅提高了系统的整体性能,此时逻辑cpu=物理CPU个数×每颗核数x2。
总核数 = 物理CPU个数 × 每颗物理CPU的核数。
总逻辑CPU数 = 物理CPU个数 ×每颗物理CPU的核数 × 超线程数
正常情况下,逻辑cpu数就是我们平时机器可以利用的资源,正如我之前的文章链接中提到的单颗单核cpu,逻辑CPU提供给你的资源中的数量1就是等同于单颗单核cpu
1.首先判断是安卓还是IOS
2.判断手机中百度地图和高德地图是否已经安装
3.已安装,则调用相应的地址
var u = navigator.userAgent var scheme = '' // IOS地图跳转 if (!!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) { if(plus.runtime.isApplicationExist({pname:'com.autonavi.minimap',action:'iosamap://'})){ // 判断高德地图 是否安装 scheme = `iosamap://navi?sourceApplication=amap&lat=${i.lat}&lon=${i.lon}&dev=1&style=2` } else if(plus.runtime.isApplicationExist({pname:'com.baidu.BaiduMap',action:'baidumap://'})){ scheme = `baidumap://map/direction?&destination=${i.lat},${i.lon}&coord_type=bd09ll&mode=driving&src=ios.baidu.openAPIdemo` // console.log(scheme, 'scheme') }else { this.$message.error('请安装高德地图或百度地图') } } // 安卓手机地图跳转 if (u.indexOf('Android') > -1) { if(plus.runtime.isApplicationExist({pname:'com.autonavi.minimap',action:'iosamap://'})){ // 判断高德地图 是否安装 scheme = `androidamap://navi?sourceApplication=amap&lat=${i.lat}&lon=${i.lon}&dev=1&style=2` } else if(plus.runtime.isApplicationExist({pname:'com.baidu.BaiduMap',action:'baidumap://'})){ // 判断百度地图是否安装 scheme = `bdapp://map/direction?destination=${i.lat},${i.lon}&coord_type=bd09ll&mode=driving&src=andr.baidu.openAPIdemo` } else { // scheme = `https://apis.
目录 一、基本介绍二、代码实验1、一维数组情况1.1、axis=01.2、axis=12、二维数组情况2.1、axis=02.2、axis=13、三维数组情况3.1、axis=03.2、axis=13.3、axis=23.4、axis=-1四、Reference 一、基本介绍 numpy中的argmax简而言之就是返回最大值的索引,当使用np.argmax(axis),这里方向axis的指定往往让人不理解。
简而言之:这里axis可以让我们从行、列、或者是深度方向来看一个高维数组。
二、代码实验 1、一维数组情况 简单一维情况,np.argmax()直接返回最大值的索引,不指定axis可以认为是将数组拉平之后寻找最大值的索引
1.1、axis=0 当我们指定axis=0时,其实是在列中作比较,寻找最大的行的索引
当然对于这个一维情况没有什么影响。
1.2、axis=1 当我们指定axis=1的时候报错了,这是因为我们的a是一维数组,没有axis=1这个轴,可见当我们使用np.argmax()时axis的指定不能超过所需要排序的数组
2、二维数组情况 不指定axis就是相当于把二维数组拉平,直接选取最大值的索引
2.1、axis=0 指定axis=0就是比较列,返回行索引中的最大值
我们改写一个b中的元素,我们期望的结果是[2,2,1,2]
实际结果和我们期望相符合
2.2、axis=1 指定axis=0就是比较行,返回列索引中的最大值
3、三维数组情况 一个三维数组可以视作一张图片,它的三个维度分别为(high, width, channels) 分别表示图像的高、宽、通道数(深度)。常见的彩色图像都有三个通道,我们以常见的RGB图像为例构建一个数组。
直接使用np.argmax(),就是之间将三维数组拉平,寻找最大值的索引
3.1、axis=0 单独查看c的三个通道的数据,如图所示
对于三个通道取axis=0意味分别比较列返回行的最大值索引
我们期望的返回值应该是[[1,1,1,],[1,1,1],[1,1,1]],实际的结果和我们的期望一致
3.2、axis=1 对于三个通道取axis=1意味分别比较行返回列的最大值索引
我们期望的结果是[[2, 2, 2],[2, 2, 2],[2, 2, 2],[2, 2, 2]],,实际的结果和我们的期望一致
3.3、axis=2 取axis=2意味着我们从图像的深度方向(通道方向)来进行比较,可以认为三个数组的叠在一起的,分别对应channel0,channel1,channel2而我们取最大值的索引就是返回对应pixel像素所在的通道索引。
c的channel2所有的像素值均大于其他两个channel所有返回值应该是[[2,2,2,],[2,2,2,],[2,2,2,],[2,2,2,]],实际结果和我的期望一致
3.4、axis=-1 axis=-1即是反过来看轴,对于三维情况axis=-1和axis=2一致
其他:
对于二维情况axis=-1和anxis=1一致
对于一维情况axis=0和anxis=-1一致
四、Reference https://blog.csdn.net/weixin_39190382/article/details/105854567
https://www.cnblogs.com/zhouyang209117/p/6512302.html
isNaN函数 isNaN(x) 函数用于检查参数x是否是非数字值
如果x是非数字值,返回true,如果x是数字值,返回false
注:如果把NaN与任何值(包括自己)相比,得到的结果都是false,因此判断某个值是否是NaN,不能使用==或=== 运算符。
两台win10电脑网线直连,使用Synergy实现鼠标键盘共享设置 最近发现一个新的软件barrier,源于Synergy,开源免费使用。
开源地址:https://gitee.com/huaxiuyiwei/barrier
下载地址:https://gitee.com/huaxiuyiwei/barrier/releases/v2.3.3
一、Synergy客户端的电脑设置:
二、Synergy服务器端的电脑设置:
三、然后客户端设置一下就可以了:
参考文章1:树莓派复制系统到新内存卡教程 - 简书 (jianshu.com)
参考文章2:
一、移动硬盘格式化为FAT32
二、插入移动硬盘后运行命令:
sudo fdisk -l 根据大小找到系统盘和移动硬盘,然后执行下面的命令,把SD卡里的系统复制到硬盘中
sudo dd bs=4M if=/dev/mmcblk0 of=/dev/sda 需要注意几个问题:1)bs=4M,M必须大写,否则会报错(dd invalid number 4m),网上的教程大部分是错的,我遇到了这个问题。2)if=/dev/mmcblk0是树莓派的系统分区,这个不需要改动。3)of=/dev/sda后面是你的内存卡的路径,究竟是哪一个需要根据刚刚查出来的结果填写。
三、树莓派断电,然后拔掉SD卡,树莓派上电,不需要其他设置,等待一会,树莓派正常启动。
四、也可以不从SD卡复制系统,也可以直接做系统到移动硬盘,方法很简单,怎么做TF卡的就怎么做移动硬盘里,做完直接插在树莓派的USB接口上通电即可。
此DEMO包含一下功能
用户界面(显示头像、学号、电话号码、性别)修改密码(密码检验+两次密码是否一致的检验)上传头像(这里采用的是先用io流将图片传到工程文件下,把图片路径保存到数据库中) 用户界面 用户界面
customerUI.jsp
<%@ page contentType="text/html;charset=UTF-8" %> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户界面</title> <link rel="stylesheet" type="text/css" href="css/customer.css"> </head> <body> <div class="container"> <div class="forms-grid"> <div class="login"> <div style="width:200px"> <div class="to3"> <div class="to2"> <div class="to1"> <img id="img" class="to" alt="图片加载失败" src="<%=request.getParameter("path")%>"> </div> </div> </div> </div> <form name="form1" method="post" class="login-form"> <div class="form"> <div class="form-row"> <label class="form-label">学 号:</label><%=request.getParameter("name")%> </div> <br> <div class="form-row"> <label class="form-label">电 话:</label><%=request.getParameter("tel")%> </div> <br> <div class="form-row"> <label class="form-label">性 别:</label><%=request.getParameter("sex")%> </div> <br> <div class="
阿里云安装完成RocketMQ后,在发送消息时出现:sendDefaultImpl call timeout
环境:centos7.4 rocketmq-4.4.0
我的配置:限制内存(非必须的)、配置文件修改、增加启动脚本
(1)/mydata/rocketmq-4.4.0/bin/runserver.sh
内存限制
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
gc日志目录修改
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/mydata/rocketmq-4.4.0/logs/rmq_srv_gc.log -XX:+PrintGCDetails"
(2)/mydata/rocketmq-4.4.0/bin/runbroker.sh
内存限制
JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m"
gc日志目录修改
JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:/mydata/rocketmq-4.4.0/logs/mq_gc_%p.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintAdaptiveSizePolicy"
(3)/mydata/rocketmq-4.4.0/conf/broker.conf
尾部增加
brokerIP1 = 机器的外网IP(如果不需要外网访问配置内网IP即可) namesrvAddr = 机器的外网IP(如果不需要外网访问配置内网IP即可):9876 (4)启动脚本
start-mq.sh
#!/bin/bash export JAVA_HOME=/opt/jdk1.8 nohup /bin/sh /mydata/rocketmq-4.4.0/bin/mqnamesrv -n 机器的外网IP(如果不需要外网访问配置内网IP即可):9876 > /mydata/rocketmq-4.4.0/logs/namesrv.log 2>&1 & nohup /bin/sh /mydata/rocketmq-4.4.0/bin/mqbroker -n 机器的外网IP(如果不需要外网访问配置内网IP即可):9876 -c /mydata/rocketmq-4.4.0/conf/broker.conf > /mydata/rocketmq-4.4.0/logs/broker.log 2>&1 & (5)查看是否启动
使用vscode连不上服务器,截止到目前,我遇到的主要原因有两种:
1. 多个PC端连接同一账户,导致后来连接的PC端连接不上。这时候需要删除一个 .vscode-server文件。
具体解决步骤如下:
(1) 进入到目录/home/name 下(根据自己的情况调整各自具体的目录)
cd /home/name
(2) 查看当前目录下是否有 .vscode-server 文件
ls -a (3) 删除 .vscode-server 文件
rm -rf .vscode-server/
删除了.vscode-server 文件之后重新打开vscode 连接服务器即可。
2. 服务器端口变了。之前连接的端口是22,现在变成了22022,我怎么连不上。后来查各种资料,最终连上了,上解决步骤:
(1) 添加一个新的服务器。(点击图中的“+”号)
(2) 输入连接的服务器信息。
格式如下:
ssh 远程用户名@服务器地址 -p 端口号
输入完之后点击“Enter”键即可连接成功。
本文用流水账的形式记录如何使用nvdla的virtual platform编译生成NVDLA硬件可识别代码并且在QEMU中模拟运行。NVDLA硬件为full模式,并没有对硬件做任何的配置。
使用Docker运行VP 下载nvdla/vp中提到的docker,所有的编译工具都已经预编译并且放在/usr/local/nvdla/中
docker pull nvdla/vp 准备caffe模型
可以从以下链接下载编译好了的caffe模型,并从以下链接获取测试样例。此处需要注意,caffe模型是使用黑底白字训练的,而我们得到的测试样例是白底黑字,所以需要使用以下代码来做转换[1]:
import sys import numpy from PIL import Image img = Image.open(sys.argv[1]).convert('L') im = numpy.array(img) im = 255 - im result = Image.fromarray(im) result.save(sys.argv[1].split('.')[0]+'_inv.'+sys.argv[1].split('.')[1]) 编译.nvdla模型
在docker容器下运行以下命令,如果没有报错,会生成.nvdla文件。此处需要注意的是,设置好nvdla_compiler的路径,否则会报找不到nvdla_compiler的错误。
./nvdla_compiler --caffemodel lenet_iter_10000.caffemodel --prototxt lenet.prototxt 在QEMU中运行runtime
4.1 使用以下命令进入QEMU
cd /usr/local/nvdla # start the virtual simulator aarch64_toplevel -c aarch64_nvdla.lua # Login the kernel with account 'root' and password 'nvdla' 4.2 挂载当前文件夹并加载所需驱动
mount -t 9p -o trans=virtio r /mnt # mount pwd cd /mnt insmod drm.
windows系统下maven的安装 一、软件下载 官网下载 点击maven下载链接,点击下载
网盘链接 网盘链接提取码:idj1
下载下来之后将其解压到一个没有中文没有空格的目录下
二、配置JDK环境变量 这边文章有详细的安装步骤:https://blog.csdn.net/qq_45282568/article/details/122093495?spm=1001.2014.3001.5501 三、配置maven环境变量 在高级系统设置中配置环境变量 变量名为MAVEN_HOMR,变量值为你安装解压的目录路径 点击path,编辑 点击新建,输入**%MAVEN_HOME%\bin** 四、测试 在终端中输入mvn -v,显示如下,表示安装成功 五、配置maven仓库 在你习惯的目录下建一个文件夹,命名为maven_repository将链接:https://pan.baidu.com/s/11R30ZQcpegFmC3h4uRO-hQ 提取码:a8x1 下载的仓库解压到该目录下在MAVE_HOME/conf/settings.xml 文件中配置本地仓库位置(maven 的安装目录下) 打开settings.xml,配置如下 六、将maven集成到idea中 在文件 --> 设置中搜索maven,做如下设置 ea中
在文件 --> 设置中搜索maven,做如下设置
window系统下JDK1.8的安装 一、下载安装文件 官网下载 直接访问官方网址甲骨文官网,点击下载 网盘链接下载 官网下载没有特殊方法的话下载可能比较慢慢,我这里准备了[网盘链接](https://pan.baidu.com/s/1ViOKvX8rkLOmnMmVaVJJYg) 提取码:giqs 二、安装 傻瓜式安装,一直下一步,存储路径想改的可以改一下jdk安装完后会安装jre,也是改一下路径或者不改,文件夹必须是空文件夹,一直下一步即可安装完毕后点击关闭 三、配置环境变量 有的电脑会自动配置环境变量,这个要注意
如果你的电脑没有自动配置环境变量,那么右击此电脑–>属性–>高级系统设置–>环境变量–>系统变量–>新建
在系统变量中找到path,点击编辑 点击新建,输入**%JAVA_HOME%\bin**,然后点击上移将其移至最前面 四、测试 在cmd中输入java -version 这样显示就表示安装成功
片转存中…(img-ZWUocEiY-1640173329914)]
这样显示就表示安装成功
文章目录 目的字符串获取字符串长度拼接字符串截取字符串替换字符串判断与默认值 内嵌文档与内嵌字符串内嵌文档 Here Document内嵌字符串 Here String 数组数组定义与使用获取数组长度拼接数组删除数组或其中元素 关联数组总结 目的 字符串与数组是Shell编程中常用的数据类型,这篇文章将对相关内容进行介绍。
字符串 Shell中的变量基本上默认都是字符串,通常使用下面方式声明和定义字符串类型的变量:
variable=value # value中不能出现空格 variable='value' # ''内部所有内容都变为单纯的字符串,即使遇到$和``也不进行替换 variable="value: \"233\"" # ""内部遇到$和``以及转义符会进行替换 # variable是变量名,value是赋给变量的值 # 赋值=周围不能有空格(重点) # 所有变量的值都是字符串,比如var=123,123也会以字符串形式存储,即'123'或是"123" # 变量定义后可以使用=重新赋值 下面是一些常用的字符串操作,需要注意的是对于复杂的字符串操作往往更多的时候会使用 cut grep awk sed expr 等命令。
获取字符串长度 在Shell中可以使用 ${#string_name} 来获取字符串长度:
拼接字符串 在Shell中拼接字符串不需要任何运算符,只需要把字符串变量排列在一起就行:
截取字符串 在Shell中截取字符串主要有下面方法:
${string:start} # 从左边start位置开始,从左到右截取剩余所有的字符串 ${string:start:length} # 从左边start位置开始,从左到右截取length长度的字符串 ${string:0-start} # 从右边start位置开始,从左到右截取剩余所有的字符串 ${string:0-start:length} # 从右边start位置开始,从左到右截取length长度的字符串 ${string#chars} # 从左开始匹配第一个chars字符串,截取其右边的字符串 ${string##chars} # 从左开始匹配最后一个chars字符串,截取其右边的字符串 ${string%chars} # 从右开始匹配第一个chars字符串,截取其左边的字符串 ${string%%chars} # 从右开始匹配最后一个chars字符串,截取其左边的字符串 替换字符串 在Shell中替换字符串主要有下面方法:
1.准备带有坐标点的csv文件
2.文件导入与显示
3 导出为点.shp文件
当前目标检测领域常用的数据集格式非 COCO、VOC、YOLO莫属,但是很多算法的源码或者框架只支持一种数据格式,数据集格式不匹配的时候就需要自己手动进行转换。
因此我最近整理了一下这三种格式互相转化的代码,并且添加了标签可视化的代码,以后打比赛或者其他情况下能节省部分手动转换的时间。
目录 太长不看直接使用格式介绍COCOVOCYOLO 代码使用教程 太长不看直接使用 代码github地址:https://github.com/FireworksFallDown/TypeTotype.git
对于windows用户,我还提供了相应的exe程序,可以直接在图形界面进行操作。
如果github登不上去的话推荐在 码云gitee里创建仓库直接导入github地址,就能够轻松下载了
格式介绍 COCO Annotations.json -------------------------------------------------------------------------------------------------- { "images": [ { "file_name": "***.jpg", # string "height": ***, # int "width": ***, # int "id": * # int },...] "annotations": [ { "iscrowd": 0, # 0 or 1 "area": *, # float or double "image_id": 0, # int "bbox": [*, *, *, *], # list[float], [x,y,w,h] "category_id": *, # int "id": * # int },.
在vue3.x中使用应该使用vue-cropper@next版本
github详解
npm install vue-cropper@next import 'vue-cropper/dist/index.css' //组件中使用 import { VueCropper } from "vue-cropper"; 自己可以把裁剪二次封装成一个组件,用在自己项目中
可以使用一个dialog承载它,当你上传完图片,展示裁剪dialog进行裁剪
<el-dialog v-model="dialogVisible" title="Tips" width="30%"> <div class="外层这个样式一定要给你一个高"> <VueCropper ref="cropper" :img="option.img" :outputSize="option.size" :outputType="option.outputType" :info="true" :full="option.full" :fixed="option.fixed" :fixedNumber="option.fixedNumber" :can-move="option.canMove" :can-move-box="option.canMoveBox" :fixed-box="option.fixedBox" :original="option.original" :auto-crop="option.autoCrop" :auto-crop-width="option.autoCropWidth" :auto-crop-height="option.autoCropHeight" :center-box="option.centerBox" @realTime="realTime" :high="option.high" @img-load="imgLoad" mode="cover" :max-img-size="option.max" @crop-moving="cropMoving" ></VueCropper> </div> </el-dialog> option: { img: "https://avatars2.githubusercontent.com/u/15681693?s=460&v=4", size: 1, full: false, outputType: "png", canMove: false, fixedBox: false, original: false, canMoveBox: true, autoCrop: true, // 只有自动截图开启 宽度高度才生效 autoCropWidth: 160, autoCropHeight: 150, centerBox: true, high: true, max: 99999, fixed: true, fixedNumber: [1, 2], },
十进制转度分秒
=TEXT(INT(A1),"0")&"°"&TEXT(INT((A1-INT(A1))*60),"00")&"′"&TEXT(((A1-INT(A1))*60-INT((A1-INT(A1))*60))*60,"00.00")&"″"
度分秒转十进制
=LEFT(A1,FIND("°",A1)-1)+MID(A1,FIND("°",A1)+1,FIND("′",A1)-FIND("°",A1)-1)/60+MID(A1,FIND("′",A1)+1,FIND("″",A1)-FIND("′",A1)-1)/3600
注意:度分秒的要完整,例如要用23°1′0″的形式;23°1′则会出错。
1、Vue-Cli3简介 Cli是Command-Line Interface命令行界面,俗称就是脚手架。Vue-Cli用于快速搭建Vue开发环境以及对应的webpack配置,它可以帮助我们构建目录结构,部署,热加载,代码单元测试等功能,是一个用于快速开发的脚手架。
vue-cli3创建项目,后面的选项自定义不做累述。
vue create 项目名称 2、如何改变URL但是页面不会发生刷新 两种方法
1、修改location.hash值
2、使用history对象
history.pushStatus({},’’,’/url’);
history.back();
histroy.replaceStatus({},’’,’/url’);
histroy.go()
3、配置资源路径的别名 在我们的项目中,有类似如下./向上查找的资源路径配置,这种方式移植性较差,且不易阅读。我们就可以尝试在项目中而配置资源目录的别名来解决这些的问题。
<img src="../../img/购物车.png" alt=""> 那么如何配置资源路径的别名呢,Vue Cli3中将我们的配置文件隐藏起来了,用户想要自定义的配置的话就需要在项目的根目录创建一个vue.config.js的文件。下面是别名的配置方式:
const path = require("path"); function resolve(dir) { return path.join(__dirname, dir); } module.exports = { chainWebpack: config => { config.resolve.alias .set("@", resolve("src")) .set("assets", resolve("src/assets")) .set("components", resolve("src/components")) .set("views", resolve("src/views")) // .set("base", resolve("baseConfig")) // .set("public", resolve("public")); }, } 以.set(“components”, resolve(“src/components”))为例,这里是将’components’作为src/components目录的别名。即我们在项目中可以使用components代替src/components,例:
import TabBar from "components/tabbar/TabBar"; import TabBarItem from "components/tabbar/TabBarItem"; 需要注意的是在HTML的src资源引入时不能直接使用目录别名,需要在别名前加上~号
<img src="
(1)第一种:类似于数组的方式:
std::vector<std::string> strArray(10); strArray[0] = "hello"; strArray[1] = "world"; strArray[2] = "this"; strArray[3] = "find"; strArray[4] = "gank"; strArray[5] = "pink"; strArray[6 ]= "that"; strArray[7] = "when"; strArray[8] = "how"; strArray[9] = "cpp"; (2)第二种:push_back的方式:
vector<string> strArray; strArray.push_back("hello"); strArray.push_back("world"); strArray.push_back("this"); strArray.push_back("find"); strArray.push_back("gank"); strArray.push_back("pink"); strArray.push_back("that"); strArray.push_back("when"); strArray.push_back("how"); strArray.push_back("cpp"); (3)第三种:构造函数的方式:
string str[]={"hello","world","this","find","gank","pink","that","when","how","cpp"}; vector<string> strArray(str, str+10);
一、安装 npm install --save-dev koa2-proxy-middleware 二、常规使用 const Koa = require('koa'); const proxy = require('koa2-proxy-middleware'); const bodyparser = require('koa-bodyparser'); const app = new Koa(); const options = { targets: { '/user': { // this is option of http-proxy-middleware target: 'http://localhost:3000', // target host changeOrigin: true, // needed for virtual hosted sites }, '/user/:id': { target: 'http://localhost:3001', changeOrigin: true, }, // (.*) means anything '/api/(.*)': { target: 'http://10.94.123.123:1234', changeOrigin: true, pathRewrite: { '/passager/xx': '/mPassenger/ee', // rewrite path } }, // ws '/websocket': { target: 'ws://10.
一 基本配置和vsftp服务安装
1 安装Linux Centos7过程省略
2 修改主机名(要重新登录才会显示修改后的主机名)
[root@192 ~]# hostnamectl set-hostname FTP
3 安装net-tools、VIM,bash-completion sysstat [root@192 ~]# yum -y install bash-completion net-tools vim*
4 检查vsftpd是否已安装
5 安装vsftpd
[root@ftp ~]# yum -y install vsftpd
6 启动vsftpd服务并设置开机启动
[root@ftp ~]# systemctl start vsftpd
[root@ftp ~]# systemctl enable vsftpd
Created symlink from /etc/systemd/system/multi-user.target.wants/vsftpd.service to /usr/lib/systemd/system/vsftpd.service.
7 检查vsftpd服务是否正常启动
8 检查ftp服务端口是否正常
9 检查ftp服务是否运行
二 vsftpd配置文件
/etc/vsftpd/vsftpd.conf #FTP主配置文件 /etc/vsftpd/ftpusers #拒绝用户登录到FTP服务器,系统默认是黑名单文件
/etc/vsftpd/user_list #user_list需要参照userlist_deny来决定该文件是黑名单还是白名单
vsftpd通过ftpusers和user_list对用户进行ACL访问控制
注1:配置文件中的userlist_enable=YES,启用"禁止用户名单"功能。ftpusers默认是黑名单文件,user_list需要参照userlist_deny来决定该文件是黑名单还是白名单。userlist_deny=YES表示黑名单,userlist_deny-NO表示白名单。
注2:黑名单表示仅拒绝名单中的用户访问FTP,其他所有帐户默认允许访问FTP。白名单表示仅允许在名单中的用户访问FTP,其他所有帐户默认拒绝访问FTP。
/etc/vsftpd/user_list
前言 利用python爬取新浪微博某高清视频
一、导入模块 import requests 二、获取微博视频URL url = 'https://weibo.com/tv/api/component?page=%2Ftv%2Fshow%2F1034%3A4715681229504535' 三、发送网络请求、获取数据 #数据参数 data = { 'data':'{"Component_Play_Playinfo":{"oid":"1034:4715681229504535"}}' } #加伪装 headers = { 'cookie':'login_sid_t=3bd4769043d679698e4027abc68a19ad; cross_origin_proto=SSL; _s_tentry=www.google.com; TC-V-WEIBO-G0=35846f552801987f8c1e8f7cec0e2230; Apache=305749860309.5965.1640091510502; SINAGLOBAL=305749860309.5965.1640091510502; ULV=1640091510510:1:1:1:305749860309.5965.1640091510502:; _ga=GA1.2.1378508093.1640091516; _gid=GA1.2.372615198.1640091516; __gads=ID=ea526ea146392bd3:T=1640091521:S=ALNI_MarcDpRuUQD6MdIP19TotAVvfRz9Q; SUB=_2AkMWnUC6f8NxqwJRmfwRz2nga4VxyAvEieKgwbFhJRMxHRl-yT92qhIttRB6PR1uVT_FVT0v2Ylh1kdhjsMZHe78F85j; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9Whi3_-XlTniI0Q9CHPNBcRw; XSRF-TOKEN=CRf522iw92KxJQ1Tpw1uNDp-; wb_view_log=1536*8641.25; WBPSESS=2jFn3n4I-3CwFbURoTaQuz54etRSR1V_5EmTPl_IM5hVQVQm3Q5LsN1ihLxr7U02rgrDcIRz_twnIMCMeIwbzc_imlpCcz0uT9AXhEZmT4b84IumL3LaMyRlbF7yS87BOuf3wr-PhzLCjmRRFZixth4zJsXy9R34LeKzfrEfayM=; UOR=www.google.com,weibo.com,m.weibo.cn', 'referer':'https://weibo.com/tv/show/1034:4715681229504535?from=old_pc_videoshow', 'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36' } json_data = requests.post(url=url,data=data,headers=headers,timeout=10).json() 四、筛选出视频链接 video_url = "https:" + json_data['data']['Component_Play_Playinfo']['urls']['高清 720P'] print(video_url) 五、保存视频 video_data = requests.get(video_url).content with open("微博某视频.mp4",'wb') as f: f.
单选 1.关系型数据库的发现,推动了数据分析的发展。关于关系型数据库的说法中错的是( D ) A. 其重要特点之一就是能保证事务的一致性B. 支持结构化查询语言SQL,使用方便,学习成本低C. 对非结构化数据支持较差D. 适用于海量数据的高效读写 单选 2.PAAS是( A ) A. Platform as a serviceB. Infrastructure as a serviceC. Software as serviceD. Fuction as service 单选 3.逻辑题:B、C、X为不等的数,当B大于C时,X小于C;但是C绝不会大于B。下面的描述正确的是( A ) A. X绝对不会大于BB. X绝对不会小于BC. X绝对不会小于C 单选 4.单机时代,保护电脑安全的主要方式是( C ) A. 防火墙B. 入侵检测C. 杀毒软件D. WAF 单选 5.数据库管理系统是( B ) A. 操作系统的一部分B. 在操作系统支持下的系统软件C. 一种编译系统D. 一种操作系统 单选 6.计算机的软件系统可分为( D ) A. 程序和数据B. 操作系统和语言处理系统C. 程序、数据和文档D. 系统软件和应用软件 单选 7.阿里云云服务器ECS的英文全称是( A ) A. Elastic Compute ServiceB.
目录
1.1、设置主机名
1.2、编辑主机名IP地址的映射
1.3、网络配置
1.4、关闭并禁用防火墙 // 生产环境当中不允许~
1.5、关闭并禁用网络管理服务
1.6、重启网络服务
1.7、内外网测试
//虚拟机初始化安装完成后,登陆状态下直接操作
1.1、设置主机名 hostname hostnamectl set-hostname +主机名 在输入一次hostname则会发现主机名已更改成功
1.2、编辑主机名IP地址的映射 vi /etc/hosts //按i键进入编辑模式 //增 #--------------------- 192.168.xxx.xxx 主机名 #--------------------- //网关前三位要一致,查看方式:(编辑-虚拟网络编辑器-选择虚拟机-nat设置)
//最后一位取值范围128-254(XXX)
//IP地址之后的主机名自定义即可
//按ESC退出编辑页面,再按 shift+zz 保存并退出
1.3、网络配置 vi /etc/sysconfig/network-scripts/ifcfg-ens33 #---------------------- //改 //按i键进入编辑模式 BOOTPROTO="static" ONBOOT="yes" //当你虚拟机启动的时候网络自动启动 //增 IPADDR="192.168.xxx.xxx" //与1.2新增的保持一致 GATEWAY="192.168.XXX.2" NETMASK="255.255.255.0" DNS1="8.8.8.8" DNS2="114.114.114.114" #---------------------- //按ESC shift+ZZ 保存并退出 } 1.4、关闭并禁用防火墙 // 生产环境当中不允许~ systemctl stop firewalld systemctl disable firewalld //成功会有两条提示信息 1.5、关闭并禁用网络管理服务 systemctl stop NetworkManager systemctl disable NetworkManager 1.
用于PON设置ipv6 Pool范围时,校验ipv6 Pool范围是否为设置的ipv6前缀的子集
前提:ipv6地址格式合法(图中1、2格式)
化简原则:
+全0块“0000”,可以化简为“0”
+多个全0块,可以化简为“::”
+一个IPv6地址中只能出现一个“::”,出现多个全0块时,“::”要化简最长的一段,没有最长的要就近(左)
+“::”可以出现在地址开头或结尾
CompareAddrPoolRange("3001::","3001::1111:111"); function CompareAddrPoolRange(Prefix,ipv6Addr){//对比前缀与地址池起始地址前缀是否相同 var addr_1 = Prefix.split("/"); var addr_2 = ipv6Addr.split("/"); var prefix = addr_1[0]; var ipv6addr = addr_2[0]; var prefix_fomart = convert2CompleteIpV6(prefix).substring(0,19); var prefix_ipv6 = convert2CompleteIpV6(ipv6addr).substring(0,19); console.log(prefix_fomart); console.log(prefix_ipv6); if(prefix_fomart != prefix_ipv6){ return false; } return true; } //ipv6地址去简化 function convert2CompleteIpV6(ip){//将3001::1111:111拓展为3001:0000:0000:0000:0000:1111:111 var ipV6 = ip; var ipv6Address; var index = ip.indexOf("::"); if(index > 0){ var size = 8-(ipV6.split(":").length-1); var tmp = "
浅谈 SOLIDWORKS 的同步建模技术 | 产品探索 SOLIDWORKS 可以用“同步建模”的方式进行产品设计,在 SOLIDWORKS 中这种建模方式我们称之为直接编辑。直接编辑包含移动面、移动/复制实体、圆角/倒角、阵列/镜像、删除/保留实体、删除面、分割/组合等多种建模方式。
这些直接编辑工具怎么使用呢,我们先来了解一下它们的具体功能。
1、移动面:移动面支持在实体或曲面模型上等距、平移以及旋转面及特征;
2、删除/保留实体:支持对实体进行删除或者保留,操作时支持选择删除或者保留的实体;
3、删除面:删除面支持从实体或者曲面上删除面,删除面的同时支持自动修补和剪裁实体(删除和修补选项),也支持生成单个面以封闭任何间隙(删除和填补选项);
4、分割/组合:分割/组合用于对实体进行分割和组合,分割时支持对分割实体的控制,组合时可以通过添加、删除、共同等操作类型实现不同的组合方式。
1、code
import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Maps; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.http.HttpServletRequestWrapper; import com.netflix.zuul.http.ServletInputStreamWrapper; import org.springframework.util.StreamUtils; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Objects; /** * @author code * @version 1.0 * @Date 2021/12/21 9:14 * @Description ${参数过滤器} */ public class ParamFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 2; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.
目录
一、前言
二、数据集
三、网络结构
四、代码
(一)net
(二)dataset
(三)train
(四)test
五、结果
(一)128*128
(二)256*256 六、完整代码
一、前言 pix2pix可以实现画风迁移、图片修复、语义分割、图片上色等等。这里主要实现将facades labels转换成真实图片。由于源码中涉及的功能较多,代码较为复杂,这里我将主要部分拿了出来并做了一些小修改。
在传统的GAN中,生成器G的输入是噪声z,目的是让G去学习一种分布去拟合真实数据的分布。而在pix2pix中,G的输入是facades labels,生成器G一方面要尽可能生成真的图片去骗过D,另一方面要使输出尽可能去逼近facades labels对应的真实图片(利用了L1loss)。G的噪声是通过在网络的dropout层引入的(如果不引入噪声,那么最终训练的G只会逼近已有的训练样本,无法拟合真实数据的分布) 。
pix2pix中判别器D采用了PatchGAN,即D不仅仅只对整张图的真假打分,而是将图片最终分成多个patch,对每个patch进行打分,D只有当图片与fecades labels匹配并且尽可能逼近真实样本时候才会打高分。
二、数据集 数据集采用的是facades数据集,训练样本是成对匹配的(其中fecades图片均以png格式存储,对应真实样本以jpg存储),共有606张图片,训练过程中将数据集按8:2的比例划分训练集和验证集。部分图像对如下图所示。
三、网络结构 生成器G采用了Unet结构,本质为encoder-decoder,网络结构如下图所示(这里以输入图片为256*256为例)。dropout层只在输入输出channel都为512时候才有。
判别器D其实就是简单的卷积神经网络,网络结构如下图所示。
四、代码 (一)net 这里提供了输入为128*128和256*256两种结构的网络
import torch.nn as nn import torch from collections import OrderedDict # 定义降采样部分 class downsample(nn.Module): def __init__(self, in_channels, out_channels): super(downsample, self).__init__() self.down = nn.Sequential( nn.LeakyReLU(0.2, True), nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=4, stride=2, padding=1), nn.BatchNorm2d(out_channels) ) def forward(self, x): return self.down(x) # 定义上采样部分 class upsample(nn.
学C语言的小伙伴,快把小心心安排上吧! 专属程序员的浪漫
#include<stdio.h> #include<stdlib.h> #include<Windows.h> int main() { float x,y,a; for(y=1.5f;y>-1.5f;y-=0.1f) { for(x=-1.5f;x<1.5f;x+=.05f) { a=x*x+y*y-1; putchar(a*a*a-x*x*y*y*y<0.0f?'x':' '); } Sleep(100); putchar('\n'); } getchar(); system("pause"); return 0; }
Git 安装教程(windows)
给新电脑安装下git,顺便记下笔记(安装版本为2.30.2 )
git下载地址: https://git-scm.com/download/win
下载后点击即可进行安装,下面是具体安装步骤。
1)许可申明
点击 “Next” 即可。
2)选择安装路径
根据自己需要修改安装位置。
3)选择安装组件
a) 默认勾选的选项,建议不要动。默认安装了一些组件Git Bash ,Git GUI 以及Git LFS 还有桌面快捷方式以及配置文件默认的文本编辑,使用sh脚本启动git bash.
b) 红色框框决定在所有控制台窗口中使用TrueType字体和是否每天检查Git是否有Windows更新,按需勾选。
注:Git LFS 用于实现 Git 对大文件的支持 ,LFS策略可以节省存储空间和提高性能,比如游戏开发中设计资源文件占用很大。
4)选择开始菜单目录
默认git即可 直接next。
5)选择Git文件默认的编辑器
很少用到,所以默认Vim即可,直接点“Next”。
6)选择Git初始化分支的名称
a) git默认的初始化分支名称为"master"。
b) 根据自己项目业务重新命名 如:main,trunk或者自己填写。
注:已经存在的项目不受影响。
7)选择使用Git的方式
a) 第一个选项, 只从Git Bash命令行工具 使用Git,也是最谨慎的默认的选择。
b) 第二个选项, 从命令行或者第三方软件 使用Git。
c) 第三个选项,在命令提示符中使用Git和可选的Unix工具。
注:这三个选项 我也有点迷 不知什么场景会用到,有啥用,希望有知道的大神回复告知下。
8)选择https传输后端
让Git使用哪个SSL/TLs库来进行HTTPS连接?
a) 第一个选项,使用OpenSSL库,服务器cer证书将使用ca包中.crtw文件进行验证通过,默认选这个。
b) 第二个选项,使用本机Windows安全通道库,服务器证书将在Windows证书存储中进行验证。这个选项还允许您通过Active Directory域服务使用您的公司内部根CA证书。
9)配置结束行转换方式
Git应该如何处理文本文件中的行结尾?
a) 第一个选项,下拉是转换Windows风格,提交转换为iunix风格,在windows这是推荐默认的设置。
在某次使用IDM扩展插件突然提示对话框“此版本的IDM不支持该类下载,请尝试将IDM更新至最新版本。”回想了一下自己好像手欠更新了一下扩展程序。。。
搜索了一下应该是电脑里的IDM和插件版本对应不上的问题。
我的解决方法就是卸载了扩展插件重新安装
在IDM安装目录找到以下crx的扩展插件:
把IDMGCExt.crx复制到一个文件夹里,扩展名改成zip,解压,之后
加载已解压的扩展程序,就安装了。完成之后重新打开浏览器试一下下载东西,成功。
本期视频为大家带来Solidworks两种柔性弹簧的建模方式,第一种方式是使用使零件成为柔性命令,在装配体中直接创建弹簧零件来实现;第二种方式是创建弹簧装配体,然后在顶层装配体中将弹簧设为柔性子装配体,从而实现弹簧的柔性状态。
添加微信“huidusolidworks”,加入solidworks社群,请备注“CSDN渠道”
↓ ↓ ↓下面一起来看看详细操作吧 ↓ ↓ ↓
第一种方法:使零件成为柔性 Step 1 采用自顶向下的建模方式在装配体中添加新零件。在前视基准面上分别绘制两个草图。
Step 2 使用两个草图进行扫面,并设置扭转值为10圈。
Step 3 新建基准面切除多余的实体。
Step 4 退出零件编辑模式,使用激活柔性零部件。
第二种方法:使子装配体成为柔性 1、利用扫面绘制一个半圆,并创建一个基准面和基准轴。
2、绘制好后进行装配。装配关系如下图。除第一个零件和最后一个零件外,左右两边边的基准面分别施加平行约束。同时第一个零件的基准轴和最后一个零件的基准轴施加重合约束。
3、装配好以后将子装配体插入顶层装配体。然后将子装配体设为柔性。
申请SOLIDWORKS试用 慧都科技是SolidWorks在西南地区的正版代理商,提供Solidworks正版试用、技术培训、正版报价 Solidworks 2021年终促销活动正在进行中,5套产品组合9折优惠,送3DEXPERIENCE Draftsight体验1年! 详情咨询“在线客服”
Kubectl基础命令的使用 kubernetes基本概念kubectl管理命令kubectl帮助 Kubectl常用命令的使用explaineditscaleautoscalecluster-infocordonuncordondescribelogsattachexecprot-forwardcplabelapi-resourcesapi-versionsversion使用deployment控制器部署镜像 滚动更新、回滚用Dockerfile编写两个镜像滚动更新、回滚 kubernetes基本概念 Pod:k8s最小部署单元,一组容器的集合
Deployment:最常见的控制器,用于更高级别部署和管理Pod
Service:为一组Pod提供负载均衡,对外提供统一访问入口
Label:标签,附加到某个资源上,用于关联对象、查询和筛选
Namespaces:命名空间。将对象逻辑上隔离,也利于权限控制
kubectl管理命令 类型命令描述基础命令create
expose
run
expose
set
explain
get edit
delete通过文件名或标准输入创建资源; 为Deployment,Pod创建Service;
在集群中运行一个特定的镜像;
在对象上设置特定的功能; 文档参考资料;
显示一个或多个资源; 使用系统编辑器编辑一个资源;
通过文件名,标准输入,资源名称或标签选择器来删除资源部署命令rollout
rolling-update
scale
autoscale管理Deployment,Daemonset资源的发布(例如状态、发布记录、回滚等); 滚动升级,仅限ReplicationController;
对Deployment、ReplicaSet、RC或Job资源扩容或缩容Pod数量; 为Deploy,RS,RC配置自动伸缩规则(依赖metrics-server和hpa)集群管理命令certificate cluster-info top cordon uncordon drain
taint修改证书资源;
显示集群信息; 查看资源利用率(依赖metrics-server); 标记节点不可调度;
标记节点可调度; 驱逐节点上的应用,准备下线维护;
修改节点taint标记 kubectl帮助 kubectl命令官方文档
用kubectl help可以查看kubectl相关的命令
[root@master ~]# kubectl --help kubectl controls the Kubernetes cluster manager. Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/ Basic Commands (Beginner): create Create a resource from a file or from stdin.