1.选中项目----右键----按下图操作,打开 settings.xml 文件 2.找到 <mirrors> 填写阿里镜像地址即可 3.阿里镜像地址 <mirror> <id>nexus-aliyun</id> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
1. 选中 Flie -> Setting 2. 按如下图选项选中,Theme 就可切换不同主题,切换时先点击 apply,看看效果后再点击 ok 按钮。
关于如何使用selenium解决requests.get(url)获取不到页面全部内容的记录 今天在尝试使用requests库进行PWA封禁信息爬取时出现了提取到的字符数组为空的情况,详细信息如下:
问题描述 这里展示部分项目源码与页面源码:
如图所示,id = “root”对应的div中包含有我们想要获取的信息
项目源码
获取到的结果
可以看到id = "root"对应的div中并没有信息,也就是说通过这种方法获取到的页面源码是不完整的
解决方案: 通过尝试,发现使用selenium库通过模拟当前浏览器可以完整地获取页面源码。
selenium 是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera等。selenium 是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行处理(Selenium Grid)。
Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可以用于任何支持JavaScript的浏览器上。
selenium可以模拟真实浏览器,自动化测试工具,支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题。
具体实现: 1.首先在设置中查看浏览器版本号,去浏览器官网下载对应版本的浏览器驱动。本次项目使用的是Edge浏览器,即去微软官网下载Edge浏览器驱动,并将驱动放在Python安装目录/Scripts下。
2.修改后的项目代码如下:
from lxml import etree from selenium import webdriver browser = webdriver.Edge() url = "https://pvp.wanmei.com/csgo/ban" browser.get(url) browser.encoding = "utf-8" browser.page_source 使用Jupyter服务器可以方便的查看每一个步骤的运行结果:
、
3.可以看到:此时id = "root"对应的div下是有内容的,接下来的任务即通过Xpath定位获取目标文本
举例如下,进一步实现:
from lxml import etree from selenium import webdriver browser = webdriver.Edge() url = "
1.什么是跨域?
跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。
• 同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;
跨域举例:
2.为什么会出现跨域?
我们都知道要想访问一个网站,首先要知道这个网站的URL,才能够进入该网站。而URL是由协议、域名、端口组成的(协议,浏览器自动填充;域名的端口默认为80,所以通常这两项不用输入)。而跨域就是说去访问的网站信息中的协议、域名、端口号这三者之中任意一个与当前页面的URL地址不同就是跨域。即使两个不同的域名指向同一个ip地址,也是跨域(即非同源)。
举个栗子:
一个钓鱼网站的页面通过iframe嵌入了某宝的登录页面,如果没有同源限制,钓鱼网站上的js脚本就可以获取到用户账号和密码。也就是说,同源限制策略就是限制了一下几种行为:
1.) Cookie、LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送
3.跨域的解决方案
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域
一、 通过jsonp跨域
通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。
vue.js解决方案:
this.$http.jsonp(‘http://www.domain2.com:8080/login’, {
params: {},
jsonp: ‘handleCallback’
}).then((res) => {
console.log(res);
})
二、 document.domain + iframe跨域
此方案仅限主域相同,子域不同的跨域应用场景。
实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
1.)父窗口:(http://www.domain.com/a.html)
三、 location.
es的起源 Elasticsearch是一个实时分布式搜索和分析引擎,它让你以前所未有的速度处理大数据。es常用于全文搜索、结构化搜索、分析以及将这三者混合使用,它是当下业界最流行的开源搜索框架。很多流行的网站采用es来提供搜索功能。
lucene 说到搜索领域,不得不提Doug Cutting。他开发了lucene,一个用于文本搜索的函数库。2004年,Doug Cutting再接再励,在Lucene的基础上,和Apache开源伙伴Mike Cafarella合作,开发了一款可以代替当时的主流搜索的开源搜索引擎,命名为Nutch。Nutch是一个建立在Lucene核心之上的网页搜索应用程序,可以下载下来直接使用。它在Lucene的基础上加了网络爬虫和一些网页相关的功能,目的就是从一个简单的站内检索推广到全球网络的搜索上,就像Google一样。
后来,Doug Cutting加盟Yahoo,基于google和业界的一些研究成果,开创了流行的大数据框架hadoop。
es Elaticsearch,简称为es, es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。
Shay Banon基于lucene开发了Elasticsearch。
solr 搭建es windows环境 安装es 1解压安装
es7相比es6的更新较大,我们选择使用较新的es7。直接在es官网下载7.14.1安装包,解压即用。
2目录介绍
bin 启动目录
conf 配置目录
log4j2 日志配置jvm.options jvm相关的配置elasticsearch.yml es服务器的配置,默认9200端口 lib 相关jar包
modules 功能模块
plugins 插件,比如ik分词器
3启动
执行elasticsearch.bat
4访问
127.0.0.1:9200
安装head master head master是一款es可视化界面插件。尽管它也提供了一些操作es的接口,但一般我们仅使用它浏览数据。
npm install #安装必须的前端依赖 npm start #启动插件,在package.json目录运行此命令 尽管安装依赖显示失败,但是显示启动成功就访问试试吧。
访问head master
http://localhost:9100
图中看不到es集群的信息,这是因为端口9100和9200之间存在端口跨域问题。
跨域问题
在elasticsearch.yml中添加跨域配置,重启es服务
http.cors.enabled: true http.cors.allow-origin: "*" 再次访问head-master,可以新建索引测试一下能否使用
安装kibana 官网下载kibana安装包并解压
进入bin目录,启动服务即可。ELK基本都是拆箱即用的
访问页面
kibana会自动去访问9200,也就是elasticsearch的端口号,我们直接访问kibana即可
http://ip:5601 操作es 汉化 中文包在 kibana\x-pack\plugins\translations\translations\zh-CN.
目录
前言
一、鼠标事件属性
1. MouseEvent.button属性
2. MouseEvent.clientX,MouseEvent.clientY
3. MouseEvent.offsetX,MouseEvent.offsetY
4. MouseEvent.pageX,MouseEvent.pageY
二、案例
1.案例一
2. 案例二
总结
前言 通过鼠标触发事件,类似用户的行为:
属性描述onclick当单击鼠标时运行脚本。onmousedown当按下鼠标按钮时运行脚本。onmouseup当松开鼠标按钮时运行脚本。onmousemove当鼠标指针移动时运行脚本。onmouseover当鼠标指针移至元素之上时运行脚本,不可以阻止冒泡。onmouseout当鼠标指针移出元素时运行脚本,不可以阻止冒泡。onmouseenter当鼠标指针移至元素之上时运行脚本,可以阻止冒泡。onmouseleave当鼠标指针移出元素时运行脚本,可以阻止冒泡。onmousewheel当转动鼠标滚轮时运行脚本。onscroll当滚动元素的滚动条时运行脚本。 mouseover事件和mouseenter事件,都是鼠标进入一个节点时触发。两者的区别是,mouseenter事件只触发一次,而只要鼠标在节点内部移动,mouseover事件会在子节点上触发多次。
var div = document.getElementById("div") var p = document.getElementById("p") div.onmouseover=function(){ console.log("div") } p.onmouseover=function(){ console.log("p") } //冒泡阶段 div.onmouseenter=function(){ console.log("div") } p.onmouseenter=function(){ console.log("p") } //捕获阶段 一、鼠标事件属性 1. MouseEvent.button属性 MouseEvent.button属性返回一个数值,表示事件发生时按下了鼠标的哪个键。
0代表左键
1代表中键
2代表右键
document.body.onmousedown=function(e){ e=e||window.event console.log(e.button) } 2. MouseEvent.clientX,MouseEvent.clientY MouseEvent.clientX属性返回鼠标位置相对于浏览器窗口左上角的水平坐标,
MouseEvent.clientY属性返回鼠标位置相对于浏览器窗口左上角的垂直坐标,
这两个属性都是只读属性。
document.body.onmousedown=function(e){ e=e||window.event console.log(e.clientX,e.clientY) } 3. MouseEvent.offsetX,MouseEvent.offsetY MouseEvent.offsetX属性返回鼠标位置距离事件作用对象左侧边缘的水平距离,
MouseEvent.offsetY属性返回鼠标位置距离事件作用对象左侧边缘的垂直距离,
这两个属性都是只读属性。
div.onclick=function(e){ e=e||window.event console.
Vuex 提示:
本博客为个人学习中一些笔记整理,如有错误欢迎指正。
部分内容搬运前辈们总结的知识结晶,部分内容为自己在学习中的debug
  ——md空格方式之一
本文章适用于Vue2,Vue3可能对于某些内容进行更新
Vuex可以简单理解为Vue项目的状态管理库,采用集中式存储管理所有组件的状态。
Vuex官方教程
安装并使用 terminal安装:npm install vuex@next --save 默认安装最新版本,但是对于vue2而言,vuex应该使用3版本;对于vue3而言,vuex应该使用4版本,如果我们项目是vue2,此时就不能用上面的默认命令下载,而是安装特定版本
terminal:npm install vuex@3 安装完之后需要使用插件,需要执行Vue.use(),不过我们使用vuex需要使用store仓库进行管理
1.在项目中创建了store文件夹(在src目录下)用来表示Vuex,在里面实现了模块划分(后面会介绍module概念),并且用store.js作为export注册在项目main.js中,以便函数调用
2.在store.js中进行使用vuex并且创建vuex实例
store.js
import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ states, mutations, actions, modules{ x // x为自定义模块 } }) 3.在/src/main.js中进行指定store,这样vm(Vue实例对象)和vc(VueComponent实例对象)全都可以使用$store
main.js
import store from './store/store' const vm = new Vue({ router, //在这里指定store属性 store, render: h => h(App) }).$mount('#app') Vuex由几大核心内容组成,分别为state、getter、mutation、action、module,下面将一一介绍。
state Vuex使用单一状态树(一个Vue项目只有一个store)。个人理解Vuex为前端项目的“数据库”,虽然能够记录所有组件的状态,但并不推荐,只对组件通信中常用状态进行记录和管理即可。
创建moduleA.js,并定义一些state状态
moduleA.js
const moduleA = { state:{ typeA: 'A', numOfA: 1, A:{ isLetter: true, nextLetter: 'B' } }, getters:{.
参考网址:C++基础入门
几个理解的知识点:
1.变量,变量类型,变量名的作用
答:
变量:是用来存放各种数据类型的容器,是一段内存空间。程序中定义了一个变量,就等于程序向内存条申请了一段存储空间。
变量类型:是为了指定多大的内存空间分配给变量,如整型,浮点型,字符型,字符串型,布尔型等。不同变量类型的变量所占用的内存大小是不一样的。
变量名:是给一段内存空间命名,这样就不需要内存空间的物理地址,直接通过变量名,访问内存空间存储的数据,简化操作。
常量:是变量的特殊形式,只是内存空间中的值不能修改。
2.数据类型存在的意义
答:
给变量分配合适的内存空间,如整型,浮点型,字符型,字符串型,布尔型等数据类型的变量所占用的内存空间是不同的。
其中字符型变量、字符串型变量并不是把字符本身放到内存中存储,而是将对应的ASCII编码放入到存储单元。而布尔类型,true存储的是1,false存储的是0。
3.数据类型和数据结构
答:
数据类型:简单数据类型有整型,浮点型,字符型,字符串型,布尔型;复杂数据类型有结构体、类
数据结构:变量是最简单的一种数据存储结构;数组也是一种数据结构;线性表、树、队列等都是数据结构。容器如vector、list、deque、set、map等都是各种数据结构,用来存放数据。
注: 数据结构,强调数据之间的关系,代表一种数据的存储结构,如树,队列,列表,字典等。 数据类型,强调合法的操作,如对字符串,数字可以进行什么样的操作。 4.cin和cout
答:
cin相当于C语言中的scanf函数,用于用户输入数据;
cout相当于C语言中的print函数,用于打印输出数据;
cin >> a; //表示用户输入的数字,存储到变量a中。 cout << "当前输入为:" << a << endl; //表示打印a的值。 5.代码注释
单行注释:// 描述信息 (通常放在一行代码的上方,或者一条语句的末尾,对该行代码解释)
多行注释: /* 描述信息 */ (通常放在一段代码的上方,对该段代码做整体解释)
从七个方面理解C++基本语法的知识体系: 数据类型、运算符、程序流程控制、数组、函数、指针、结构体
一、数据类型 整型:short、int(4)、long、long long
答:
整型所占内存空间大小,因操作系统的种类和位数不同而有所区别。
注意:
硬件的64位和32位,指的是CPU位宽,即CPU可以处理的数据比特数。
软件的64位和32位,指的是程序指令的位宽,包括操作系统的位数,也是我们经常提到的32位和64位含义。
浮点型:float(4)、double(8)
字符型:char(1)
字符串型:字符数组、字符指针、string类
布尔型:bool(1)
二、运算符 算术运算符、赋值运算符、比较运算符、逻辑运算符
三、程序流程控制(逻辑控制) 1.顺序结构 从程序入口开始,程序一步一步顺序执行。
2.选择结构 1)if语句
if
if —else
if—else if—else
1、前端错误如何捕获,promise的错误是如何捕获的 try/catch 1.能捕获包裹体内的同步执行错误; 2.不能捕获语法错误/异步任务错误/Promise任务错误/资源加载错误 window.onerrer 1.能捕获包裹体内的同步执行错误/普通异步任务错误; 2.不能捕获语法错误/Promise任务错误/async任务错误/资源加载错误 window.addEventListener(‘error’) 与onerror差不多 区别:捕获资源加载的错误 Promise异常捕获 通过throw抛出错误,catch捕获 通过reject抛出错误,catch捕获 2、vue的dom diff算法 虚拟dom定义:其实就是一个普通js对象;是用来描述真实dom结构的js对象,不是真实dom; 虚拟dom结构 { children: Array<VNode | string> | underfined //节点下的其他标签 data: any | underfined //节点的属性 elm: Element | Text | underfined //当前虚拟节点对应的真实节点 key: data.key | underfined sel: string | underfined //当前节点标签名 text: string | underfined//当前节点下的文本 } diff算法就是用于比较新旧两个虚拟dom之间差异的一种算法; 旧dom 新dom 1 1 2 5 9 2 5 9 3 4 6 3 4 6 7 8 7 8 diff算法思路: a.
C#联合halcon开发框架源码。
拖拽式编程,无halcon基础也能上手,匹配,测量,条码识别,ocr,定位引导,对位等,支持plc通讯,集成主流相机sdk,系统集成.
YYID:164660819255325资深视觉开发工程师
Typora设置标题在大纲中不显示的解决方法 (icode9.com)
可以看这个
文章目录 一、ACL访问控制列表1. 使用 acl list 命令展现用户权限列2. 使用 acl cat 命令3. 使用 acl whoami 命令查看当前用户4. 使用 acl setuser 命令创建和编辑用户 ACL 二、IO 多线程1. 简介2. 原理架构 三、集群工具支持 Cluster四、Redis6 其他新功能 一、ACL访问控制列表 Redis ACL 是 Access Control List(访问控制列表)的缩写,该功能允许根据可以执行的命令和可以访问的键来限制某些连接
在 Redis 5 版本之前,Redis 安全规则只有密码控制 还有通过 rename 来调整高危命令比如 flushdb,KEYS* ,shutdown 等。Redis 6 则提供 ACL 的功能对用户进行更细粒度的权限控制 :
(1)接入权限:用户名和密码
(2)可以执行的命令
(3)可以操作的 KEY
参考官网:https://redis.io/topics/acl
1. 使用 acl list 命令展现用户权限列 2. 使用 acl cat 命令 (1)查看添加权限指令类别
(2)加参数类型名可以查看类型下具体命令
3. 使用 acl whoami 命令查看当前用户 4.
一、taobao.trade.get( 获取单笔交易的部分信息(性能高),淘宝R2接口,淘宝开发平台oAuth2.0接口代码对接如下:
1.公共参数
名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中,点击获取测试key和secret)secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_search,item_get,item_search_shop等]cacheString否[yes,no]默认yes,将调用缓存的数据,速度比较快result_typeString否[json,jsonu,xml,serialize,var_export]返回数据格式,默认为json,jsonu输出的内容中文可以直接阅读langString否[cn,en,ru]翻译语言,默认cn简体中文versionString否API版本 2.请求参数
请求参数:api=
参数说明:其它参数:参考淘宝开放平台接口文档,与淘宝的参数一致 https://open.taobao.com/api.htm?docId=140&docType=2
名称类型必须描述apiString淘宝开放平台的接口名(如:taobao.picture.upload( 上传单张图片 ))sessionString授权换取的session_id[其他参数]String其它参数:参考淘宝开放平台接口文档,与淘宝的参数一致
https://open.taobao.com/api.htm?docId=140&docType=2 3.请求示例(CURL、PHP 、PHPsdk 、Java 、C# 、Python...)
# coding:utf-8 """ Compatible for python2.x and python3.x requirement: pip install requests """ from __future__ import print_function import requests # 请求示例 url 默认请求参数已经做URL编码 url = "https://vx19970108018/taobao/custom/?key=<您自己的apiKey>&secret=<您自己的apiSecret>&method=" headers = { "Accept-Encoding": "gzip", "Connection": "close" } if __name__ == "__main__": r = requests.get(url, headers=headers) json_obj = r.json() print(json_obj) 4.响应示例
{ "trade_get_response":{ "trade":{ "seller_nick":"我在测试", "pic_path":"http:\/\/img08.taobao.net\/bao\/uploaded\/i8\/T1jVXXXePbXXaoPB6a_091917.jpg", "
1.安装依赖
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel gcc 2.添加epel扩展源
yum -y install epel-release yum -y install libffi-devel yum install python-pip 3.下载python3源码
wget https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tar.xz 4.解压
tar -xf Python-3.9.6.tar.xz 5.配置
cd Python-3.9.6 ./configure prefix=/usr/local/python3 --with-ssl 6.编译及安装
make && make install 7.添加软连接
ln -s /usr/local/python3/bin/python3.9 /usr/bin/python3 8.查看安装版本
python -V python2 -V python3 -V 9.查看软连接
cd /usr/bin ll python* ll pip* 10.添加pip3软连接
ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3
本文目的 1、Spring5.x单纯使用spring-jcl打印日志是什么输出格式(JUL)
2、Spring5.x如何让spring-jcl用log4j2输出,直接加入log4j2依赖[调皮]
3、Spring5.x加入log4j2又加了slf4j+logback,都spring-jcl的api打印日志,为什么都是log4j2输出
4、Spring5.x加入log4j2又加了slf4j+logback,分别用jcl和slf4j的api打印日志,为什么日志输出格式不统一
5、如何做到和SpringBoot一样统一日志输出格式(slf4j+桥接器)
准备 Spring版本号:5.2.19.RELEASE
知识储备:1、需要了解slf4j、log4j2、logback;2、什么是slf4j的绑定器;3、什么是slf4j的桥接器
说明 该模块是对输出的日志框架进行适配,是从Apache的commons-logging改造而来
Spring更喜爱log4j(log4j2),用spring-jcl这个来表明
Spring5.x开始自己实现了日志框架的适配器在spring-jcl模块下 开始 spring5.x现象: 1、自定义工程,加入spring-context依赖,使用spring-jcl下的LogFactory
package com.csh.spring.log; import org.apache.commons.logging.LogFactory; //import org.slf4j.LoggerFactory; public class Test { public static void main(String[] args) { //spring-jcl api LogFactory.getLog(Test.class).info("log4j2 say hello world!!"); // //slf4j api // LoggerFactory.getLogger(Test.class).info("logback say hello world!!"); } } 2、没有log4j2依赖,执行代码,打印如下 3、加入log4j2依赖
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.17.2</version> </dependency> 4、添加logback依赖和在resources中logback.xml配置
我在logback设置了时间-线程高亮,日志级别绿色 ,log4j2是黑底白字
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> a、都是用jcl的api打印日志
package com.csh.spring.log; import org.apache.commons.logging.LogFactory; import org.
参考:https://blog.csdn.net/zcn596785154/article/details/121281668
学习目标: 例如:
git提交代码风格 自古至今,无规矩不成方圆,Git提交也有其规范。
用于说明本次commit的类别,只允许使用下面7个标识
feat:新功能(feature)fix:修补bugdocs:文档(documentation)style: 格式(不影响代码运行的变动)refactor:重构(即不是新增功能,也不是修改bug的代码变动)test:增加测试chore:构建过程或辅助工具的变动
用Java实现猜数字小游戏(范围0-20)
利用for死循环让用户能一直猜数字,直到猜对,跳出循环。
输出结果
源码:
//猜数字小游戏
//导包
//java提供做随机的类
import java.util.Random;
//java提供接收用户键盘输入的类
import java.util.Scanner;
public class Exercise{
public static void main(String[] args){
//输出游戏名字
System.out.println("猜数字小游戏0-20");
//创建随机类的实例
Random rd=new Random();
//使用功能
int sjs=rd.nextInt(20);
for(;true;){
//创建接收用户键盘输入的实例
Scanner sc=new Scanner(System.in);
//输出提示语
System.out.print("请输入您猜的数字:");
//使用功能
int srs=sc.nextInt();
//判断随机数和输入数的大小,若随机数大则输出您猜小了,
if(sjs>srs){
System.out.println("您猜小了。");
//若随机数小则输出您猜大了,
}else if(sjs<srs){
System.out.println("您猜大了。");
//若随机数和输入数相等则输出恭喜您!您猜对了!
}else{
System.out.print("恭喜您!您猜对了!");
//猜对break跳出循环
break;
}
}
}
}
知识点:for死循环
for( ; true ; ){
循环体;
}
欢迎补充。
Java基础 说下面向对象四大特性Java语言有些特点什么是Java程序的主类?应用程序和小程序的主类有何不同?访问修饰符public,private,protected,以及不写(默认)时的区别?float f=3.4;是否正确?Java有没有goto?&和&&的区别?Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?用最有效率的方法计算2乘以8?什么是Java注释Java有哪些数据类型final 有什么用?final finally finalize的区别String str = "i" 和String str = new String("1")一样吗?Java 中操作字符串都有哪些类?它们之间有什么区别?Java中为什么要用 clone?深克隆和浅克隆?new一个对象的过程和clone一个对象的区别?Java中实现多态的机制是什么?谈谈你对多态的理解?构造器(constructor)是否可被重写(override)?两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?String类的常用方法有哪些?char型变量中能否能不能存储一个中文汉字,为什么?this关键字的用法super关键字的用法this与super的区别static存在的主要意义static的独特之处static应用场景static注意事项break ,continue ,return 的区别及作用在Java中定义一个不做事且没有参数的构造方法的作用构造方法有哪些特性?静态变量和实例变量区别静态方法和实例方法有何不同?什么是方法的返回值?返回值的作用是什么?什么是内部类?内部类的分类有哪些Java中异常分为哪些种类?hashCode 与 equals (重要)hashCode()介绍为什么要有 hashCode抽象类和接口(Java7)的区别Java 8的接口新增了哪些特性?重写和重载的区别ArrayList和LinkedList有什么区别?HashMap是怎么实现的?HashMap在Java7和Java8中的实现有什么不同?HashMap有时候会死循环,你知道是什么原因吗?ConcurrentHashMap是怎么实现的?静态代理和动态代理的区别JDK动态代理和CGLIB动态代理的区别 Java多线程 说说synchronized的实现原理ReentrantLock与synchronized的区别ReentrantLock实现原理Java原子类AtomicInteger实现原理Java线程池实现原理ThreadLocal实现原理InheritableThreadLocal原理知道吗?说一下synchronized锁升级过程了解过什么是“伪共享”吗?“伪共享”出现的原因是什么?如何避免“伪共享”?Java里的线程有哪些状态?什么是悲观锁?什么是乐观锁?怎么停止一个运行中的线程?说一下你对volatile的理解?并发编程三要素?线程池的优点?CyclicBarrier和CountDownLatch的区别什么是CAS?CAS的问题什么是AQS?AQS支持几种同步方式?什么是自旋锁?什么是多线程的上下文切换?什么是线程和进程?程序计数器为什么是私有的?虚拟机栈和本地方法栈为什么是私有的?并发与并行的区别?什么是线程死锁?如何避免死锁?sleep() 方法和 wait() 方法的区别和共同点?为什么我们调用 start() 方法时会执行 run() 方法,为什么我们不能直接调用 run() 法?什么是线程安全问题?如何解决?什么是活锁?什么是线程的饥饿问题?如何解决?什么是线程的阻塞问题?如何解决?synchronized 关键字和 volatile 关键字的区别说一说几种常见的线程池及适用场景?线程池都有哪几种工作队列?什么是线程安全?Java中如何获取到线程dump文件Java中用到的线程调度算法是什么?Thread.sleep(0)的作用是什么?单例模式的线程安全性Semaphore有什么作用?Hashtable的size()方法中明明只有一条语句"return count",为什么还要做同步?同步方法和同步块,哪个是更好的选择?高并发、任务执行时间短的业务怎样使用线程池?并发不高、任务执行时间长的业务样使用线程池?并发高、业务执行时间长的业务怎样使用线程池? Java虚拟机 说一下JVM的内存结构?栈帧里面包含哪些东西?程序计数器有什么作用?字符串常量存放在哪个区域?你熟悉哪些垃圾收集算法?Java里有哪些引用类型?JVM怎么判断一个对象是不是要回收?GC Roots 有哪些?你知道哪些GC类型?对象都是优先分配在年轻代上的吗?你了解过哪些垃圾收集器?说说CMS垃圾收集器的工作原理说说G1垃圾收集器的工作原理说说ZGC垃圾收集器的工作原理ZGC收集器中的染色指针有什么用?说说类加载的过程说下有哪些类加载器?什么是双亲委派机制?双亲委派机制可以被违背吗?请举例说明。Tomcat是怎么打破双亲委派机制的呢?Java对象的布局了解过吗?什么情况下会发生栈内存溢出?JVM新生代中为什么要分为Eden和Survivor?JVM中一次完整的GC流程是怎样的,对象如何晋升到老年代?什么是指令重排序?什么是内存屏障?什么是happen-before原则?说说你知道的几种主要的JVM参数怎么打出线程栈信息?为什么需要双亲委派模式?怎么打破双亲委派模型?说一下堆和栈的区别Java 8 为什么要将永久代(PermGen)替换为元空间(MetaSpace)呢?说一下Java对象的创建过程对象的访问定位有哪几种方式?说一下堆内存中对象的分配的基本策略Minor Gc和Full GC 有什么不同呢?Java会存在内存泄漏吗?请简单描述。如何判断一个类是无用的类?介绍一下类文件结构吧!说一下 JVM 调优的工具?JVM调优命令有哪些?JRE、JDK、JVM 及 JIT 之间有什么不同?程序计数器为什么是私有的?如何判断一个常量是废弃常量 ? Java IO Java 中有几种类型的流?什么是 java序列化?如何实现 java 序列化?字节流和字符流的区别?PrintStream、BufferedWriter、PrintWriter的比较?什么是节点流,什么是处理流,它们各有什么用处,处理流的创建有什么特征?流一般需要不需要关闭,如果关闭的话在用什么方法,一般要在那个代码块里面关闭比较好,处理流是怎么关闭的,如果有多个流互相调用传入是怎么关闭的?什么是BIO什么是NIO什么是AIO同步与异步阻塞与非阻塞同步、异步、阻塞、非堵塞通道是个什么意思?缓冲区是什么意思?IO多路复用的底层原理 MySQL什么是索引? 1.什么是索引?
2.索引是个什么样的数据结构呢?
3.Hash索引和B+树索引有什么区别或者说优劣呢?
在Python 3中,Tkinter库在Python中的模块名称被重命名为tkinter,在程序中使用时,需要先导入该模块。
Options选项 Tkinter提供了一组通用的属性来控制控件的外观和行为,可在创建控件时通过参数设置属性,也可以调用控件的config()方法来设置属性。
尺寸设置:在设置控件与尺寸有关的属性(如边框宽度bd、容器的宽度width或高度height等)且直接使用整数时,其的默认单位为像素。label1.config(bd=2)颜色设置:颜色属性(如背景色、前景色等)可设置为颜色字符串,字符串中可使用标准颜色名称或以#开头的RGB颜色值。label1.config(bg='#00ff00') Python常用填充颜色: Gray(灰色) light gray(浅灰色) brown(棕色) orange(橙色) olive(橄榄绿) green(绿色) cyan(青色)blue(蓝色) purple(紫色)pink(粉色) red(红色) 字体设置:控件的font属性用于设置字体名称、字体大小和字体特征,justify属性设置文本对齐方式。label1.config(font=('隶书',20,'bold'),justify = "left") 显示图片:在Windows系统中,可调用tkinter.PhotoImage类来引用文件中的图片,然后通过控件的image属性使用图片,支持gif、png等格式的图片文件使用绑定变量:文本控件使用textvariable属性绑定StringVar变量,数值控件,使用variable属性绑定BooleanVar、DoubleVar或IntVar变量。调用变量的set()方法设置变量的值,变量值同步反映到控件,调用get()方法可通过绑定变量返回控件的值 控件简介 Tkinter类
名称
简介
Label
标签
用于显示不可编辑的文本或图标。width/height:宽度高度以英文字符大小为单位,汉字占两个字符
Button
按钮
代表按钮组件,用来指定用户的单机操作,可以包含文本和图形
Entry
单行输入框
用户可输入内容,添加show="*"设置密码框
Checkbutton
复选框
可供用户勾选的复选框
Listbox
列表框
列出多个选项,供用户选择
Menu
菜单
菜单组件
Menubutton
菜单按钮
用来包含菜单的按钮(包括下拉式、层叠式等),可以替代Menu使用
OptionMenu
菜单按钮
Menubutton的子类,也代表菜单按钮,可通过按钮打开一个菜单
Message
消息框
类似于标签,但可以显示多行文本;后来当Label也能显示
Scrollbar
滚动条
配合Canvas、Entry、Listbox和Text等控件使用
Canvas
画布
提供绘图功能,包括直线、矩形、椭圆、多边形、位图等
Framer
容器
用于装载其它GUI组件,作为控件容器使用,实现控件分组
Toplevel
顶层
容器类,用来创建主窗口的子窗口,可用于为其他组件提供单独的容器;Toplevel有点类似于窗口
LabelFrame
容器
也是容器组件,类似于Frame,但它支持添加标题
Scale
滑块
允许通过滑块来设置数字值
torchvision的tranform中,读取图像采用PIL图像,而一般情况下我们都是用cv2,这里介绍下两者的区别,
PIL读取图片scale为(0~1),读取为RGB格式,对于彩色图像,不管其图像格式是PNG,还是BMP,或者JPG,在PIL中,使用Image模块的open()函数打开后,返回的图像对象的模式都是“RGB”。而对于灰度图像,不管其图像格式是PNG,还是BMP,或者JPG,打开后,其模式为“L”。
data = np.array(Image.open(img_path)) data = np.transpose(data,(2,0,1))#转换通道 caffe.io.load_image()读取图片scale为(0~1),读取为RGB格式,通道格式为(H,W,C)
cv2.imread()读取图像scale为(0~255),读取为BGR 格式,通道格式为(H,W,C),即行,列、通道数(Row, Col, C)。
round( )函数简介 round() 函数作用就是,返回浮点数x的四舍五入值。
round( x [, n] )
参数x,n均为数值表达式,返回值为x的四舍五入值。n为保留的小数位数,不加n则只保留x四舍五入后的整数部分。
>>> round(2.3)
2
>>> round(2.45, 1)
2.5
>>> round(2.675, 2)
2.67
round()函数只有一个参数,不指定位数的时候,返回一个整数,而且是最靠近的整数,类似于四舍五入,当指定取舍的小数点位数的时候,一般情况也是使用四舍五入的规则,但是碰到.5的情况时,如果要取舍的位数前的小数是奇数,则直接舍弃,如果是偶数则向上取舍。根据取舍的位数前的小数奇偶性来判断,奇偶平分,符合公平性原则。
为什么需要平分呢?原因就是部分小数无法用二进制完整表示,如1.15,转为二进制将是很长的一串数字:1.0010011001100110011001100110011001100110011001100110011 这可不是简单的几个字节就能存放下的。因此这里就出现了取舍的问题。
那么正确的四舍五入是否无法实现了呢?当然是有解决办法的。比如,当你需要四舍五入保留两位小数的时候,可以将数值乘以100再除以100.0:
>>> round(2.675 * 100)/100.0
2.68
这样可以解决部分浮点数四舍五入的问题。为什么是部分呢?笔者发现:
>>> round(2.135*100)/100.0
2.13
检验下过程:
>>> 2.135*100
213.49999999999997
>>> Decimal(2.135)*100
Decimal('213.4999999999999786837179272')
由于二进制导致这个结果
目录
一、运用unity Live Capture插件与iphone Unity Face Capture软件
1. 版本要求
2. unity中操作:
(1)引入Live Capture Package
(2)创建一个空物体(命名:Recorder),添加Take Recorder组件。
(3)将模型拖入场景,并添加ARKit Face Actor组件,将该模型制作成Prefab。
(4)设置模型ARKit Face Actor组件中的mapper。
(5)设置New FaceDevice的ARKit Face Device组件的Actor值。
(6)创建服务器。
3. iphone下载Unity Face Capture软件
二、通过算法数据来控制BlendShape数值
1.相关函数
2.实现
一、运用unity Live Capture插件与iphone Unity Face Capture软件 1. 版本要求 unity版本:Unity Editor 2020.3.16f1 or later versioniphone版本:iOS 14.6 or higher参考文档:About Live Capture | Live Capture | 1.0.1 (unity3d.com) 2. unity中操作: (1)引入Live Capture Package Live Capture在Package Manager中通过git url的方式进行添加:
(2)创建一个空物体(命名:Recorder),添加Take Recorder组件。 在该组件下添加ARKit Face Device:此时会在Recorder物体下自动创建New FaceDevice,该物体上有个ARKit Face Device组件。
前言 本文节选UG472的第二章,进行整理翻译,用于介绍7系列 FPGA的时钟布线资源。
文章目录 前言时钟布线资源概述时钟缓冲器选择注意事项时钟功能输入单个时钟驱动单个 CMT单个时钟驱动多个 CMT具有时钟功能的输入引脚布局规则 全局时钟资源Clock Tree and Nets - GCLKClock RegionsGlobal Clock Buffers全局时钟缓冲器原语BUFGCTRLBUFGBUFGCE and BUFGCE_1BUFGMUX 和 BUFGMUX_1BUFGMUX_CTRL 其他使用模型使用 BUFGCTRL 的异步 MUX带时钟使能的 BUFGMUX_CTRL reference 时钟布线资源概述 7 系列 FPGA 具有多种时钟布线资源,可支持各种时钟方案和要求,包括高扇出、短传播延迟和极低偏移。 为了最好地利用时钟布线资源,您必须了解如何将用户时钟从 PCB 获取到 FPGA,确定哪些时钟布线资源是最佳的,然后通过使用适当的 I/O 和时钟缓冲器来访问这些时钟布线资源。
时钟缓冲器选择注意事项 7 系列 FPGA 具有丰富的时钟资源。 各种缓冲器类型、时钟输入引脚和时钟连接满足许多不同的应用要求。 选择适当的时钟资源可以提高可布线性、性能和通用 FPGA 资源利用率。 对于某些应用和设计,平面图或其他类型的手动指导也会对实施产生很大影响。
BUFGCTRL(最常用作BUFG)是最常用的时钟布线资源。 这些真正的全局时钟可以连接到设备上的每个时钟点。
然而,在某些情况下,出于性能、功能或时钟资源可用性的原因,使用备用时钟缓冲器更为有利。 BUFG 最适合在以下情况下部署:
设计或设计的一部分在设备的大范围内具有全局影响,并且功能本地化是不可能的。跨越多个时钟区域、级联或需要连接到不在附近的CLB 的硬件功能块,例如块RAM、DSP 或集成IP。通过切换时钟同步(无毛刺)或异步,应用程序能够从停止的时钟切换或选择具有不同频率的时钟(例如,降低功耗)。时钟使能(CE) 功能可用于在非工作期间降低功耗。 然而,在大多数情况下,由于时序(CE 延迟)限制,不应使用 CE 功能在时钟元件处模拟真正的 CE 逻辑功能。CE 功能可用于在设备启动后同步初始化的时钟元素。 BUFR 和 BUFIO 组合的主要目的是支持源同步接口。 当接口被放置在单个区域中时,BUFIO 为 SelectIO 的高速端提供时钟,BUFR 为提供时钟域传输功能的 FPGA 逻辑提供低速的反串行/串行端时钟。
一、镜像文件的下载 请提前准备 Windows 10 ISO 镜像文件
可以观看我前一篇文章:Win10 镜像 ISO下载
二,在VMware中配置镜像文件 1、打开VMware软件,点击创建新的虚拟机 2、点击自定义(高级) 3、直接下一步即可 4、选择稍后安装操作系统 5、选择微软的window,版本要根据自己的镜像文件来决定,选择好后点击下一步 6、虚拟机名称:可自定义更改! 安装位置:建议不要安装在C盘,完事后下一步 7、这里用BIOS就可以,然后下一步 8、这里根据物理机的硬性要求,自定义设置。 9、分配运行内存 10、设置网络 11、默认点击下一步 12、选择SCSI,然后点击下一步 13、创建一个新的虚拟磁盘 14、分配磁盘空间,选择单个文件初期方便管理 15、默认,点击下一步 16、点击自定义硬件 17、选择win10的镜像文件 18、移除不需要的设备 19、最后点击完成 20、点击开始此虚拟机进入安装win10 三,进入windows10安装界面 1、准备工作已经完成,下面开始进入win10的安装界面 2、选择语言,然后下一步开始安装 3、现在安装 4、跳过产品密钥 5、选择安装的版本 6、勾选我接受,然后下一步 7、选择自定义安装 8、选择磁盘,然后下一步 9、等待安装即可 10、自动重启,不用操作 11、稍等片刻 12、选择区域 13、选择键盘布局 14、跳过 15、耐心等待系统设置 16、设置主机名称 17、设置密码 18、设置安全问题 19、接受 20、稍等片刻 21、以后再说 22、进入桌面 四、安装 VMware Tools 1、选择虚拟机,然后点击 安装 VMware Tools 2、点击文件资源管理器,点击此电脑,双击DVD 驱动器(D:)VMware Tools 3、选择是,继续安装 4、等待加载 5、点击下一步 6、选择典型安装,点击下一步 7、点击安装 8、安装中。。。 9、点击完成 10、点击是,重启虚拟机,完成VMware Tools的安装
在STM32中,绝大多数事件都是不可见的,但是事件几乎都与终端功能绑定在一起,所以通常我们开启中断功能来使用相应的事件
EXTI:拓展中断和事件控制器,是stm32上的一个外设,可以捕获外部输入线电平变化等等一些事件,EXTI捕获到事件后,还可以生成相应的EXTI中断及等等的一些终端
EXTI的2个功能:捕获外部输入等事件,生成EXTI中断等中断请求
当输入线发生电平变化时,就会被边沿检测电路检测到,然后上升沿触发选择器和下降沿触发选择器会对这个信号进行选择,比如设置了下降沿触发寄存器,同时边沿检测电路检测到电平由1-0,则这个信号会通过或门,这就是硬件触发,同样的,软件中断事件寄存器的中断请求也可以通过或门,称为软件触发,信号通过或门,如果事件屏蔽器没有屏蔽该信号,则信号会到达脉冲发生器,发起中断请求,货唤醒CPU,中断请求会通过或门到达请求挂起寄存器,如果中断屏蔽寄存器没有屏蔽请求挂起寄存器,这一中断请求就会被送到NVIC
使用CubeMX进行中断配置
1.先进行系统时钟配置,选择外部晶振
2.进行最高频率设置
3.进入GPIO,开始中断配置,随便点击一个引脚,选择EXTI项
我们可以通过查阅参考手册,知道引脚在哪些事件线上
4.设置触发方式
5.设置中断优先级
6.代码输出设置
7.生成代码
自动生成的代码已经完成了刚才的配置
生成的代码可以复制到自己的项目中
中断的触发过程:
触发EXTI中断,CPU到中断向量表中取到存放在其中的偏移量,也就是入口地址,最后跳转到中断服务函数中
以下都是中断向量表中的服务函数,触发中断时,CPU就会到这里,根据终端编号进行偏移,取到偏移地址,EXTI被触发,就会跳转到下图红框部分
halcon变量窗口的图像变量不显示,重启软件和电脑都没用 有幸遇到halcon变量窗口的图像变量不显示,重启软件和电脑都没用这个沙雕问题,也是找了蛮久才发现解决办法特意记录一下。
这是正常情况下的窗口(左边)和图像变量不显示的窗口(右边): 解决方法: 鼠标左键双击图像中红框的位置 2.双击完之后把鼠标移动到如图指定的区域,会显示移动鼠标来调整窗口大小,然后按住鼠标左键向右拖动窗口
3.拖动完之后会如下图显示,双击图像中红框位置即可。
问题挺沙雕,遇到也是真难搞。
Python GUI案例之看图猜成语(第三篇) 前言看图猜成语小程序开发(第三篇)游戏闯关模式页面 Python GUI案例之看图猜成语开发(第一篇)
Python GUI案例之看图猜成语开发(第二篇)
Python GUI案例之看图猜成语开发(完结篇)
前言 我们将要实现这些功能:
一,游戏首页页面:在首页页面里需要实现绘制一个看图猜成语文字的标题,定义两个按钮功能(开始游戏,退出游戏),还有一个输入游戏昵称的功能并且要对昵称进行验证是否为空,才能开始游戏;二,游戏选择模式页面:在首页点击开始游戏后,进入游戏的选择模式页面,分为训练模式和闯关模式两种;三,游戏训练模式页面:将成语图片加载后,只实现猜成语功能(一张图片,一个输入框,一个按钮)和回答的准确率;四,游戏闯关模式页面:将实现自定义有多少个关卡数,16个汉字提示(12个随机生成的干扰汉字),游戏通关记录所用的时间。 (素材提取:https://download.csdn.net/download/qq_59142194/85827790)
看图猜成语小程序开发(第三篇) 终于来到第三篇了!!!
游戏闯关模式页面 在这里我们将实现自定义有多少个关卡数,16个汉字提示(12个随机生成的干扰汉字),游戏通关记录所用的时间,主要要注意下面3个的实现功能。
自定义关卡数
在自定义关卡数时(默认10关),我们需要在游戏选择模式页面中点击闯关模式后添加ttkbootstrap里面的一个查询框Querybox,然后根据提示输入关卡数后则将进入游戏闯关模式页面。
def game_chuangguan_mode(self,event): # 默认10个关卡(initialvalue=10) number = Querybox.get_integer(prompt="请设置关卡数量:",title="自定义关卡数量 ",initialvalue=10,minvalue=0,maxvalue=50) if number: self.frame.destroy() game_chuangguan_page(self.nickname,number) ① 创建四个用于显示选择结果的标签,在这里还要定义一个self.answer_list 列表来装下生成的标签对象,以便后面在标签上配置文字configure()。
# 创建四个用于选择结果的标签 def create_selection_result_label(self): self.answer_list = [] for i in range(4): label = ttk.Label(self.canvas, text='', font=("微软雅黑", 35), background='', width=2, cursor='hand2') label.place(x=130 + i * 100, y=450) self.answer_list.append(label) 重选按钮,点击执行后就会将self.answer_list 列表里面的标签对象全部摧毁后重新创建。
# 重选 def update_label(self): self.CLICKTIMES = 0 self.
1~100以内猜数字游戏
一、猜数字的实现思路
难点:随机数的产生和循环语句、分支语句的运用
二、随机数的产生
2.1 函数 int rand(void):生成一个随机的整数,范围为0~RAND_MAX(具体指看编译器)不需要 参数,函数返回类型为整型
函数的具体简介:
但这样产生的随机数在每次执行代码时产生的随机数一致。这样每次所猜数字的值都一样,那这个游戏就没有趣味性了。例:
根据我们的需求,我们需要的随机数需要完全随机,没有规律可言,这里我们就可以将随机数与时间结合起来,时间是在不断改变的,这里就产生了时间戳的概念。怎样才能将时间和产生的随机数结合起来呢?
查看 rand()函数的用法,在调用 rand()函数之前可以调用 srand()来 生成随机数的生成器。
2.2 函数 void srand(unsigned int seed):该函数没有返回值,传参的时候需要传一个无符号的整形。 函数作用是设置一个随机开始的起点,如果每次运用该函数都需要进行传参,那么每需要一个随机数就要传一个数字,这样就不方便。例:
int main() { srand(999); int ret = rand(); printf("%d\n", ret); return 0; } 所以我们需要传一个值,这个值会不断地变化,这样就可以联想到时间是不断地改变。
时间戳:每一个时间相对应计算机起始时间的差值,单位是秒,只要时间改变,对应的时间戳就在改变。可以通俗地理解为每一个时间对应一个不同的数值。
2.3 生成时间戳:需要用到 time_t time( time_t *timer ) 函数
time_t time( time_t *timer )函数:函数的返回值就是时间戳,其类型是,返回的就是时间戳,需 要传参的是一个指针,如果不需要用参数的时候可以传一个空 指针NULL
time_t:是C语言规定的一种类型,是一个long long的整型
我们在对srand传参的时候需要传一个无符号的整型,所以需要对time的返回值进行强制类型转换。产生随机数的代码为:
#include<time.h> #include<stdlib.h> int main() { srand((unsigned int)time(NULL)); int i= 0; for (i = 1; i <= 10; i++) { int ret = rand(); printf("
本文主要讨论图数据库背后的设计思路、原理还有一些适用的场景,以及在生产环境中使用图数据库的具体案例。
从社交网络谈起 下面这张图是一个社交网络场景,每个用户可以发微博、分享微博或评论他人的微博。这些都是最基本的增删改查,也是大多数研发人员对数据库做的常见操作。而在研发人员的日常工作中除了要把用户的基本信息录入数据库外,还需找到与该用户相关联的信息,方便去对单个的用户进行下一步的分析,比如说:我们发现张三的账户里有很多关于 AI 和音乐的内容,那么我们可以据此推测出他可能是一名程序员,从而推送他可能感兴趣的内容。
这些数据分析每时每刻都会发生,但有时候,一个简单的数据工作流在实现的时候可能会变得相当复杂,此外数据库性能也会随着数据量的增加而锐减,比如说获取某管理者下属三级汇报关系的员工,这种统计查询在现在的数据分析中是一种常见的操作,而这种操作往往会因为数据库选型导致性能产生巨大差异。
传统数据库的解决思路 传统数据库的概念模型及查询的代码 传统解决上述问题最简单的方法就是建立一个关系模型,我们可以把每个员工的信息录入表中,存在诸如 MySQL 之类的关系数据库,下图是最基本的关系模型:
但是基于上述的关系模型,要实现我们的需求,就不可避免地涉及到很多关系数据库 JOIN 操作,同时实现出来的查询语句也会变得相当长(有时达到上百行):
(SELECT T.directReportees AS directReportees, sum(T.count) AS count FROM ( SELECT manager.pid AS directReportees, 0 AS count FROM person_reportee manager WHERE manager.pid = (SELECT id FROM person WHERE name = "fName lName") UNION SELECT manager.pid AS directReportees, count(manager.directly_manages) AS count FROM person_reportee manager WHERE manager.pid = (SELECT id FROM person WHERE name = "fName lName") GROUP BY directReportees UNION SELECT manager.
EXTRACT(DOW FROM CURRENT_DATE) 函数的返回值,0表示星期日,6表示星期六
测试数据
select extract(DOW FROM cast('20220630' as TIMESTAMP)),
extract(DOW FROM cast('20220701' as TIMESTAMP)),
extract(DOW FROM cast('20220702' as TIMESTAMP)),
extract(DOW FROM cast('20220703' as TIMESTAMP)),
extract(DOW FROM cast('20220704' as TIMESTAMP)),
extract(DOW FROM cast('20220705' as TIMESTAMP)),
extract(DOW FROM cast('20220706' as TIMESTAMP))
select current_date||'/'||
(case extract(DOW FROM current_date) when 1 then 'Monday'
when 2 then 'Tuesday'
when 3 then 'Wednesday'
when 4 then 'Thursday'
when 5 then 'Friday'
when 6 then 'Saturday'
Tarjan算法 1 算法简介 还记得无向图判连通块吗?对于无向图中,判连通块是一件很容易的事。你只需要dfs(深度优先搜索)一下就可以了。但是,如果我们把无向图换成有向图呢?
这就是另一个故事了…
2 算法定义 Robert Tarjan计算机科学家,以LCA,Tarjan等算法闻名。Tarjan是求强连通分量的一个强力的算法。
要理解Tarjan这个算法,我们先讲几个定义:
强连通分量 :
对于一个分量,若任意两个点相通,则称为强连通分量。
树边 :
对于一个图的dfs树,它的树边便是此图的树边。
返祖边 :
对于一个图的dfs树,可以使得儿子节点返回到它的祖先的边为返祖边。
横插边 :
对于一个图的dfs树,可以使得一个节点到达另一个节点且它们互不是祖先的边为横插边。
神奇海螺结束!
3 算法详细 先讲一下我们要用到的数组。
dfn:第 i i i个节点他的时间戳
low:第 i i i个节点他最多经过一条返祖边所能到达的最小时间戳
st:一个栈,用来储存当前还未确定但已经扩展过的点
co:第 i i i个节点他所在的强连通分量编号
我们讲一下算法流程。
此时来到了点 u u u
扩展他的子节点,这里假设现在到的子节点为 v v v,扩展完了就来到第 5 5 5步
三种情况:
!dfn[v],即还未扩展的点,则我们直接来到第 4 4 4步!co[v]&& dfn[v],即还未出栈但已扩展过的点(就是返祖/横叉了嘛),我们更新一下 l o w u = min ( l o w u , d f n v ) low_u = \min(low_u, dfn_v) lowu=min(lowu,dfnv),并返回第 2 2 2步。(看不懂的感性理解一下)co[v] && dfn[v],即已出栈且遍历过,那么我们直接返回第 2 2 2步 我们先对 v v v这个顶点扩展一下(即返回第 1 1 1步),然后把 l o w u = min ( l o w u , l o w v ) low_u = \min(low_u, low_v) lowu=min(lowu,lowv)更新一下,接着回到第 2 2 2步
一、找一个STM32的裸机工程模板
我们以STM32F103裸机程序为例
随便找的一个裸机程序
二、去官网上下载FreeRTOS V9.0.0 源码
在移植之前,我们首先要获取到 FreeRTOS 的官方的源码包。这里我们提供两个下载 链 接 , 一 个 是 官 网 : http://www.freertos.org/ , 另 外 一 个 是 代 码 托 管 网 站 : https://sourceforge.net/projects/freertos/files/FreeRTOS/。虽然不是最新版本的源码包但是因为内核很稳定, 并且网上资料很多所以我们选用V9.0.0 版本
我们打开 FreeRTOS 的代码托管网站,就可以看到 FreeRTOS 的源码及其版本信息了, 具体见图
点开V9.0.0下载zip这个,
解压完成后就会得到一个完整的Freertos源码包
FreeRTOS 包含 Demo 例程和内核源码(比较重要,我们就需要提取该目录下的大部分 文件),具体见图 13-5。FreeRTOS 文件夹下的 Source 文件夹里面包含的是 FreeRTOS 内 核的源代码,我们移植 FreeRTOS 的时候就需要这部分源代码;FreeRTOS 文件夹下的 Demo 文件夹里面包含了 FreeRTOS 官方为各个单片机移植好的工程代码,FreeRTOS 为了 推广自己,会给各种半导体厂商的评估板写好完整的工程程序,这些程序就放在 Demo 这 个目录下,这部分 Demo 非常有参考价值。我们把 FreeRTOS 到 STM32 的时候, FreeRTOSConfig.
一、DOM 一、DOM文档对象模型 一个网页其实就是个文档,文档是由一个一个节点组成的
节点:标签、属性、文本、注释
DOM主要用来:1。获取元素 2.动态创建元素 3.对元素进行操作 4.添加事件
二、获取节点 1.通过id来获取节点 getElementById(id的名字)[0];
<body> <p id="title">我是一个p标签</p> <script type="text/javascript"> // 通过id来获取节点 var title = document.getElementById('title');//和HTML标签名重名可以,括号里面输入id的名字 console.log("title",title);//把整个p标签打印出来了,证明获取的是整个p标签,返回的是一个元素对象 title.style.color = "red";//通过js来写入元素的行内样式 </script> </body> 2.通过标签名来获取节点 getElementsByTagName(‘标签的名字’)
注意:标签名的elements中有s
<body> <ul> <li>这是ul中的li标签1</li> <li>这是ul中的li标签2</li> <li>这是ul中的li标签3</li> <li>这是ul中的li标签4</li> </ul> <script> //通过标签名获取节点 var li = document.getElementsByTagName('li'); //注意Elenments获取多个页面的标签,加上s console.log("li",li); // li[1].style.color = 'blue';//伪数组的第二个变成蓝色,如果页面只有一个li返回的还是伪数组的形式,页面如果没有元素,返回的是空的伪数组 //js变化得到的就是变化的效果 //奇数蓝色,偶数红色 for(var i = 0; i<li.length;i++){ if(i%2==0){ li[i].style.color = 'bule'; }else{ li[i].style.color = 'red'; } } </script> </body> 3.
//计算1-100之间的奇数和
public class Day1{
public static void main(String[] args){
int sum=0; //定义一个存放奇数和的变量
for(int i=1;i<=100;i++){ //for循环实现1-100的递增
if(i%2==0){ //if判断奇偶数,偶数就跳出本次循环
continue; //跳出本次循环
}
sum+=i; //sum=sum+i 奇数和相加
}
System.out.print("1-100的奇数和为:"+sum); //输出1-100的奇数和
}
}
相信大部分在学习的时候都会面临这样的问题,毕竟学习完的最终目的还是能够找到一个心仪的工作~ 不过也不用头疼~ 找工作除了你自身的技术条件要过关之外,面试简历可以说的非常重要的了~ 一份优秀的简历可以让HR对你眼前一亮~
给你提供下简历的思路和模板~
1.项目类型:
1后台管理系统
2移动端(webapp)
3微信小程序
4微信公众号
2.工作年限
3年工作经验5个项目以上
2年工作经验项目4个项目
个人能力提升
团队能力提升
高要求、清晰的目标
团队建设
3.技术栈
Vue+vuex+vue-router+webpack+ES6+node+vue-resource+mock+art-template|(12k)
React+redux+react-router+webpack+ES6
4.项目查找网站
https://www.leapcloud.cn/website/case
http://www.apicloud.com/cases
https://www.liqucn.com/
http://www.wxapp-union.com/(小程序)
http://app.weijuju.com/all_tpl.html?list=03_0_0(小程序)
http://adhub.com.cn/#!/case
http://www.pc6.com/pc/shoujikanche/10/
https://www.jfh.com/
https://www.misuland.com/
5.常用插件
https://www.toutiao.com/i6599426533952061956/(vue常用插件)
https://www.toutiao.com/c/user/3969351329/#mid=1577759178270734(reactes6学习)
https://juejin.im/entry/58e9a4cfb123db1ad05e0300(前端开发常用插件)
https://github.com/yygmind/blog(前端高频面试文档学习)
6.项目介绍
使用了什么技术、实现了什么功能、遇到过什么样的问题、怎么解决的
我做了XX项目重构,用了XX技术方案,克服了XX的困难,最终让XX这类需求变更可以短平快的被消化,极速研发、快速上线、且数据采集也做到了标准化,研发成本大大降低,数据积累增长迅速,比如XX,最后在XX产品线中开始推广。
具体: xxxx后台管理系统:
1.使用vue-cli搭建项目基本结构,对项目进行模块化划分,并集成ivew组件库、axios请求库
2.利用axios拦截器实现了权限校验,对系统的登入权限进行控制,避免了无效请求
3.利用vue-router路由钩子函数实现系统角色权限控制,使不同权限的角色可以查看不同的模快
4.使用iview进行组件化开发,实现了登录、用户列表、访问统计、个人信息修改、权限配置、角色管理等页面
5.自定义日期选择组件实现,使用自定义指令、过滤器、注册全局组件等技术实现多个组件共享日期选择器组件
xxxx移动商城
1.负责登录、注册、商品列表、购物车、订单等模块
2.使用rem对页面进行布局,以适应不同设备屏幕
3.实现了注册、登录业务逻辑,包含第三方登录,使用了cookie、localstorage等技术进行数据存储
4.负责购物车、订单页面业务逻辑,集成第三方支付
6.0.1.专业技能
-熟练掌握HTML5、CSS3等前端技术,熟悉HTML5新特性,且能熟练应用CSS实现动画效果
-熟练使用jQuery,zepto等库快速进行网站特效开发;
-熟练使用bootstrap和栅格系统进行响应式布局,熟悉常用插件(fullpage、pagenator、Validator);
-熟练使用UI框架库element-ui,iview-ui,cube-ui,vant-ui,mint-ui等
-熟悉vue、vue-router、vuex、webpack、es6等相关技术,可以使用vue-cli脚手架进行项目开发
-掌握微信小程序开发以及微信公众号开发
-了解node.js,react.js,angular.js以及MVC&MVVM设计模式与模块化开发流程。
-了解混合App开发,掌握hbuilder、cordova、ionic等打包技术----熟练两条技术栈:Vue+vuex+vue-router+webpack+ES6+node+vue-resource+mock+art-template|(12k)React+redux+react-router+webpack+ES6
-熟练掌握大型后台项目的构建:MVC、MVVM的开发模式
-熟练掌握JavaScript常见设计模式-熟悉移动端APP混合开发,设计交互模式
6.0.1.提前准备
1.哪个项目让你最满意、代表你的最高水平?如何做的?
2.让你印象最深刻的一个(技术)难点,害的你搞了很久,最后怎么解决的,有什么心得?
3.你做的时间最久的一个项目(或产品),你看到这个项目有哪些问题,你能做什么?
4.你能给我们团队或者产品带来什么?
6.0.1.问面试官
1.贵公司主营业务是什么,目前正在做什么项目
2.目前技术团队有几人(8),分工是什么样的,后台是什么语言(如果有前端开发,可以问一下目前前端使用的是什么技术栈)
如何彻底禁止win10家庭版系统自动更新-2021跟新 文章主要参考:http://www.xitongcheng.com/jiaocheng/win10_article_61393.html
————————————————————————————————————————————————
第一步:将重启bin更新|关机并更新关闭掉;将电脑的更新程序从后台关掉 首先,大家的电脑上一定已经有了“更新提醒标志”如下图1:那么第一步的目的就是把这个标志符给取消掉,编程下面这幅图2的模样:
1.1找到windows update的服务并且禁用了: 1.3 C:\Windows\SoftwareDistribution文件中的Download和DataStore内的文件删光。如下图1.3:
1.4 然后,再次更新并重启:
1.5 这一次电脑不会更新了,开机以后,等待一会,然后发现电源键已经没有了“”关机并更新“这一选项”的讨厌东西。
【图2】
1.6 然后你就放心的开始接下来的操作:把windows update的服务并且禁用
WIN+R,输入service.msc或者在任务管理器里打开服务的栏目;
第二部:同样按WIN+R,输入regedit,打开注册表,在HKEY_LOCAL_MACHINE中找到SYSTEM,在子文件夹中找到CurrentControlSet文件,打开其中的Services文件,在其中找到wuauserv文件夹 找到目录图7
找到文件图7
第三步:重中之重!具体要求如下 1.接下来,打开你之前服务中开启的图片中有一个“可执行的文件路径”;
2.在注册表中,找到数据和这个地址相同的子项。
我的是Imagepath和它同路径【如图9】,
3. 在Imagepath所在路径——c盘SYSTEM32里建个空的文件夹,随便命名,比如closeUpdate_2021-10-15.exe,然后将第2步发现的注册表中的那个名字叫做“Imagepath”项目的路径(最好先复制下来存到别的地方,以后方便改回来)改成“C:\Windows\System32\closeUpdate_2021-10-15.exe”也就是刚刚空白文件夹所在的路径; 打开注册表编辑器:计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wuauserv\ImagePath-找到
数值名称:ImagePath
数值数据:%systemroot%\system32\svchost.exe -k netsvcs -p
任务管理器-服务-所有服务----Windows Update:
C:\WINDOWS\system32\svchost.exe -k netsvcs -p
将
数值名称:ImagePath
数值数据:%systemroot%\system32\svchost.exe -k netsvcs -p
修改成为:
数值名称:ImagePath
数值数据:C:\Windows\System32\closeUpdate_2021-10-15.exe
现在,你不难发现:当你重新打开服务,你就会发现windows更新服务的路径已经改变成Imagepath所在路径了
文本预处理的核心思想是如何将文本中转化成能够训练的样本,而且通常情况下是转化成序列数据。通常有以下几个步骤:
通常英文和中文的处理会有些差别,我们分别举例讲解
处理英文文本 加载原始文本(一般我们按行来进行处理,因此一行一行的读) import collections import re from d2l import torch as d2l # 这里主要是懒得再去下载英文文章了,就直接copy的李沐老师的代码 d2l.DATA_HUB['time_machine'] = (d2l.DATA_URL + 'timemachine.txt', '090b5e7e70c295757f55df93cb0a180b9691891a') def read_time_machine(): """将时间机器数据集加载到文本行的列表中""" with open(d2l.download('time_machine'), 'r') as f: lines = f.readlines() return [re.sub('[^A-Za-z]+', ' ', line).strip().lower() for line in lines] # 这一步是暴力将所有非英文字符全部替换并转换成小写 # 可能会有一些问题,但是无伤大雅 lines = read_time_machine() print(lines[0]) print(lines[10]) the time machine by h g wells twinkled and his usually pale face was flushed and animated the 获得每一行句子的token(可以理解为词汇表) # 这里由于是英文,都是空格分割,相对好处理,中英文的处理差别就在这儿 def tokenize(lines, token='word'): "
一、#define定义常量和宏 1.#define 定义常量
#define MAX=1000;(定义常量MAX,他的值为1000)
#define STR "abcde"(定义常量STR 为字符串abcde)
2.定义宏
宏跟函数很像,但不相同
#define ADD(x,y) ((x)+(y)) (定义ADD 宏体功能是x+y,宏的参数没有类型。)
二、指针 1.一个内存大小为一个字节,每个内存单元都有一个编号,编号就称为该内存单元的地址,我们把地址也叫指针 例如 int a=1; 当a创建完后,占用四个字节,每个字节都有一个地址,&a取地址a取出的是第一个字节的地址。
int * pa=&a;//pa是创建出来存放地址的,pa为指针变量 (int说明的是pa指向的对象,也就是a为int类型,*说明pa是个指针变量,int*整体是一个整形指针变量。)
*pa;(*是解引用操作符,*pa就是通过pa中存放的地址,找到pa指向的空间)
&-取地址操作符,用来取出谁的地址。
指针变量的大小 我们可以用sizeof来计算指针变量的大小,sizeof对应的打印格式为%zu
int main() { printf("%zu\n", sizeof(char *)); printf("%zu\n", sizeof(short *)); printf("%zu\n", sizeof(int *)); printf("%zu\n", sizeof(double *)); return 0; } 当我们使用的是64位环境下,他的结果为64bit=8Byte
当我们为32位环境下,指针变量大小均为32bit=4Byte 三、结构体 我们平常使用的都为单个数据,但是实际生活中往往不是单个数据,比如一个学生,他有身高,体重,性别,学号等等等,这时候我们就需要用到C语言中的结构体来实现。
简单结构体举例:
struct Tag struct Stu //结构体类型 { { 成员列表; char name[20]; } int age; float score; } void print(struct Stu *ps) { 1.
一、解压aar 1、命令格式 unzip 【aar名称】 -d 【aar名称所在的路径】
2、举个栗子 要求:解压C:\Users\Administrator\Desktop\aar_test路径下的subPkage-release.aar
命令:
(1)、打开C:\Users\Administrator\Desktop\aar_test文件夹
cd C:\Users\Administrator\Desktop\aar_test
(2)、用命令解压subPkage-release.aar
unzip subPkage-release.aar -d C:\Users\Administrator\Desktop\aar_test
注意:执行解压命令出现错误:'unzip' 不是内部或外部命令,也不是可运行的程序或批处理文件,解决方法请看本文章尾部 “三、遇到的问题”
查看结果:成功后的样子如下
(1)、命令窗口
(2)、aar解压后的文件
二、解压成功后,按照自己的要求修改文件 三、文件压缩成aar 1、命令格式(注意:路径后有个点,中间有空格) jar cvf 【压缩后aar名称】 -C 【压缩后aar名称的路径】 . 2、举个例子 要求:把C:\Users\Administrator\Desktop\aar_test路径下的所有文件压缩成aar
命令:
(1)、打开C:\Users\Administrator\Desktop\aar_test文件夹
cd C:\Users\Administrator\Desktop\aar_test
(2)、用命令把文件压缩成aar
jar cvf newaar.aar -C C:\Users\Administrator\Desktop\aar_test . 查看结果:成功后的样子如下
(1)、命令窗口
(2)、压缩成aar后的文件
最终newaar.aar就是项目所需要的aar包
三、遇到的问题 1、执行解压命令出现如下错误: 'unzip' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
2. 错误分析 unzip是linux系统下,windows不自带。
3、解决方法: (1)、unzip官网
UnZip for WindowsUnZip: list, test and extract compressed files in a ZIP archivehttp://gnuwin32.
服务器上行带宽和下行带宽是上传还是下载?服务器公网带宽分为两个方向,即上行带宽和下行带宽,从服务器的角度上行带宽和下行带宽
代表用户上传还是下载呢,让我们一起了解一下!
服务器带宽上行下行详解:
服务器上行带宽是指流量从服务器流出(出网带宽),下行带宽指流量流入服务器(入网带宽)。即服务器上行带宽对应的是用户从服务器下载文件到本地;
服务器下行带宽代表用户从本地上传数据到服务器。如下表所示:
如何分辨服务器上行流量和下行流程?
服务器下载资源消耗的是服务器的下行流量(流入),服务器上传资源消耗的是服务器的上行流量(流出);
客户端下载资源消耗的是服务器的上行流量(流出),客户端上传资源消耗的是服务器的下行流量(流入)。
1、上行即上传带宽,下行即下载带宽,我们知道家用宽带的下行带宽通常很足,而上行带宽则很小,那么机房的宽带是否有这样的限制?
通常买的云服务器,一般买的带宽指的是上行带宽,比如你买的3M带宽,也就是你买的上行带宽是3M。
下行通常是不限的。而且流量的计算一般都是以上行的来计算的。
所以,客户端上传资源,对服务器带宽基本没有影响,因为服务器下行基本不限的,跟客户端本身网络的带宽有影响;
而客户端下载资源,除了跟服务器的带宽有影响,跟客户端本身的网络带宽也有影响的。
2、服务器的上行带宽主要用于本地用户请求服务器上的资源(即本地的下载、服务器的上传),服务器的下行带宽主要用于本地用户上传文件至服务器。
在整个服务器用途调查中,发现服务器的上行带宽起到决定性作用,所以在服务器的销售中,标注的带宽肯定是要确保上行带宽达标的。
从服务器角度,上行带宽是指出流量、下行带宽是指入流量。以阿里云服务器为例,用户购买的公网带宽指的是上行带宽,流量从云服务器流到用户客户端的流量,下行带宽是免费的,用户上传文件到服务器是免费的。
一、Go编程语言概述 Go语言也叫Golang,是由谷歌(Google)公司在2007年推出的一款静态编译型语言。主要将其用于服务端开发、并发编程和网络编 程等。 1.1 Go语言特性及应用场景 1.容易上手 2.编程速度快 3.原生支持并发 Go语言最主要的特性就是从语言层面原生支持并发,无须任何第三方库。Go的并发基于 goroutine,可以理解为一种微线程。与Python的多线程性能限制于GIL全局锁不同,Go语言的并发 可以充分利用CPU的资源,将goroutine合理地分配到每个CPU中,最大限度地使用CPU的性能。 goroutine之间的通信可以使用Go语言的sync包和channel机制来实现。 4.垃圾回收 5.代码风格清晰 1.2使用Go语言的项目 1.docker 网址:https://github.com/docker/docker-ce Docker是一个开源的应用容器引擎,基于Go语言开发并遵从Apache 2.0协议开源。Docker可以 让开发者打包他们的应用和依赖包到一个轻量级、可移植的容器中,也可以实现虚拟化,更重要 的是容器性能开销极低。 2.Kubernetes 网址:https://github.com/kubernetes/kubernetes Kubernetes是自动化容器操作的开源平台,使用Kubernetes可以进行自动化容器的部署和复 制、随时扩展或收缩容器规模和容器间的负载均衡等。 3.Beego项目 网址:https://github.com/astaxie/beego Beego是一个使用Go编写的极轻量级、高可伸缩性和高性能的Web应用框架。 4.Golang项目 网址:https://github.com/golang/go Go语言自1.5版本后,可以完全使用Go语言自身来实现。对Go语言的源码研究有助于深入理解 Go的底层实现,想对Go语言有持续深入了解的读者可阅读此项目。 5.Codis项目 网址:https://github.com/CodisLabs/codis Codis是一个国产开源的分布式redis解决方案,对于上层的应用透明,就像连接到原生的redis 服务器那样。 1.3常用软件和网站 1.开发工具(IDE或编辑器) Go开发工具有许多,其中IDE(Integrated Development Environment,集成开发环境)功能比 较强大,会提供代码提示、文件和目录管理、代码搜索和替换、查找函数等功能。一 般会通过IDE进行代码开发。 Visual Studio Code,是一个由微软开发的,同时支持Windows、Linux和Mac OS操作系统并且开 放源代码的文本编辑器。它支持调试,并内置了Git版本控制功能,同时也具有开发环境功能,例 如代码补全、代码片段、代码重构等。该编辑器支持用户自定义配置,例如改变主题颜色、键盘 快捷方式、编辑器属性和其他参数,还支持扩展程序并在编辑器中内置了扩展程序管理的功能。 GoLand是JetBrains推出的一款新型商用IDE,旨在为Go开发提供符合人体工程学的环境。新的 IDE扩展了IntelliJ平台,提供Go语言特有的编码辅助和工具集成,强大的静态代码分析和人体工程 学设计使开发更高效。 2.代码管理工具 开发人员通过代码管理工具进行权限控制,能防止代码混 乱,提高安全性,防止一些不必要的损失和麻烦。
SVN(Subversion)是一个开源的集中式版本控制系统,管理随时间改变的数据,所有数据集 中存放在中央仓库(repository)。repository就好比一个普通的文件服务器,不过它会记住每一次文 件的变动,这样你就可以把Java文件恢复成旧的版本,或是浏览Java文件的变动历史。 GIT,是一个开源的分布式版本控制系统,和SVN功能类似,但GIT的每台电脑都相当于一个 服务器,代码是最新的,比较灵活,可以有效、高速地处理项目版本管理。全球最大的代码托管 平台GitHub网站,采用的也是GIT技术 3.其他工具 Jira,是Atlassian公司出品的项目与事务跟踪工具,可以进行网站bug管理、缺陷跟踪、任务跟 踪和敏捷管理等.
Redmine,是由Ruby编程语言开发的一套跨平台项目管理系统,通过“项目(Project)”的形 式把成员、任务(问题)、文档、讨论以及各种形式的资源组织在一起,让大家参与更新任务、 文档等内容来推动项目的进度,同时利用时间线索和各种动态的报表形式来自动给成员汇报项目 进度,并提供Wiki、新闻台等,还可以集成其他版本管理系统和bug跟踪系统.
前言 跨域是因为浏览器存在对不同源页面数据接收的限制。这种限制就是浏览器的同源策略。
同源策略是浏览器的安全机制,跨域的原理就是通过各种方式避开浏览器的安全机制
使用 在项目开发时,对跨域的概念仅限于了解,所以没有注重过程,只注重结果。所以在开发项目时,使用的是市面上比较常用,并且能够一劳永逸的cors。虽然cors方法能够完美解决跨域问题,但是还是要秉持着对知识探索的态度,去深入理解跨域问题。
报错提示 这里我使用8080端口的客户端访问3000端口的服务器,结果报错。
原因是因为端口号不同产生跨域。
如果将服务器端口号改为8080就不会报错了。
跨域方法 跨域的方法有cors、Proxy正向代理、Nginx反向代理、Jsonp
现阶段跨域方式有很多种,但是基本思想只有两种:
绕过同源策略
Jsonp:历史遗留的产物,虽然思想很好,但是局限性太大(仅支持get、因为数据是在url中,所以携带数据小)。
原理: 有三个标签不受同源策略影响: <script src="xxx"></script> <link herf="xxx"></link> <img src="xxx"></img> 实现: // 1.创建script var script = document.createElement('script') // 2.定义回调函数 function getData(data) { // 调用函数返回的数据 console.log(data); } // 3.设置src属性 script.src = 'http://localhost:3000?callback=getData' // 4.让cript生效 document.appendChild(script) Nginx:通过反向代理绕过去,这是很完美的解决方案,加上会给服务器增加一点压力,不过这点压力问题并不大
如何理解反向代理:代理服务器代替目标服务器去接收并响应给客户端发起的请求。隐藏服务器。
发起请求:客户端向代理服务器发出请求,代理服务器再将请求转发给目标服务器
响应数据:目标服务器向代理服务器响应数据,代理服务器再向数据响应给客户端
很常用的方法,像网易、头条都使用nginx代理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ddoEgRFd-1656482203293)(https://juejin.cn/)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4M4avsX0-1656482203293)(https://juejin.cn/)]
这是我在chrome上看的某些文件。
nginx使用:
下载nginx
直接到官网下载
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gaMNC5wi-1656482203294)(https://juejin.cn/)]
修改默认配置
打开conf/nginx.conf
配置代理端口
- 配置监听端口
> 输入 start nginx.exe 没有反应表示启动成功 Proxy:通过正向代理绕过去,让服务器帮我们向服务器发送请求,因为跨域均存在于浏览器与服务器之间。只能在本地开发环境使用。
Microsoft Windows Driver Kit (WDK) 包含几个单独的组件。如果您了解 WDK 的结构,您就将知道各种支持文件和信息的查找位置。
默认情况下,WDK 组件将安装到计算机硬盘驱动器上的 WDKInstallationPath\BuildNumber\ 文件夹中,其中 WDKInstallationPath 为 WDK 安装到的计算机上的根目录位置(例如,C:\WinDDK),而 BuildNumber 为安装的 WDK 的内部版本号(例如 5600)。
这些组件将在安装 WDK 的过程中复制到计算机上,具体取决于您在 WDK 安装向导中选择的选项。最常见的 WDK 组件将安装到主 WDK 安装文件夹下的以下子目录(如 C:\WinDDK\5600)中:
\ (the WDK root directory)
WDK 根目录(如 C:\WinDDK\5600\)包含 WDK 发行说明 (Relnotes.htm)。这些发行说明包含有关 WDK 的最新信息,并经常包含有关对头文件和生成环境的更改的有用信息。虽然可以考虑忽略发行说明,但强烈建议您阅读 WDK 发行说明(通常您值得花时间这样做)。
\bin\
\bin 目录包含支持 WDK 生成环境的可执行映像和命令过程。该目录中的文件包括编译器、链接器和其他支持文件。通常无需直接访问或修改该目录中的文件。
\debug\
\debug 目录包含操作系统映像和硬件抽象层 (HAL) 的调试版本及其关联的符号文件。这些文件可在您调试驱动程序时为您提供帮助。
有关调试版本和符号文件的内容及其使用方式的更多信息,请参见 Windows 的调试版内部版本。
\help\
\help 目录包含 Microsoft HTML Help 2.0 格式的 WDK 文档文件。可通过以下操作查看帮助文件:单击“开始”按钮,再依次指向“所有程序”、“Windows Driver Kits”(Windows 驱动程序包)、“WDK 内部版本号”和“Help”(帮助),然后单击“WDK Documentation”(WDK 文档)。
自我介绍:大家好,我是吉帅振的网络日志;微信公众号:吉帅振的网络日志;前端开发工程师,工作4年,去过上海、北京,经历创业公司,进过大厂,现在郑州敲代码。
JS继承专栏 1【JS继承】什么是JS继承?
2【JS继承】常见的7种继承方式
3【JS继承】JS继承之原型链继承
4【JS继承】JS继承之构造函数继承
5【JS继承】JS继承之组合继承
6【JS继承】JS继承之原型式继承
7【JS继承】JS继承之寄生式继承
8【JS继承】JS继承之寄生组合式继承
9【JS继承】JS继承之ES6 Class继承
JS是一种基于对象的语言,要实现面向对象,写法跟传统的面向对象有很大的差异。ES6引入了Class语法糖,使得JS的继承更像面向对象语言的写法。
此篇博客,分为:基本介绍、Vue使用案例
基本介绍 Class可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多;
1
2
3
4
class Father {
}
class Son extends Father {
}
代码定义了一个Son 类,该类通过extends关键字,继承了Father类的所有属性和方法,但是由于没有部署任何代码,所以这两个类完全一样,等于复制了一个Father类。
1
2
3
4
5
6
7
8
9
10
class Son extends Father {
constructor (name,age,city) {
super(name,age);//调用父类的constructor(name,age);
this.city = city;
}
toString () { return this.city+ " " +super.toString();//调用父类的toString()
}
}
constructor方法和toString方法之中,都出现了super关键字,他在这里表示父类的构造函数,用来新建父类的this对象;
子类必须在constructor方法中调用super方法,否则新建实例时会报错,这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工,如果不调用super方法,子类就得不到this对象;
1
2
MYSQL数据库中 addtime() 为日期加上指定秒数
select addtime(now(),1); -- 加1秒
adddate() 有两种用法,第二个参数直接填数字的话是为日期加上指定天数,填interval的话是为日期加上指定的interval时间。
select adddate(now(),1); -- 加1天
select adddate(now(), interval 1 day); -- 加1天
select adddate(now(), interval 1 hour); --加1小时
select adddate(now(), interval 1 minute); -- 加1分钟
select adddate(now(), interval 1 second); -- 加1秒
select adddate(now(), interval 1 microsecond); -- 加1毫秒
select adddate(now(), interval 1 week); -- 加1周
select adddate(now(), interval 1 month); -- 加1月
select adddate(now(), interval 1 quarter); -- 加1季
select adddate(now(), interval 1 year); -- 加1年
1.ufw安装 Ubuntu22.04默认安装了ufw,若没有安装,则使用以下命令安装:
sudo apt-get install ufw 2.查看ufw的状态 一般ufw是不会开启的,激活ufw用sudo ufw enable来激活。需要注意的是,在激活的时候,默认是不允许ssh端口连接的,ufw会保持当前的连接,这时候执行sudo ufw allow ssh 来开启ssh的端口。如果不执行,重启后下次ssh连接就不能正常连接,因为ufw默认允许内部流量出去,但不允许外部流量进来。
你可以通过下面的命令来检查ufw的状态。
sudo ufw status verbose 一般ufw命令只能在具有sudo权限的用户以及root用户下执行。执行完上面的命令后,如果开启了ufw则会输出下面这段文字和防火墙的规则。
Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip 如果没有激活ufw,则输出应该为Status: inactive 。
查看ufw的规则还有另一条命令
sudo ufw status 这条指令相比于上面的sudo ufw status verbose。这条指令则没有上面那条输出的信息多,上面那条指令会输出更为详细的端口规则。
还有一条查看的命令会给规则前面加上序列号,通过序列号可以删除规则。
sudo ufw status numbered 3.端口规则设置 ufw激活后的默认的策略是允许出去,不允许流量进来,这个可以在ufw的配置文件中看到。在配置文件/etc/default/ufw中可以看到DEFAULT_OUTPUT_POLICY=“ACCEPT”,如果需要端口可以出去,则需要自己配置。
可以通过ufw的命令来直接修改端口规则。
命令格式为: ufw allow port_number/protocol
ufw配置了一些特定的端口的规则,我们可以直接用。
sudo ufw allow http #允许http连接 sudo ufw denty http #阻止http连接 这些特定的端口定义在文件/etc/services 中。
前言
键盘事件
键盘事件定义的属性:
一、键盘按键事件案例
二、div方向移动案例
三、拓展知识:
前言 在JavaScript中,当用户操作键盘时,会触发键盘事件,通过键盘触发事件,类似用户的行为:
keydown: 在键盘上按下某个键时触发。如果按住某个键,会不断触发该事件,但是Opera浏览器不支持这种连续操作。该事件处理函数返回false时,会取消默认的动作(如输入的键盘字符,在IE和Safari浏览器下还会禁止keypress事件响应).keypress: 按下某个键盘键并释放时触发。如果按住某个键,会不断触发该事件。该事件处理函数返回false时,会取消默认的动作(如输入的键盘字符).keyup: 释放某个键盘键时触发。该事件仅在松开键盘时触发一次,不是一个连续的响应状态。 当获取用户正按下建码时,可以使用keydown、keypress和keyup事件获取这些信息。其中keydown和keypress事件基本上是同义事件,它们的表现也完全一致,不过一些浏览器不允许使用keypress事件获取按键信息。所有元素都支持键盘事件,但键盘事件多被应用在表单输入中。
键盘事件 属性描述onkeydown当按下按键时运行脚本。onkeyup当松开按键时运行脚本。onkeypress当按下并松开按键时运行脚本。 键盘事件定义的属性: 属性说明keyCode该属性包含键盘中对应键位的键值charCode该属性包含键盘中对应键位的Unicode编码,仅DOM支持target发生事件的节点(包含元素),仅DOM支持srcElement发生事件的元素,仅IE支持shiftKey是否按下Shift键,如果按下返回true,否则为falsectrlKey是否按下Ctrl键,如果按下返回true,否则为falsealtKey是否按下Alt键,如果按下返回true,否则为falsemetaKey是否按下Meta键,如果按下返回true,否则为false,仅DOM支持 一、键盘按键事件案例 当键盘按下判断当前的按键是不是 a ,如果是就输出true,否则输出false
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>案例一</title> </head> <body> <script> /* 当键盘按下判断当前的按键是不是 a ,如果是就输出true,否则输出false */ window.onkeydown = function (event) { /* 解决兼容性问题 */ event = event || window.event; if (event.keyCode == 65) { console.log("true"); } else { console.log("false"); } }; </script> </body> </html> 二、div方向移动案例 使div可以根据不同的方向键向不同的方向移动
键位和码值对照表
键位码值键位码值0~9(数字键)48~57A~Z(字母键)65~90Backspace(退格键)8Tab(制表键)9Enter(回车键)13Space(空格键)32Left arrow(左箭头键)37Top arrow(上箭头键)38Rigth arrow(右箭头键)39Down arrow(下箭头键) 40 <!
yum install samba # 安装 Samba
步骤一 创建被共享的目录 smb_folder、创建Samba用户 widuan,并且设置 Samba的配置文件如下:
[global] workgroup = SAMBA security = user encrypt passwords = yes passdb backed = tdbsam [smb_folder] comment = Share Directories browseable = Yes writable = yes path = /home/widuan/smb_folder create mask = 0775 directory mask = 0775 admin users = widuan valid users = widuan su - widuan # 切换到 widuan
mkdir /home/widuan/smb_folder
exit # 退出 widuan
pdbedit -a widuan # pdbedit -a username 新建Samba账户
正文: 内容都在上方封面图,高清演示图放到压缩吧了,有兴趣的自己去看,程序是基于彩虹ds的模板,彩虹商城是什么,我就不用多说了吧,大家应该都知道,安装教程里面都有。
程序: wwutj.lanzouq.com/iouNP072hfvi
图片:
1、sysctl.conf的配置路径
/etc/sysctl.conf,此文件内容对应/proc/sys/这个目录的子目录及文件 2、作用:
作用:主要是配置一些系统信息 3、内容–centos7
[root@szb etc]# grep -v "^#" sysctl.conf | grep -v "^$" net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 net.ipv4.conf.all.promote_secondaries = 1 net.ipv4.conf.default.promote_secondaries = 1 net.ipv6.neigh.default.gc_thresh3 = 4096 net.ipv4.neigh.default.gc_thresh3 = 4096 kernel.softlockup_panic = 1 kernel.sysrq = 1 net.ipv6.conf.all.disable_ipv6=0 net.ipv6.conf.default.disable_ipv6=0 net.ipv6.conf.lo.disable_ipv6=0 kernel.numa_balancing = 0 kernel.shmmax = 68719476736 kernel.printk = 5 注意: 1. 上述参数中每个.分割的就是一个目录,例如kernel.msgmnb就等价于/proc/sys/kernel/msgmnb文件 2.
pod search AFNetworking
[!] Unable to find a pod with name, author, summary, or description matching `AFNetworking`
pod repo 返回也是 0 repo
解决方法 使用国内清华cocoapod源手动下载:
git clone https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git ~/.cocoapods/repos/trunk
下载完成后 再使用pod repo 就会返回 1 repo
再使用pod search 不会再报错了
问题 unity打包成webgl的时候,会自动在window上挂载unityInstance。可以在js代码中调用unityInstance.SendMessage向unity发送消息。
但是使用微信小程序官方打包插件(minigame-unity-webgl-transform),将unity项目打包成小游戏之后,在js脚本的window上找不到unityInstance。在微信开发者工具的控制台的window上也找不到。(unity版本2019.4.33f1,微信开发者工具版本1.05.2204250,插件版本minigame.202206201602)
解决办法(手动挂载) 手动在window上挂载unityInstance ,在游戏加载好之后运行这几行代码,游戏未加载好的时候是没有unityNamespace的:
if (typeof window !== 'undefined' && typeof window.unityInstance === 'undefined') { if (window.unityNamespace && window.unityNamespace.Module) { // console.log("[set]: window.unityInstance = window.unityNamespace.Module"); window.unityInstance = window.unityNamespace.Module; } else { console.error('缺少unityInstance'); } } 以上代码可以插入到以下两个地方之一,(二选一即可):
①插入到小游戏gameManager.onModulePrepared的回调方法里 在微信开发者工具,项目目录里找到“game.js”,然后找到“gameManager.onModulePrepared”,在它回调方法的开头加入这段代码。
②用户初次点击游戏界面或unity组件加载完成的时候,进行挂载。 这个就需要开发者自己判断挂载时机了,而且需要在unity端调用js函数。
首先下载lodash插件:里面封装函数的防抖与节流的业务【闭包+延时器】
- 终端执行
npm i --save lodash 成功后可以在node_modules文件夹中找到lodash.js
如果你想在html中使用lodash,可以将lodash.js文件复制到指定路径下,就可以方便通过script标签引入了
<script src="./lodash.js"></script> 防抖:前面所有的触发都被取消,最后一次执行在规定的时间之后才会触发,也就是说如果连续快速的触发只会执行一次。
比如防抖可以作用于用户在输入框中输入内容时,是边输入边发请求还是结束后才发请求。或者用户鼠标移到某个按钮上就发请求的情况,容易造成卡顿。如果设置为结束后再发请求则实现防抖。
以下实现防抖的例子:文本输入一秒后才执行
let input=document.querySelector("input") //绑定事件 文本发生变化立即执行 input.oninput=_.debounce(function(){ console.log("ajax发请求"); },1000) 节流:在规定间隔时间范围内不会重复触发回调,只有大于这个时间间隔才会触发回调,只有大于这个时间间隔才会触发回调,把频繁触发变为少量触发。可以参考短信验证码,我们总是遇到要一分钟后才可以再次点击,这就避免了用户不断发请求的情况。
以下实现节流的例子:计数器,一秒内只能加一
button.onclick=_.throttle(function(){ //节流:目前的回调函数是五秒执行一次 //假如这里有很多业务代码,就可以给浏览器充裕的时间去解析 //比如短信验证码 count++ span.innerHTML=count console.log("执行啦"); },5000) 总结一下区别:
防抖:用户操作很频繁,但是只执行一次
节流:用户操作很频繁,但是会把频繁操作转换为少量操作,可以给浏览器充裕的时间解析代码
import java.util.Random; //导包
public class Lei{
public static void main(String[] args){ //主函数,程序的入口
Random rd=new Random(); //创建实例
int num=rd.nextInt(100)+1; //使用功能 nextInt(范围); 产生随机整数,范围从0开始
System.out.println("随机数为"+num); //输出随机数
一 、启动流程一览 加载BIOS的硬件信息与进行自我检测(自检),并根据设置取得第一个可启动的设备;读取并执行第一个启动设备内MBR的启动引导程序(gurb2、spfdisk等程序);根据启动引导程序的设置加载Kernel (内核),Kernel会开启检测硬件与加载驱动程序 ——完成后,主机硬件已经准备就绪;在硬件驱动成功后,Kernel会主动调用systemd程序 ——准备软件执行环境,并以default.target流程启动: systemd 执行 sysinit.target 初始化系统及 basic.target 准备操作系统;
systemd 启动 mulit-user.target 下的本机与服务器服务;
systemd 执行 mulit-user.target 下的 /ect/rc.d/rc.local 文件;
systemd 执行 mulit-user.target 下的 getty.target 及登录服务;
systemd 执行 graphical 需要的服务;
BIOS (Basic Input Output System) ,启动自我测试与MBR
MBR (Master Boot Record ,主引导记录),代表该磁盘的最前面可安装 boot loader 的那个区块
boot loader , 启动引导程序
BIOS 会指定启动的设备好让我们可以读取磁盘中的操作系统内核文件时,我们必须要以一个启动引导程序(boot
loader)来处理内核文件加载(load)的问题;boot loader 程序安装在,启动设备的第一个扇区(sector)中,也就是 MBR;boot loader 加载 kernel 与 initramfs (init ram
filesystem,它是一个cpio格式的内存文件系统打包),在内存中让 initramfs 解压缩成为
根目录,内核就能借此加载适当驱动程序,最终释放虚拟文件系统,并挂载实际的根目录文件系统,从而开始后续正常启动流程。 fdisk -l 命令 查看启动设备
Linux下安装MySQL8.0.18 一 下载MySQL1 官网下载地址2 安装mysql3 添加用户,授权4 项目运行时遇到问题 一 下载MySQL 1 官网下载地址 https://downloads.mysql.com/archives/community/
1.1 如何选择MySQL版本?
1.1.1 先查询Linux版本
参考文献
# hostnamectl
[root@VM_0_9_centos ~]# hostnamectl Static hostname: VM_0_9_centos Icon name: computer-vm Chassis: vm Machine ID: -------------------------------- Boot ID: -------------------------------- Virtualization: kvm Operating System: CentOS Linux 7 (Core) CPE OS Name: cpe:/o:centos:centos:7 Kernel: Linux 3.10.0-862.el7.x86_64 Architecture: x86-64 # cat /proc/version
[root@VM_0_9_centos ~]# cat /proc/version Linux version 3.10.0-862.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.
前言 echarts的横向柱状图也是比较常见的,但是类目文字基本上都是在左侧,比如:
但是你永远可以相信你的项目经理或产品经理会给你找麻烦,比如给客户看的ui图,文字是上面的:
遇到一些好说话的客户还好可以协商,但是有些客户。。。 最后苦逼的就是我们开发的。
正文 能实现该效果吗?虽然一直没有见过类似的,但是还真能实现。
代码
option = { xAxis: { type: 'value' }, yAxis: { type: 'category', axisLabel: { show: false }, data: ['abc', 'abcdefgh'] }, series: [ { name: 'Cost', type: 'bar', label: { show: true, formatter: '{b}', position: 'left', align: 'left', offset: [10, -20] }, barWidth: 20, data: [10, 20] } ] }; 效果图
注意点:
1、在yAxis里必须添加 axisLabel: { show: false }, ,不然会出现两个类目,比如:
2、series 里 label 的属性配置(关键)
H.264码流分析 1.SPS,PPS分析(1)sequence parameter set 序列参数集(2)picture parameter set 图像参数集 2.GOP分析(1)I帧(帧内编码帧)(2)P帧(前向预测编码帧)(3)B帧(双向预测编码帧)(4)图像帧比特分析 码流分析工具:H264visa,Elecard StreamEye Tools 1.SPS,PPS分析 使用码流分析仪打开一个MP4文件:
打开View-info可以看到SPS和PPS的内容
(1)sequence parameter set 序列参数集 SPS中保存了一组视频编码序列的全局参数,一般情况下位于整个码流的起始位置。在做视频播放器时,为了让后续的解码过程可以使用SPS中包含的参数,必须对其中的数据进行解析。
各个参数的含义
参数解释profile_idc: Main表示当前H.264码流的profile。H.264中定义了三种常用的profile:baseline_profile,main_profile,extended_profilelevel_idc: 41标识当前码流的level。编码的level定义了某种条件下的最大视频分辨率,最大视频帧率等参数,码流所遵从的level由level_idc指定seq_parameter_set_id : 0标识当前的序列参数集的id。通过该id值,图像参数集PPS可以引用其代表的SPS中的参数log2_max_frame_num_minus4: 4(8)MaxFrameNum 是frame_num的上限值,frame_num是图像序号的一种表示方法,在帧间编码中常用作一种参考帧标记的手段 。MaxFrameNum=2(log2_max_frame_num_minus4+4)。所以该视频MaxFrameNum=28=256pic_order_cnt_type: 0表示解码picture_order_count(POC)的方法。POC是另一种计量图像序号的方式,与frame_num有着不同的计算方法pic_width_in_mbs_minus1: 119用于计算图像的宽度,单位为宏块个数,因此图像的实际宽度为:(60+1)×16=976pic_height_in_mbs_minus1: 60使用PicHeightInMapUnits来度量视频中一帧图像的高度。PicHeightInMapUnits并非图像明确的以像素或以宏块为单位的高度,而需要考虑该宏块是帧编码或场编码。因此 图像的实际高度为(119+1)×16=1920frame_mbs_only_flag:1标识位,说明宏块的编码方式。等于0时表示本序列中所有图像的编码模式都是帧,等于1时表示本序列中的编码模式可能是帧或场或帧场自适应direct_8x8_inference_flag标识运动向量的预测方法,frame_mbs_only_flag为0时此处则应为1。frame_cropping_flag标识是否需要对输出图像进行裁剪,要裁剪(=1)时需要再声明裁剪的边缘位置frame_cropping_rect_left_offset,frame_cropping_rect_right_offset,frame_cropping_rect_top_offset,frame_cropping_rect_bottom_offsetvui_parameters标识码流中是否有vui子结构。同时,其中 time_scale 与num_unis_in_tick 可以对视频的帧率进行计算。公式为frame = time_scale / num_unis_in_tick 由frame = time_scale / num_unis_in_tick计算方法,得到本视频的帧率为60/1=60,但在File信息中给出的帧率为30,不一致。
(2)picture parameter set 图像参数集 通常情况下,PPS类似于SPS,在H.264的裸码流中单独保存与一个NAL Unit中,只是PPS NAL Unit的nal_unit_type值为8;而在封装格式中,PPS通常与SPS一起,保存在视频文件的文件头中。
各个参数的含义
参数解释pic_parameter_set_id: 0表示当前PPS的id,某个PPS在码流中会被相应的slice引用,slice引用PPS的方式就是在slice header中保存PPS的id值。该值的取值范围为[0,255]seq_parameter_set_id: 0表示当前PPS所引用的激活的SPS的id。通过这种方式,PPS中也可以取到对应SPS中的参数。该值的取值范围为[0,31]entropy_coding_mode_falg: 1(CABAC)熵编码模式标识,该标识位表示码流中熵编码/解码地算法,当该值为0时,选择左边的算法,通常为哥伦布码或者是CAVLC;当该值为1时,选择右边的算法,通常为CABACnum_slice_groups_minus1表示某一帧中slice group的个数。当该值为0时,一帧中所有的slice都属于一个slice groupnum_ref_idx_l0_default_active_minus1表示当Slice Header中的num_ref_idx_active_override_flag标识位为0时,P/SP/B slice的语法元素num_ref_idx_l0_active_minus1和num_ref_idx_l1_active_minus1的默认值weighted_pred_flag: 1标识位,表示在P/SP slice中是否开启加权预测weighted_bipred_idc: 0表示在B slice中加权预测地方法,取值范围为[0,2]。0表示默认加权预测,1表示显式加权预测,2表示隐式加权预测pic_init_qp_minus26和pic_init_qs_minus26表示初始的量化参数。实际的量化参数由该参数、slice header中的slice_qp_delta/slice_qs_delta计算得到chroma_qp_index_offset用于计算色度分量的量化参数,取值范围为[-12,12]deblocking_filter_control_present_flag标识位,用于表示Slice header中是否存在用于去块滤波器控制的信息。当该标志位为1时,slice header中包含去块滤波相应的信息;当该标识位为0时,slice header中没有相应的信息constrained_intra_pred_flag若该标识为1,表示I宏块在进行帧内预测时只能使用来自I和SI类型宏块的信息;若该标识位0,表示I宏块可以使用来自Inter类型宏块的信息redundant_pic_cnt_present_flag标识位,用于表示Slice header中是否存在redundant_pic_cnt语法元素。当该标志位为1时,slice header中包含redundant_pic_cnt;当该标识位为0时,slice header中没有相应的信息 2.
随着人工智能,大数据的时代来临,以前嵌入式处理器中的CPU和GPU渐渐的难以满足与日俱增的需求,尤其是深度学习方面。为了应对日渐增长的需求,NPU就诞生的了。
NPU英语全称为Neural Process Unit,译为神经网络处理器。
为了满足人工智能的需要,瑞芯微的处理器也逐渐集成了NPU,称之为RKNPU。
RKNPU经过了几代的发展,首代初次引入了RKNPU是从RK3399pro和RK1808开始的,相比传统的CPU和GPU,在深度学习运算能力上有比较大幅度的提升。接下来在RV1109和RV1126上使用了第二代NPU,提升了NPU的利用率。第三代NPU应用在RK3566和RK3568上,搭载全新NPU自研架构。
瑞芯微RK3568芯片内置NPU,是RKNPU第三代的代表产品。第三代RKNPU特点如下所示:
☛ 搭载全新自研架构
☛ 支持整数8、整数16卷积运算
☛ 内置的NPU支持INT8/INT16混合操作
☛ 推理工具支持:TensorFlow, Caffe, Tflite, Pytorch, Onnx NN, Android NN等等
☛ 高达1 TOPS的神经网络加速处理性能
基于iTOP-RK3568开发板实现的全新NPU自研架构,可通过算法加持应用到以下场景:
目前,iTOP-RK3568开发板正在热卖中,基于RK3568开发板的《iTOP-3568开发板NPU使用手册》也同步上新。
手册目录展示
第1章 你好!NPU
1.1 NPU的诞生!
1.2 初识RKNPU
第2章 准备RKNPU开发环境
2.1 开发环境
2.1 软件架构
2.2 SDK说明
第3章 让NPU跑起来
3.1 在Linux系统中使用NPU
3.1.1 设置交叉编译器
3.1.2 修改编译工具路径
3.1.3 更新RKNN模型
3.1.4 编译demo
3.1.5 开发板运行demo
3.2 在Android系统中使用NPU
3.2.1下载编译所需工具
3.2.2 修改编译工具路径
3.2.3 更新RKNN模型
3.2.4 编译demo
3.2.5 开发板运行demo
第4章 体验RKNN_DEMO
记录一下最近做的一个cookie共享的需求.,有两种情况:
第一种:相同的顶级域名的情况下,只需要将cookie写在顶级域名下,该域名下的所有子域名都能访问到了。如 PHP:
//xxx.com 前面不能加. (生成的cookie的domain是 .xxx.com) setcookie('test','value',time()+60*60*24*30,'/','xxxx.com'); //xxx.com 的所有子域名就 都能获取到了 $_COOKIE['test']; JS的设置和php类似:
//存储cookie,这里的域名必须是顶级域名 setCookie('test','value','xxx.com','20') function setCookie(cName, value,domain,expireDate) { const exDate = new Date(); exDate.setDate(exDate .getDate() + expireDate); document.cookie = cName + "=" + decodeURIComponent(value) + (expireDate== null ? "" : ";expires=" + exDate.toUTCString()) + ";path=/;domain="+domain; } //获取cookie getCookie('test') function getCookie(key) { return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(key).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null; } 第二种:两个顶级域名不同的站点,需要在设置cookie的时候设置httpOnly、secure、sameSite;比如A设置了cookie,B可以通过jsonp的方式就能取到了。sameSite必须设置为None,默认是空。如PHP:
php>=7.3版本可以直接设置
setcookie('test','value',[ 'expires'=>time()+60*60*24*30, 'path'=>'/', 'domain'=>'xxx.
文章目录 1、Logback1.1、Logback简介1.2、Logback中的组件1.3、基础日志输出格式1.4、入门使用1.5、异步日志 2、Log4j22.1、Log4j2简介2.2、Log4j2特征2.3、入门使用2.4、slf4j搭配log4j2使用 1、Logback 1.1、Logback简介 Logback是由log4j创始人设计的又一个开源日志组件Logback当前分成三个模块:logback-core,logback- classic和logback-accesslogback-core是其它两个模块的基础模块,类似与springframeworklogback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API。使你可以很方便地更换成其它日志系统如log4j或JDK14 Logginglogback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能 1.2、Logback中的组件 Logger:日志的记录器,主要用于存放日志对象,也可以定义日志类型、级别Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等Layout:负责把事件转换成字符串,格式化的日志信息的输出。在Logback中Layout对象被封装在encoder中。也就是说我们未来使用的encoder其实就是Layout 1.3、基础日志输出格式 %-10level 级别:案例为设置10个字符,左对齐%d{yyyy-MM-dd HH:mm:ss.SSS}:日期%c: 当前类全限定名%M: 当前执行日志的方法%L: 行号%thread: 线程名称%m或者%msg: 信息%n: 换行 1.4、入门使用 基础使用
依赖
<!--slf4j 核心依赖--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- logback依赖 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> 导包
import org.slf4j.Logger; import org.slf4j.LoggerFactory; 日志级别:trace < debug < info < warn < error默认的日志级别是debug @Test public void test01(){ Logger logger = LoggerFactory.getLogger(LOGBACKTest.class); logger.error("error信息"); logger.warn("warn信息"); logger.info("info信息"); logger.debug("debug信息"); logger.trace("trace信息"); } 输出结果:logback默认输出格式
11:21:36.810 [main] ERROR com.
题目
在n nn个人中,某些人的银行账号之间可以互相转账。这些人之间转账的手续费各不相同。给定这些人之间转账时需要从转账金额里扣除百分之几的手续费,请问A AA最少需要多少钱使得转账后B BB收到100元。
输入
第一行输入两个用空格隔开的正整数n nn和m mm,分别表示总人数和可以互相转账的人的对数。以下m行每行输入三个用空格隔开的正整数 x xx , y yy , z zz,表示标号为x的人和标号为y的人之间互相转账需要扣除z zz%的手续费( z < 100 ) ( z < 100 )(z<100)。最后一行输入两个用空格隔开的正整数A AA和B BB。数据保证A AA与B BB之间可以直接或间接地转账。
输出
输出A AA使得B BB到账100元最少需要的总费用。精确到小数点后8位。
样例
input
3 3 1 2 1 2 3 2 1 3 3 1 3 output
103.07153164 #include<bits/stdc++.h> using namespace std; using ll = long long; int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 }; //using lll = __int128; template <class T> istream& read(T& x, istream& cin = std::cin) { T num = 0; bool f = 0; char ch = 0; while (!
WHERE 与 HAVING 有什么区别 WHERE 是一个约束声明,使用 WHERE 约束来自数据库的数据,WHERE 是在结果返回之前起作用的,WHERE 中不能使用聚合函数。
HAVING 是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作,在 HAVING 中可以使用聚合函数。另一方面,HAVING 子句中不能使用除了分组字段和聚合函数之外的其他字段
MySQL调优 索引覆盖 索引覆盖可以减少树的搜索次数,显著提升查询性能,因此使用索引覆盖是一个常用的性能优化手段
最左前缀 如果已经有了(a,b)这个联合索引后,一般就不需要单独在 a 上简历索引了。因此,第一原则是,如果通过调整顺序,可以少维护一个索引,那么这个顺序往往就是需要优先考虑采用的。
索引下推 在 MySQL5.6 之后引入索引下推,可以在索引遍历过程中,对索引包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表的次数。
怎么减少行锁对性能的影响 在 InnoDB 事务中,行锁是在需要的时候才加上的,但并不是不需要了就立刻释放,而是要等到事务结束时才释放。这就是两阶段锁协议。
如果我们的事务中需要锁多个行,要把最可能造成冲突,最可能影响并发度的锁尽量往后放
举例说明:
顾客A到电影城B买票,将会执行一下操作
从顾客 A 账户中扣除电影票价给影院的账户余额增加这张电影票价记录一条交易日志 一共需要 update 两条记录,并 insert 一条记录,该三个语句在一个事务中。
假设又有顾客C到电影城B买票,那么这两个事务冲突的部分就是第二条语句了,因为他们要更新同一个影院账户的余额,需要修改同一行数据。
根据两阶段锁协议,不论怎么安排语句,所有的操作需要的行锁都是在事务提交的时候才释放的。所以,把 2 安排在最后,比如按照 3,1,2这样的顺序,那么影院账户余额这一行的锁时间就最少。最大程度地减少了事务之间地锁等待,提升了并发度。
文章目录 前言 准备 一、存储信息 1、存储信息寄存器 这个寄存器可以获取 片上FLASH存储器容量、片上SRAM容量
2、系统架构示意图 可见Flash的操作可以通过FMC控制器尽心操作,提供字、半字、字节闪存操作,可以扇区擦除、块擦除和部分系列(GD32F470xx, GD32F427xx and GD32F425xx )还提供页擦除(4KB)
3、存储器映射 这个F4系列最大3072KB,我们用的芯片只有 512K
4、存储扇区基地址和大小
可以看出,不同的扇区大小还不一样,有16K、64K、128K不同大小的扇区
二、解锁 1、解锁FMC_CTL、FMC_OBCTLx 复位之后 如果要操作FMC前要解锁 FMC_CTL这个控制寄存器、若果要操作选项字节需解锁FMC_OBCTLx 选项字节控制寄存器,都是先后往对应的KEY解锁寄存器写入两个对应的序列,上锁是把对应 的 LK bit 置1
FMC_CTL解锁上锁例程
/*! \brief unlock the main FMC operation \param[in] none \param[out] none \retval none */ void fmc_unlock(void) { if((RESET != (FMC_CTL & FMC_CTL_LK))) { /* write the FMC key */ FMC_KEY = UNLOCK_KEY0; FMC_KEY = UNLOCK_KEY1; } } /*! \brief lock the main FMC operation \param[in] none \param[out] none \retval none */ void fmc_lock(void) { /* set the LK bit*/ FMC_CTL |= FMC_CTL_LK; } 2、解锁 也擦除配置寄存器 FMC_PECFG 当需要执行页擦除操作时需要 往 FMC_PEKEY 寄存器写入 0xA9B8C7D6来解锁FMC_PECFG寄存器
【ST-LINK报错原因之一:固件丢失】 好久没有用开发板和stlink,今天发现下载报错,明明电脑已经装了stlink驱动。猜测可能是stlink固件丢失。
1.确认stlink驱动已安装:打开keil->魔术棒->Debug->setting->[Debug Adapter]框中可以检测到ST-LINK/V2和Serial等信息。 但右侧[SW Device]框内无法检测到stm32设备,框内显示[ST-LINK Connection error]。 2.更新stlink固件,可通过官方软件STM32CubeProgrammer来更新你的stlink固件。 3.更新后重新插拔,按步骤1中操作,如图所示[SW Device]中可以检测到stm32设备,即可下载程序。
error: L6002U: Could not open file ..\..\output\motor.o: No such file or dir
在motor.c/.h文件中使用的编译器不能识别的操作符:
如 变量 =*(uint8_t*) (&value);
在钉钉群中添加Webhook自定义机器人,
复制Webhook地址保存:
https://oapi.dingtalk.com/robot/send?access_token=xxxxxx 安全设置:选择加签方式,复制加签保存
#!/usr/bin/python # -*- coding: utf-8 -*- import requests import json import time import hmac import hashlib import base64 import urllib.parse timestamp = str(round(time.time() * 1000)) secret = '复制的安全设置中的加签' secret_enc = secret.encode('utf-8') string_to_sign = '{}\n{}'.format(timestamp, secret) string_to_sign_enc = string_to_sign.encode('utf-8') hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest() sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) print(timestamp) print(sign) headers = {'Content-Type': 'application/json;charset=utf-8'} api_url = 'https://oapi.dingtalk.com/robot/send?access_token=xxxxx×tamp=' + timestamp + "&sign=" + sign def msg(text): json_text= { "
前言 这个笔记来自黑马程序员的SpringBoot,里面是老师的笔记,这里给写了下来
restful风格 REST简介
* REST表现形式状态转换 传统风格资源描述形式 http://localhost/user/getById?id=1 http://localhost/user/saveUser REST风格描述形式 http://localhost/user/1 http://localhost/user * 优点: * 隐藏资源的访问行为,无法通过地址得知对资源是何种操作 * 书写简化 REST风格简介
按照REST风格访问资源时使用行为动作区分对资源进行了何种操作
http:localhost/users 查询全部用户信息 GET(查询)
http:localhost/users/1 查询指定用户信息 GET(查询)
http:localhost/users 添加用户信息 POST(新增/保存)
http:localhost/users 修改用户信息 PUT(修改/更新)
http:localhost/users/1 删除用户信息 DELETE(删除)
根据REST风格对资源进行访问称为RESTful
注意事项:
上述行为是约定方式,约定不是规范,可以打破,所以称RESt风格,而不是REST规范
描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts…
@Controller public class Controller{ @RequestMapping(value="/users",method = RequestMethod.POST) @ResponseBody public String save(){ System.out.println("user save..."); return "{'module':' user save'}"; } @RequestMapping(value="/users/{id}",method = RequestMethod.DELETE) @ResponseBody public String delete(@PathVariable Integer id){ System.out.println("user delete..."+id); return "
图像翻译/Transformer:ITTR: https://arxiv.org/abs/2203.16015用Transformer进行非配对图像对图像的转换 0.摘要1.概述2.方法2.1.预备知识2.2.整体架构2.3.混合感知块2.4.双重修剪自我注意2.5.目标 论文地址
0.摘要 未配对图像到图像的翻译是在没有成对训练数据的情况下,将图像从源域翻译到目标域。通过利用CNN提取局部语义,人们开发了各种技术来提高翻译性能。然而,基于CNN的生成器缺乏捕获长期依赖性的能力,无法很好地利用全局语义。近年来,视觉转换器在识别任务中得到了广泛的研究。虽然很有吸引力,但由于生成困难和计算限制,将基于识别的视觉转换器简单地转换为图像到图像的翻译是不合适的。在本文中,我们提出了一种有效的基于Transformer的非成对图像到图像翻译体系结构(ITTR)。它主要有两种设计:1)混合感知块(HPB),用于从不同感受域混合标记,以利用全局语义;2) 双剪枝自我注意(DPSA)可大幅降低计算复杂度。在六个基准数据集上,我们的ITTR在未配对图像到图像的翻译方面优于最新水平。
1.概述 未配对图像到图像的翻译是在没有成对训练数据的情况下,将图像从源域翻译到目标域。翻译结果应该由源域的内容和目标域的风格构成。大多数重要的未配对图像到图像翻译方法【59,34,58】都关注训练策略的制定。然而,生成器结构仍然基于卷积神经网络(CNN)。虽然CNN在提取局部语义方面是有效的,但它缺乏捕获图1中所示的长期依赖性的能力。
为了丰富美国有线电视新闻网的能力,之前的一项研究I2ISA[20]试图采用非局部块[49]。特别是,受SAGAN【56】的启发,I2ISA【20】在其生成器架构中嵌入了一个非局部块,以增强未成对图像到图像的转换性能。尽管I2ISA的翻译性能大体上是有效的,但如图2所示,I2ISA的翻译性能仍然在一定程度上受到限制。产生此结果的一个可能原因是I2ISA在生成器的解码器中只有一个非局部块,这仍然缺乏充分利用全局语义的能力。
为了完全捕获长距离依赖关系,一个潜在的解决方案是引入基于Transformer的生成器体系结构,用于未成对的图像到图像的转换。事实上,视觉Transformer可以与多个多头自我注意(MHSA)块堆叠在一起,以持续捕获长期依赖性。然而,基于识别的Transformer不适合像未成对图像到图像的转换这样的生成任务,这需要视觉质量和语义一致性。此外,当输入图像分辨率较高时,由于MHSA算法的复杂性,基于识别的Transformer也会遭受巨大的计算开销和内存消耗。因此,需要新的设计来处理生成困难和计算限制。
在本文中,我们提出了一种有效的基于Transformer的非成对图像到图像翻译体系结构(ITTR)。它有两种有针对性的设计。首先,我们提出了混合感知块(HPB),用于不同感受野的空间token混合,旨在解决生成器在生成过程中遇到的难点。HPB能够分别通过深度卷积分支和自我注意分支提取短距离和长距离上下文信息。其次,我们提出双重剪枝自我注意(DPSA)来降低MHSA的复杂性。在计算注意图之前,DPSA评估标记对行和列的贡献。然后,对贡献较少的标记进行修剪,以便大幅降低注意力地图的复杂性。
为了证明我们的方法的有效性,我们在包括Horse在内的六个基准数据集上对未成对图像到图像的翻译进行了定性和定量实验→ 斑马[59]、城市景观[6]、猫→ 狗,脸→ Metface【21】,女性→ 卡通【36】和自拍→ 动画【24】。图3显示了ITTR产生的一些定性结果。与最先进的方法相比,ITTR在定性和定量方面都取得了更好的性能。
我们的贡献总结如下:
针对未成对图像到图像的翻译任务,提出了一种基于转换器的体系结构ITTR混合感知块(HPB)旨在从本地和全球的不同感知中捕获上下文信息为了在保持性能的同时降低计算复杂度和内存消耗,提出了双剪枝自我注意(DPSA)在六个数据集上的实验从定性和定量两方面验证了我们方法的有效性。特别是,我们的方法在FID【16】和DRN得分【34】方面都优于最先进的方法。 2.方法 图4所示。ITTR的架构。从左到右分别为ITTR整体架构、HPB (hybrid perception block)架构、DPSA (dual pruned self-attention)架构。“Conv”意味着卷积。“IN”是实例规范化的缩写。“DW”意味着深度方面。圈中的“C”表示串联。“L2规范”是明智的L2规范化。space -wise sum是计算q中所有令牌的和。row -wise或Col-wise sum是计算k中同一行或同列令牌的和。Token selection是从一个有索引的矩阵中选择行和列。圈中的“×”表示矩阵乘法。右边的虚线框表示在DPSA单个头部进行的操作。
在本节中,我们首先介绍有关vision transformer的一般架构的一些预备知识。然后,我们从总体架构和构建块、混合感知块和双重修剪自我注意等方面说明了ITTR的详细设计,如图4所示。最后,我们提出了完整的学习目标。
2.1.预备知识 Transformer(Transformer)[43]最初是作为自然语言处理(NLP)任务的网络体系结构提出的。后来,ViT[8]为图像分类等视觉任务引入了基于transformer的体系结构。ViT是由MHSA和FFN组成的纯Transformer网络。在ViT中,二维图像的面片I∈ RH×W×3嵌入到Token X∈ RN×C中。然后将Token 拆分为Nh头X∈ RNh×N×C/Nh。Xi∈ RN×Dh,i∈ {1,2…Nh},Dh=C /Nh,用于按线性层计算Qi、Ki和Vi。
这里,Wq,Wk,Wv∈ RC×C表示对应于查询、键和值的可学习参数矩阵。然后,用Qi,Ki,Vi计算自我注意。
来自每个头部的结果被串联起来,并以偏差输入到线性层中。
然后将串联的特征映射输入前馈网络(FFN)。
最近的一些工作【47,12】已经在FFN中插入了深度方向的卷积层。这种变体被称为反向前馈网络(IFFN),因为它类似于MobileNetV2中的反向残差块[37]。
2.2.整体架构 如图4所示,我们提出的ITTR的总体架构由三部分组成:1)带有三个卷积层的stem,用于重叠的贴片嵌入和下采样操作;2) ITTR主体由9个串联的混合感知块组成;3) ITTR的解码器,是stem的镜像。设计动机描述如下
首先,为了扩大面片的大小,我们使用堆叠卷积层进行重叠面片嵌入。与非重叠面片嵌入相比,重叠面片嵌入的面片大小由4×4增加到13×13像素。此外,将重叠的面片嵌入层解耦为三个卷积层更有效。其次,为了确保生成器容量并进行公平比较,我们在ITTR主体中堆叠了9个HPB,以便块数与基线切割中的发电机相同【34】。第三,ITTR译码器采用三层卷积实现。卷积层比HPB更有效地处理上采样后的高分辨率特征映射。
使用输入图像I∈ RH×W×3执行上述步骤可描述如下:
2.3.混合感知块 提出了混合感知块(HPB)从局部感知和全局感知中获取上下文信息。为了实现这一点,HPB使用图4所示的两个并行分支在相邻或遥远的token之间进行空间token混合。局部分支采用卷积层以提高局部效率。更准确地说,我们使用了一个深度方向的卷积层来进一步降低复杂性。此外,全局分支机构采用自我关注来实现远程依赖。因为自我注意中的注意映射在每个标记对之间建立了关系。
此外,预计将进行信道融合。首先采用MLP层对两个分支提取的位置对应标记进行融合,目的是融合从不同感知中提取的上下文信息。然后,采用卷积FFN进行更详细的融合,并进行信道扩展和缩减。此外,在信道扩展后,还使用深度卷积层进行空间令牌混合。此外,Instance Normalization[41,42]和GELU[14]激活用于稳定分布和加速收敛。
2.4.双重修剪自我注意 图5所示。DPSA中令牌预剪枝机制示意图,见3.4节。Key中的令牌按行和列分组,以计算贡献分数。贡献较小的行和列中的令牌将从Key和Value中删除。
为了简化描述,我们在本小节中采用单头DPSA来解释其机理。图5所示的DPSA的前向传播过程可以分解为token贡献测量和token修剪。
在DPSA中,标记kj在K∈ RN×C中的贡献定义为ΣNi=1aij。根据该定义,注意力图的计算应先于token贡献的计算。然而,这是不可接受的,因为设计DPSA的动机是在计算注意图之前对键和值进行预修剪。相反,我们计算按行或列分组的标记的贡献。因此,由于向量内积的分布性质,贡献度量的成本可以大幅降低。贡献度量公式如下所示,qi和kj是查询中的标记(Q∈ RN×C)和整形键(K′∈ RH×W×C):
值得注意的是,只有在查询和密钥采用基于token的L2规范化时,才能以这种方式计算分组token的贡献。由于Q或K中标记向量的范数被归一化为1,因此注意图中的元素值被限制在该范围内(−1, 1).
可以分为两种情况:
代码换行长字符串换行 一、 C/C++代码换行直接用enter键换行,同时注意关键字不要切割: bool a=true; if(a == true) { std::cout<<"Hello"<<std::endl; }//ok,关键字没有切割 if(a = = true) { std::cout<<"Hello"<<std::endl; }//error,切分了关键字== 下面可以但是最好不要这么做的用法(可读性):
void fun\ ction() { std::cout<<"I am function"<<std::endl; } 宏函数倒是挺常见的:
#define MAX(a,b)\ ((a)>(b)?(a):(b)) 二、长字符串换行 两种方式实现长字符串在编辑区换行。
2.1 双引号 将一个大字符串拆分成属于不同行的、引号字符串。
const char *text = "This text is pretty long, but will be " "concatenated into just a single string. " "The disadvantage is that you have to quote " "each part, and newlines must be literal as "
背景:
因项目需要,要做一个调用短信接口发送短信的功能。需要实现一个功能是,给定一个字符串,给定一个密钥对。实现RSA公钥加密,Base64加密,然后将加密后的字符串发给服务器。服务器返回通过私钥和Base64加密后的字符串,然后我这边要实现Base64解密后,RSA公钥解密。
1.RSA加密的原理,网上都有很多介绍,在这就不介绍了,需要注意的概念如下:
rsa加解密分两种,第一:公钥加密私钥解密。第二:私钥加密公钥解密。 需要注意的是,公加私解得到的密文是变化的,而私加公解的得到的密文是固定的。
生成密匙对需要设置一个长度,常用的设置为1024,或者2048。注意,不同长度的密匙,能够加密的明文最长度是有限制的。说明如下:
1024的情况:
加密时,明文最大长度: 1024/8 - 11 = 117 ,因此需要对明文做117字节长度的分片加密,再拼接。
解密时,密文最大长度:1024/8 = 128, 因此需要对密文做128字节长度的分片解密,再拼接。
2048的情况:
加密时,明文最大长度: 2048/8 - 11 = 245 ,因此需要对明文做245字节长度的分片加密,再拼接。
解密时,密文最大长度:2048/8 = 256, 因此需要对密文做256字节长度的分片解密,再拼接。
C++调用openssl库生成的密匙对是pkcs#1格式的。java调用库生成的密匙对是pkcs#8格式的。
pkcs#1
-----BEGIN RSA PUBLIC KEY-----
......公钥
-----END RSA PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
......私钥
-----END RSA PRIVATE KEY-----
pkcs#8
-----BEGIN PUBLIC KEY-----
......公钥
-----END PUBLIC KEY-----
-----BEGIN PRIVATE KEY-----
......私钥
-----END PRIVATE KEY-----
2.先上代码
```
RSACrypt.h
#include <openssl/rsa.
Function.prototype.changeThis = function (obj, args) { // 判断调用者是否为function类型 if (typeof this !== 'function') { throw new Error('调用者不是一个函数') } const fn = Symbol() // 防止和其他属性冲突 // 判断obj是否为null或者undefined if (obj == null || obj == undefined) { window[fn] = this window[fn](...args) delete window[fn] } // 判断obj是 number类型 if (typeof obj === 'number') { Number.prototype[fn] = this Number.prototype[fn](...args) delete Number.prototype[fn] } // 判断obj是 string类型 if (typeof obj === 'string') { String.prototype[fn] = this String.
MCU:STM32F10ZE(正点原子战舰板),开发环境:MDK5
DMA:(Direct Memory Access),即直接存储器访问。
优点:解放CPU。
UART:串口,不作介绍。
目的:使用DMA完成对串口数据的接收,这样可以解放出CPU,CPU可以同时做其他事情。
说明:这里仅用dma+uart接收,因为发送正点原子的例程里有。
参考资料:stm32中文参考手册,STM32F1开发指南(库函数版),正点原子官方例程战舰板。
直接粘代码:
1.串口初始化
//这里直接用的正点原子例程 void uart_init(u32 bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure);// //USART1_RX GPIOA.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure);//³õʼ»¯GPIOA.10 //Usart1 NVIC NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //USART USART_InitStructure.USART_BaudRate = bound; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.
概述
近来发现很多新手似乎不太明白驱动声卡的流程,也有同学清楚需要使用 AppleALC.kext,也知道要注入 id,可是就在启动参数那里扔一个 alcid=1 就觉得“我完事了”?,这个其实还没完,还有一些步骤要做,本篇将详细介绍一下驱动声卡的详细方法。
瑞昱 ALC 芯片
对于主流的 瑞昱 ALC 芯片(Realtek ALC),推荐使用 AppleALC.kext,它由 acidanthera 团队开发维护,是一个开放源代码内核扩展(Kernel Extension,缩写 kext),可以无需进行任何文件系统修改就可以为不受苹果官方支持的编解码器提供 HD 音频服务。目前来看,市面上大多数主板均板载了瑞昱的 ALC 芯片,所以 AppleALC.kext 也成为了主流驱动方案。
如何确认你的音频芯片是不是瑞昱,具体是 ALC 哪一款,可以通过以下几种方法:
鲁大师经典版,硬件检测标签下,声卡一栏在大部分情况下可以直接看到瑞昱以及具体 ALC 型号:
或者到主板的官方查看具体参数,比如微星 MPG Z490M
,一般情况下主板厂商会在参数页面明确标注出具体芯片的型号:
此外,如果你已经安装好了 macOS,还可以使用 Hackintool → 音频 进行查看。
仅在极少数情况下,可能存在显示芯片型号和实际芯片型号不一致的情况,常见于 OEM 产品,比如联想的启天 M420 部分机型,此类情况请先百度自己的芯片型号以确定真实的型号。
最后,除了瑞昱的 ALC 系列芯片外,AppleALC 还支持部分其他品牌的芯片(但型号都比较老旧),例如 AnalogDevices、Conexant,IDT 等,具体可参考下面的表格。
黑苹果系列之alc声卡id速查表
厂家 型号 id参数 AnalogDevices AD1984 0x100400, layout 11 ...
推荐 2021-12-22
找到合适的布局 ID
下一步,根据你得到的 ALC 芯片型号信息,在上面的表中找到对应的布局 ID(layout-id),例如 ALC1220 的对应 id 有 1, 2, 3, 5, 7, 11, 13, 15, 16, 21, 27, 28, 29, 34 ,前面可能还有一个修订号,这个指的是硬件版本,个别型号就会有这类情况,就是布局 ID 特别多,不知道用哪个,这个时候推荐优先尝试 11 以下的 id,因为 1-10 是为基本补丁资源预留的布局 ID:
1.项目效果展示 这里主要以后端为主,前端的代码不做展示,如果需要代码可以评论或者私信
用户注册、登录相关:
用邮箱进行注册,并通过向邮箱发送验证码来进行判断,一个邮箱只能注册一个账号
首页相关:
用户登录后可以进行发布问题和回答,同时也提供搜索功能,在首页展示所有问题
搜索:
评论:
2.项目工程目录 blueprints:
项目蓝图包括问答的逻辑实现和用户的逻辑时间
migrations:
项目数据库迁移
static、templates:
前端相关,css、html文件等
3.项目实现: 3.1数据库 主要是需要设计一个用户表user表,一个邮箱对应验证码EmailCaptcha的表,一个问题question表,一个评论Answer表
利用flask中提供的SQLAlchemy不用我们自己手动写SQL代码,用面向对象的思维解决就好
(1)新建db对象 因为在很多文件中都需要用到db对象,所以用一个专门的文件etx.py储存,并在app.py中进行初始化:
etx.py:
from flask_mail import Mail from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() mail = Mail() app.py:
app = Flask(__name__) # 配置项 app.config.from_object(config) db.init_app(app) mail.init_app(app) migrate = Migrate(app, db) # 组装蓝图 将book、course、user模块都组装在main.py中 app.register_blueprint(qa_bp) app.register_blueprint(user_bp) (2)配置数据库: # 数据库的配置变量 HOSTNAME = '127.0.0.1' PORT = '3306' DATABASE = 'flask' USERNAME = 'root' PASSWORD = '*****' DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.
目录 FIFO一. 自定义同步FIFO1.1 代码设计1.2 Testbech1.3 行为仿真***学习位宽计算函数$clog2()***$clog2()系统函数使用,可以不关注***分布式资源或者BLOCK BRAM 二.异步FIFO2.1 在FIFO判满的时候有两种方式:2.2 异步FIFO为什么要使用格雷码2.2.1 介绍格雷码2.2.2 格雷码在异步FIFO中的应用2.2.2 格雷码判满 2.4 二进制与格雷码之间的转换2.4.1 二进制码转换为格雷码的方法2.4.2 格雷码转换为二进制码的方法 2.3 实现框图2.5 实现及仿真代码2.6 仿真图验证2.7 结论 FIFO 这篇更多的是记录FIFO学习,参考了众多优秀的文章,我都会标记出来,首先是关于同步FIFO的参考搞懂FIFO书写的关键是什么,异步FIFO参加这篇异步FIFO讲解
FIFO 的英文全称是 First In First Out,即先进先出。 FPGA 使用的 FIFO 一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存,或者高速异步数据的交互也即所谓的跨时钟域信号传递。它与 FPGA 内部的 RAM 和 ROM 的区别是没有外部读写地址线,采取顺序写入数据,顺序读出数据的方式,使用起来简单方便,由此带来的缺点就是不能像 RAM 和 ROM 那样可以由地址线决定读取或写入某个指定的地址。
一. 自定义同步FIFO 为了增强对FIFO的认识,用Verilog描述一个FIFO。
FIFO是基于双口RAM衍生出来的,同步FIFO和异步FIFO的区别是主要是双口RAM的两套独立端口是否使用同一时钟,同步FIFO读写受同一时钟控制,其中设计的同步FIFO的信号如下所示。
FIFO大致分为写端和读端,两者都拥有独自的使能信号,以及写数据,这里数据宽度是8Bit,输出端对于FIFO的空满有相应的标志位,以及计数器和读出的数据。
FIFO读写的规则:
永远不要写入满FIFO永远不要读空FIFO FIFO在外部端口上表现没有地址线,因为是第一个到达的数据也将是第一个输出的数据,所以 FIFO缓冲区是一种读/写存储阵列,可自动跟踪数据进入模块的顺序并以相同顺序读出数据。而内部的实现需要两个指针来分别表示读和写的地址,读指针和写指针。初始时读写指针指向第一个存储单元,此时FIFO队列为空,fifo_empty有效,当写入256个数据,也就是写指针重新指向第一个FIFO的存储单元,而计数data_count等于FIFO的深度(0~255,但是写指针总是指向在下一个写的存储单元,所以当写完地址为255,8’b1111 1111后,变为9位的256 = 9‘b1 0000 0000)时,fifo_full有效。由此可知读写指针相同,此时有可能是满状态(写一直有效,写完最后一个255地址后,取低8位= 8’b0000 0000,此时读写指针的地址相同),所以用地址差不能用于判断空满,而是使用计数器来判断,但是计数器要设置比深度的位数多一位 ,这里也就是9位。
上面提到的博文中的这幅图,结合上一段的解释可以帮助理解地址的变化:
1.1 代码设计 其实更加规范的模式是想其中的位宽设置为参数,接下来的代码书写使用参数声明宽度。
//FIFO两条铁律就是不能满写 不能空读 module custom_FIFO( input wire clk, input wire rst_n, input wire wr_en, input wire [7:0] wr_data, input wire rd_en, output wire fifo_full, //空和满都是1有效 output reg [7:0] rd_data, output wire fifo_empty, output reg [8:0] data_count ); reg [7:0] mem [255:0]; reg [7:0] wr_add; reg [7:0] rd_add; //FIFO的书写方式应该是分信号进行书写 //wr_add总是指向下一个写的存储单元,在上升沿监测到写地址为255时,实际上的地址值重新因为溢出指向了地址0,此时溢出信号为真,而计数值达到256 //这里的逻辑是读写地址会自动从255变为0 always@(posedge clk)begin if(rst_n == 1'b0)begin wr_add <= 8'b0; end else if(wr_en == 1'b1 && fifo_full== 1'b0) begin wr_add <= wr_add + 1'b1; end end // rd_add always@(posedge clk)begin if(rst_n == 1'b0)begin rd_add <= 8'b0; end else if(rd_en == 1'b1 && fifo_empty == 1'b0) begin rd_add <= rd_add + 1'b1; end end //rd_data always@(posedge clk)begin if(rst_n == 1'b0)begin rd_data <= 8'h00; end else if(rd_en == 1'b1 && fifo_empty == 1'b0)begin rd_data <= mem[rd_add]; end end //wr_data always@(posedge clk)begin if(wr_en == 1'b1 && fifo_full== 1'b0)begin mem[wr_add] <= wr_data; end end always@(posedge clk)begin if(rst_n == 1'b0)begin data_count <= 9'h0; end else begin if(wr_en == 1'b1 && !
执行带group by的SQL语句出现如下错误:ERROR1055:Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'db.tb_list.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by。
错误原因:
MySQL 5.7.5及以上功能依赖检测功能。若是启用了ONLY_FULL_GROUP_BY SQL模式(默认状况下),MySQL将拒绝选择列表,HAVING条件或ORDER BY列表的查询引用在GROUP BY子句中既未命名的非集合列,也不在功能上依赖于它们。
解决方法:修改sql_model
方法一:执行数据库指令:
select @@global.sql_mode 查询出结果后去掉ONLY_FULL_GROUP_BY,重新设置值。
set @@global.sql_mode=’STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’; 方法二:修改mysql配置文件 :
找到mysql配置文件my.ini,或者跟我一样是集成环境phpstudy中的mysql找到配置文件mysql.ini:
双击打开,在mysqld下,client上方添加如下内容,保存后重启数据库即可:
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
文章目录 前言一:Spring源码核心结构1.1 图示1.2 Spring框架基本使用方式 二:配置文件的信息如何加载并解析成IOC容器2.1 大致流程2.2 Bean定义信息的定义方式2.3 BeanDefinition对象2.4 BeanDefinitionReader接口2.5 从BeanDefinition对象实例化Bean对象2.6 自定义BeanFactoryPostProcessor的演示2.7 PlaceholderConfigurerSupport占位符配置支持2.8 对象实例化的方式2.9 对象创建的流程2.9.1 图示2.9.2 填充属性2.9.3 执行int-method初始化方法 2.10 bean对象初始化阶段的细节分析2.10.1 流程图2.10.2 Aware接口 三:spring容器的存储结构3.1 string-object型3.2 class-object类型3.3 string-objectFactory3.4 string-BeanDefinition 四:总流程图 前言 Spring是spring生态圈的基石,大家工作中常用的SSM框架,SpringBoot框架都是在Spring基础上衍生的,所以想更好的了解它们深入学习Spring是必不可少的。本章以综述的方式带大家快速了解Spring核心流程。
一:Spring源码核心结构 1.1 图示 1.2 Spring框架基本使用方式 XML配置文件
使用函数
由上述Spring的使用过程可以衍生出两个问题:
1. XML配置文件加载解析到容器中并实例化成Bean对象的主要步骤是什么?
2. IOC容器是以什么数据结构存储Bean对象的?
接下来我们就来探讨以上这两个问题。
二:配置文件的信息如何加载并解析成IOC容器 2.1 大致流程 2.2 Bean定义信息的定义方式 相信大家通过观察上图很容易就发现出问题,难道Bean的定义信息只能通过XML配置文件来定义吗?显然不是。Spring为了提高拓展性提供了一个Bean定义信息的接口,只要想承载Bean定义信息的只需要实现这个规范即可。
如图所示:
2.3 BeanDefinition对象 BeanDefinition对象就是BeanDefinitionReader在解析Bean定义信息时,将Bean的定义信息封装成的对象。例如将xml文件中的bean标签的内容封装成对象,从这个对象中我们可以获取所有bean标签中定义的信息,也可以修改配置文件中定义的信息。
看源码BeanDefinition的方法:
2.4 BeanDefinitionReader接口 这个接口是所有想要承载Bean定义信息所需要实现的接口,该接口定义了一系列的规范。
看BeanDefinitionReader的子实现类
2.5 从BeanDefinition对象实例化Bean对象 相信很多小伙伴们觉得有了BeanDefinition对象就可以直接实例化Bean对象,这种思想咋一看好像是对的,毕竟都有了Bean的定义信息直接按照Bean定义信息封装的对象BeanDefinition来实例化对象不就可以了吗?但是如果在程序运行过程中要动态改变Bean的信息怎么办?要随时改变Bean的信息怎么办?例如<property name=url value=${jdbc.url},在这个情况下是绝对不能直接将BeanDefinition实例化成Bean对象的,因为IOC容器并不认识 ${jdbc.url},所以我们要在对象真正实例化进入容器之前进行拦截,替换掉 ${jdbc.url}。
我们可以在Bean对象真正被实例化出来之前,加BeanFactoryPostProcessor,来达到动态修改Bean对象信息的目的。
2.6 自定义BeanFactoryPostProcessor的演示 输出结果图:
2.7 PlaceholderConfigurerSupport占位符配置支持 现在我们解决2.
问题描述 在Ubuntu 22.04 中使用apt-get update 命令更新软件列表时,出现次错误
解决方法 apt-key命令用于管理Debian Linux系统中的软件包密钥。每个发布的Debian软件包都是通过密钥认证的,apt-key命令用来管理Debian软件包密钥,常用命令如下。
列出已保存在系统中key:
[root@wild_wolf ~]# apt-key list 把下载的key添加到本地trusted数据库中:
[root@wild_wolf ~]# apt-key add keyname 从本地trusted数据库删除key:
[root@wild_wolf ~]# apt-key del keyname 更新本地trusted数据库,删除过期没用的key:
[root@wild_wolf ~]# apt-key update 使用如下命令向pgp传递高级特性,后面跟的是NO PUBKEY后面那串代码,比如:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 76F1A20FF238972E 解决结果 然后使用 apt-get update 即可。
目录
1.Docker镜像加载原理
2.分层理解
3.commit镜像
镜像是什么?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时库、环境变量和配置文件。
将所有的应用和环境,直接打包为docker镜像,就可以直接运行。
1.Docker镜像加载原理 UnionFs (联合文件系统)
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。
联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系
统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
Docker镜像加载原理
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含 bootloader和 Kernel, bootloader主要是引导加 kernel,Linux刚启动时会加bootfs文件系统,在 Docker镜像的最底层是 bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs转交给内核,此时系统也会卸载bootfs。
rootfs(root file system)在 bootfs之上。包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。 rootfs就是各种不同的操作系统发行版,比如 Ubuntu,Centos等等
虚拟机里的CentOS都是好几个G,为什么Docker里才200M?
对于个精简的OS,rootfs可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就可以了。由此可见对于不同的Linux发行版, bootfs基本是一致的, rootfs会有差別,因此不同的发行版可以共用bootfs。
虚拟机启动是分钟级别,容器是秒级!
2.分层理解 我们可以去下载一个镜像,注意观察下载的日志输出,可以看到是一层层的在下载
[root@fedora ~]# docker pull redis Using default tag: latest latest: Pulling from library/redis a2abf6c4d29d: Already exists c7a4e4382001: Pull complete 4044b9ba67c9: Pull complete c8388a79482f: Pull complete 413c8bb60be2: Pull complete 1abfd3011519: Pull complete Digest: sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339 Status: Downloaded newer image for redis:latest docker.
一、引入 涉及技能:
循环、分支方法的抽取数组的使用面向对象继承,子类方法的重写接口,接口的实现GUI(图像化界面编程) GUI中的组件:
7.1 窗口
7.2 弹窗
7.3 面板
7.4 文本框
7.5 列表框
7.6 按钮
7.7 图片
7.8 交互的事件:监听事件(鼠标事件,键盘事件)
GUI技术,不流行了!!!界面太简单粗糙!!
已经被淘汰了,为什么还学?
提起兴趣分层思想锻炼监听器的思想举一反三(蛇的图片换成其他图片,食物的图片换成其他图片)工作中用到 注意:
学的是 思想!!!
二、原理图 小蛇素材图像素为25*25,因此在对应xy轴上的数值也以25为步长。
三、进入正题 1.打开IDEA工具,新建一个模块module。
2.选择java,点next。
3.取一个名字叫TestSnake,然后点击finish。
4.打开新建好的TestSnake,在src下新建一个文件夹,取名为images。
5.将所有的素材图片复制到images文件夹下。
四、将图片加载到程序中 1.在src下再新建一个文件夹com.game,在这个文件夹下新建一个类Images,用于获取图片。
2.打开Images类,将以下代码写入,封装图片,后续使用时只要类名+图片即可。
import javax.swing.*; import java.net.URL; /*用来获取游戏中所有涉及的图片*/ public class Images { /*面向对象思想:将图片进行封装,封装为一个对象,在程序中通过操纵这个对象来操纵图片*/ /*将图片的路径封装为一个对象:*/ // class获取字节码 // getResource获取图片路径 // 在菜单Build下选中第二个Build Module,重写构建一下,生成对应的字节码信息 // 在out文件夹下找图片路径 // '/'指代相对路径,相对file:/C:/Users/ASUS/Desktop/贪吃蛇小游戏/out/production/TestSnake/而言 public static URL bodyURL=Images.class.getResource("/images/body.png"); /*将图片封装为程序中一个对象:*/ // ImageIcon构造器,可以直接把url传进去 public static ImageIcon bodyImg=new ImageIcon(bodyURL); /*同理,将剩下的图片都封装:*/ public static URL downURL=Images.
专栏:数据结构与算法分析
上一篇: (一)数据结构绪论
下一篇:
文章目录 1. 估计算法资源消耗所需1.1 实验统计1.2 理论分析1.3 实验统计与理论分析 2. 算法复杂度2.1 时间复杂度 (Time complexity)2.1.1 一个简单的例子2.1.2 不同复杂度之间的对比 2.2 空间复杂度(Space complexity) 算法(algorithm) 是对特定问题的求解步骤的一种描述,是指令的有限序列,其中一条指令表示一个或多个操作。
根据算法编制的程序最终是要运行在计算机上,由计算机执行程序最终得出结果。所以我们需要考虑的是程序执行完毕得出结果需要多少时间,以及占用了多少资源(通常指占用内存)。
现在个人计算机的内存容量多数已经达到了4GB 和 8GB,而专门用于实验室的计算机,内存甚至已经达到了256GB以上。目前多数情况下,问题的规模不超过千万,足以存储,但是目前计算机的运行速度仍相对有限,特别当规模较大时,在执行时间上,不同效率的算法天差地别,有些算法只需要运行几秒就能得出答案,而另一种算法可能需要数千年。
目前来说,更为重视算法的运行时间,而不是内存空间占用大小。因此大规模问题的内存占用,现在的计算机基本上可以满足要求,并且内存并不是一次性消耗品,程序执行结束后,内存即可得到释放,并没有产生消耗。但是算法的运行时间则不同,不同效率的算法之间的差别过大,导致如果算法设计得不够好,即使小规模的问题,计算机仍需要数小时、数天来完成计算,当规模变得更大后,计算机在报废前完成计算都变成了奢望。
当然,也不是说内存空间占用就完全不需要理会,而是说目前的存储器容量在大规模问题上都可以满足大多数算法的需求,大多时候存在空闲空间,很少会出现需要远超于问题规模的存储空间的情况。反而是一般效率的算法,处理中等规模问题时很有可能做不到数秒内完成,所以一般是优先考虑运行时间,甚至为了更快还会以空间换时间。
1. 估计算法资源消耗所需 估计算法资源消耗所需,通常有两种方法,分别是实验统计和理论分析。
1.1 实验统计 实验统计 的方法是直接按照对应算法编写程序,然后分别记录不同规模的输入时程序所需的运行时间和占用空间。
这种方式虽然可以得到较为准确的运行时间和占用空间数据,但是需要由算法编写出相应的程序并在机器上运行,比较费时间。对于同一个算法,使用不同的编程语言编写或者同一个编程语言使用不同的实现也会对运行时间造成影响。同时,计算机硬件配置不同,运行速度有快有慢,得到的数据也只能作为参考,并不说明在其它机器上也消耗这么多资源。
对实验统计得到的数据进行拟合,可以得到算法所需资源消耗与问题规模的关系。
1.2 理论分析 理论分析方法则是直接根据算法或相关代码来得到运行时间与问题规模大小的关系。
理论分析的方法仅仅是得到资源消耗与问题规模大小之间的关系,并非是实际时间数据,因此,要估算出算法所需的资源消耗,还需要在计算机上运行实际程序,得到输入在某个规模大小时对应时间值和占用空间大小,以此推算出算法在不同问题规模下所需的相应资源消耗。
理论分析方法得到的资源消耗与问题规模大小之间的关系,在不同的设备上,不同的环境都通用,可以借此来对算法的好坏做一个评估。
1.3 实验统计与理论分析 实验统计和理论分析方法各有优势。理论分析较为简便,通用性好,但无法得到实际数据,只能估算。实验统计方法耗时久,受环境因素影响大,但针对性强。
当程序实际运行环境确定后,实验统计方法得到的数据更接近实际,并且可以用来验证理论分析所得出结果。所以通常采用理论结合实际的方式,在理论分析完毕后进行实验统计,不仅可以验证算法的正确性,还能防止意料情况的发生(如问题达到一定规模后,占用内存超出设备内存容量等)。
2. 算法复杂度 算法复杂度 即算法所需资源与数据规模之间的增长关系,分为 时间复杂度 和 空间复杂度。
2.1 时间复杂度 (Time complexity) 算法总是假定运行在计算机上,但是并不指定计算的性能。为了便于分析,我们把计算机执行一条简单指令或执行由数条简单指令构成的复合指令的时间都定为1。
相当于如果两条语句分别是执行一次加法和执行3次乘法,它们的运行时间认为是相同的,这么做是为了简化分析。分析时先得出简单的关系,如果有必要,再进行细致的分析。
下面我们尝试对一个实现的简单算法分析其运行时间与数据规模大小之间的关系。
2.1.1 一个简单的例子 这里是一个计算通项公式为 a i = i 3 a_i = i^{3} ai=i3 的数列的前 N N N项和 S ( N ) = 1 3 + 2 3 + 3 3 + ⋯ + N 3 S(N) = 1^{3} + 2^{3} + 3^{3} + \cdots + N^{3} S(N)=13+23+33+⋯+N3 的简单程序片段:
在某个页面(JSP)有localStorage保存的值; 在使用location.href重新指向该页面时,原先在localStorage的值就会被清空. 所以LocalStorage并不是永久性的本地缓存
给出N个数字,请找出升序排列后,处于中间位置的那个数字. 即输出第(1+n) /2 那个数字. N<=2*10^6
Input 如题所示
Output 如题所示
Samples 输入数据 1 5 2 4 1 3 5 Copy
输出数据 1 3 思路:使用sort排序快速将数组升序排列,在求出第 (1+n) /2个数,即a[(1+n) /2]。
代码如下:
#include<bits/stdc++.h> using namespace std; int n,a[2000005]; int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; } sort(a+1,a+1+n); cout<<a[1+n/2]; return 0; }
1.堆的定义 堆(heaps)是一种特殊的数据组织方式,STL 中的 priority_queue 容器适配器底层就是采用堆来组织数据存储的。
一般可用变量size存储堆的长度,数组名为heep。 2.堆的基本操作 3.堆的基本性质 4.堆的存储 5.堆的维护1——down() 代码如下: void down(int k) { int t=k; if(k*2<=size && heep[k*2]<heep[t]) t=k*2; if(k*2+1<=size && heep[k*2+1]<heep[t]) t=k*2+1; if(k!=t) { swap(h[k],h[t]); down(t); } } 6.堆的维护2——up() 代码如下: void up(int k) { while(k/2 && heep[k/2]>heep[k]) { swap(heep[k/2],heep[k]); k/=2; } } 7.堆的基本操作之caru() int caru(int x) { heep[++size]=x; up(size); //down(size); } 8.堆的基本操作之min_dui() int min_dui(int x) { return heep[1]; } 9.堆的基本操作之dele_min() int dele_min(int x) { heep[1]=heep[size]; size--; down(1); } 10.
尺取法:有效三角形的个数 文章目录 尺取法:有效三角形的个数问题:思路:代码: 问题: 思路: 该题需要使用三个元素的尺取法求解,三个元素的尺取法就是需要枚举一个,然后利用双指针扫描剩下的区间,其余两个元素分别为区间左端点与右端点,根据题中的不同条件移动这两个元素之一
我们先对题中数组进行排序,三条边长从小到大为 a、b、c,当且仅当 a + b > c 这三条边能组成三角形。这道题只能枚举最大边进行反向扫描,如果是枚举最短边正向扫描,若两边之和小于第三边,那么会有两种情况,一种是左指针往右移动,一种是右指针往左移动,移动的情况是不确定的。枚举最大边反向扫描时,如果两边之和小于第三边,只能是左指针往右,移动的情况是确定的,如果两边之和大于等于第三边,只能是右指针往左。
因此我们枚举数组最右边的最大值,下标k,剩下的区间中,区间右端点为第二大的值,下标为j = k - 1,最小值从下标i = 0开始,若nums[i] + nums[j] > nums[k],那么i从当前的i开始,一直到j - 1,都能满足这个条件,因此我们找到了j - i个有效三角形,同时将右指针往左,j - -,寻找其他满足条件的情况。若nums[i] + nums[j] <= nums[k],将左指针往右,i ++。在i >= j时,我们就遍历了区间中的所有情况。
代码: public int triangleNumber(int[] nums) { // write code here Arrays.sort(nums); int ans = 0; int i, j, k; for (k = nums.length - 1; k >= 2; k--) { j = k - 1; i = 0; while (i < j) { if (nums[i] + nums[j] > nums[k]) { ans += (j - i); j--; } else { i++; } } } return ans; }
(注:这里通用摄氏度,Python版本为3.8.5)
今天教大家做一个温度换算模块,非常简单实用。
这张图是最终效果:
(CK指将摄氏度转换为开氏度,CRe指将摄氏度转换为列氏度)
不多说了,直接捧上代码,程序猿们敲起键盘来:
1.源代码 class ChangeTempCelsius(): def CF(celsius): #华氏度 cf = celsius * 1.8 + 32 return cf def CK(celsius): #开氏度 ck = celsius + 273.15 return ck def CRe(celsius): #列氏度 cre = celsius / 1.25 return cre def CR(celsius): #兰氏度 cr = (celsius + 273.15) * 1.8 return cr 这个模块用摄氏度来转换成四种别的温度,制作过程中无需引入任何库。
这里用到return来报出计算出来的结果。
然后放到Python对应目录中:
(Python38中的Lib文件夹)
2.测试 1.测试能否导入模块:
>>> import ChangeTemp >>> from ChangeTemp import ChangeTempCelsius as CTC >>> 如果能,进行下一步:
如图:
使用jquery.ajax 与直接浏览器 访问同一个接口,大概有3倍左右的差距
下面直接引用原生代码:
发现时间差不多,那么问题了,这多余的时间干嘛去了??
数据格式的组成?
接下来点开看下区别
jq请求
浏览器请求
你是日了狗了, DNS Lookup dns调优???????
那是不是接着重复在浏览器异步里发送该请求是不是更快
果然如此,害我还以为是jQuery 封装 的xmlhttp 有问题,搞了这么久,分享下代码吧
<script> // 格式化请求参数 function formatParams(data) { let arr = []; for (let name in data) { arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name])); } arr.push(('v=' + Math.random()).replace('.', '')); return arr.join('&'); } function ajax_xml2(options) { options = options || {} // 调用函数时如果options没有指定,就给它赋值{},一个空的Object options.method = (options.method || 'GET').toUpperCase() // 请求格式GET、POST,默认为GET options.dataType = options.dataType || 'json' // 响应数据格式,默认json options.
简答题:
软件体系结构建模的种类有: 结构模型、框架模型、动态模型、过程模型、功能模型。
“4+1”视图模型从5个不同的视角包括: 逻辑视图、进程视图、物理视图、开发视图和场景视图来描述软件体系结构。
构件:是具有某种功能的可重用的软件模板单元,表示了系统中主要的计算元素和数据存储。 连接件:表示构件之间的交互.
配置:表示构件和连接件的拓扑逻辑和约束。
端口:表示构件和外部环境的交互点.
角色:定义了该连接交互的参与者。
4、画出“4+1”视图模型图,分析各部分的原理和功能。
软件体系结构风格: 是描述某一特定应用领域中系统组织方式的惯用模式.
6、软件体系结构
(Software Architecture)
软件体系结构以组件和组件交互的方式定义系统,说明需求与成品系统之间的对应关系,描述系统级别的可伸缩性、能力、吞吐量、一致性和兼容性等属性。 软件体系结构由组件、连接件和属性组成.
7、分层系统的优点有:
1)支持基于抽象程度递增的系统设计,使设计者可以把一个复杂系统按递增的步骤进行分解;
2)支持功能增强,因为每一层至多和相邻的上下层交互,因此功能的改变最多影响相邻的上下层;
3)支持重用。只要提供的服务接口定义不变,同一层的不同实现可以交换使用。这样,就可以定义一组标准的接口,而允许各种不同的实现方法。
8、分层系统的缺点有:
1)并不是每个系统都可以很容易地划分为分层的模式,甚至即使一个系统的逻辑结构是层次化的,出于对系统性能的考虑,系统设计师不得不把一些低级或高级的功能综合起来;
2)很难找到一个合适的、正确的层次抽象方法。
9、 B/S体系结构的优点有什么?
答:1)基于B/S体系结构的软件,系统安装、修改和维护全在服务器端解决。用户在使用系统时,仅仅需要一个浏览器就可运行全部的模块,真正达到了“零客户端”的功能,很容易在运行时自动升级.
2)B/S体系结构还提供了异种机、异种网、异种应用服务的联机、联网、统一服务的最现实的开放性基础。
10、B/S体系结构的缺点有什么?
答:1)B/S体系结构缺乏对动态页面的支持能力,没有集成有效的数据库处理功能。
2)B/S体系结构的系统扩展能力差,安全性难以控制。
3)采用B/S体系结构的应用系统,在数据查询等响应速度上,要远远地低于C/S体系结构。
4)B/S体系结构的数据提交一般以页面为单位,数据的动态交互性不强,不利于在线事务处理(OLTP)应用.
DSSA 答案:DSSA就是在一个特定应用领域中为一组应用提供组织结构参考的标准软件体系结构
11、软件体系结构的动态性主要分为:
交互式动态性、结构化动态性、体系结构动态性等三类。
12、请画出基于构件的动态系统结构模型画。
13、软件产品线
产品线是一个产品集合,这些产品共享一个公共的、可管理的特征集,这个特征集能满足选定的市场或任务领域的特定需求。这些系统遵循一个预描述的方式,在公共的核心资源(core assets)基础上开发的
14、SOA
即service-oriented architecture,面向服务架构。它是一个组件模型,它
将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接
口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于
实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的
系统中的服务可以以一种统一和通用的方式进行交互。
RIA 中间件 设计模式 答:一些设计面向对象的软件开发的经验总结,就是系统的命名、解释、和评价某一个重要的面向对象的可重现的面向对象的设计方案。
软件体系结构测试和传统软件测试区别 16、UML中的交互图有两种,分别是顺序图和协作图,请分析一下两者之间的主要差别和各自的优缺点。掌握利用两种图进行的设计的方法.
答:顺序图可视化地表示了对象之间随时间发生的交互,它除了展示对象之间的关联,还显示出对象之间的消息传递.与顺序图一样,协作图也展示对象之间的交互关系.顺序图强调的是交互的时间顺序,而协作图强调的是交互的语境和参与交互的对象的整体组织。顺序图按照时间顺序布图,而协作图按照空间组织布图。顺序图可以清晰地表示消息之间的顺序和时间关系,但需要较多的水平方向的空间。协作图在增加对象时比较容易,而且分支也比较少,但如果消息比较多时难以表示消息之间的顺序。
17。 管道过滤器风格结构特点
(1)使得软构件具有良好的隐蔽性和高内聚、低耦合的特点;
(2)允许设计者将整个系统的输入/输出行为看成是多个过滤器的行为的简单合成; (3)支持软件重用。
(4)系统维护和增强系统性能简单.
(5)允许对一些如吞吐量、死锁等属性的分析;
(6)支持并行执行。
但是,这样的系统也存在着若干不利因素。
(1)通常导致进程成为批处理的结构。这是因为虽然过滤器可增量式地处理数据,但它们是独立的,所以设计者必须将每个过滤器看成一个完整的从输入到输出的转换.
(2)不适合处理交互的应用。当需要增量地显示改变时,这个问题尤为严重。
(3)因为在数据传输上没有通用的标准,每个过滤器都增加了解析和合成数据的工作,这样就导致了系统性能下降,并增加了编写过滤器的复杂性.
18. 什么是设计模式?它与风格、框架有什么区别与联系?
利用nginx和nps搭建内网穿透测试环境且为https 基本的nginx、nps这里不再说明 背景:公司开发云直播需要使用https协议且测试人员不方便访问,干脆用云服务器干点活,闲着也是闲着
云服务器上对nginx配置ssl证书并代理nps指定的端口nps指定端口并指定内网端口 nps本身很像nginx,也可以反向代理,对nps熟悉的话可以直接取消nginx这一层
多语言的intl: ^0.17.0导不进去
intl: ^0.17.0 在命令行那里输入
flutter pub pub run intl_translation:gene rate_from_arb --output-dir=lib\i18n --generated-file-prefix=stock_ --no-use-deferred-loading lib\*.dart lib\i18n\stocks_*.arb 然后会说找不到插件,上网查了一下,添加
参考
build_runner: ^1.7.0 再运行就好了
Cannot read properties of undefined (reading ‘echarts’)
at eval (webpack-internal:///./src/views/my_components/charts/china.js:14:22)
引入本地china.js报错,信息如下
找了很多js文件都报错
解决办法: 使用echart中的文件
1、安装依赖
npm install echarts -S 2、引入
import 'echarts/map/js/china.js' 完美解决
检测机构报告,说我们app在杀死app有自启动和关联启动行为
情况一 排查中发现一种情况是AlarmManager定时任务导致的
@kotlin.jvm.JvmStatic fun startBDAlarmManager(context: Context, intervalInMS: Long) { // 启动定时器,发送BD_stat startAlarmManager(context, intervalInMS, BDTimerReceiver::class.java) } private fun startAlarmManager(context: Context, intervalInMS: Long, clazz: Class<*>) { try { val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager? val intent = Intent(context, clazz) val pIntent = PendingIntent.getBroadcast(context, 0, intent, 0) // 立即启动,有些手机上延迟会收不到通知 if (alarmManager != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + intervalInMS, pIntent) } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { alarmManager.
MongoDB-exporter部署文档 一、准备工作 mongodb_exporter 使用账号连接首先需要增加权限:
{ "role":"clusterMonitor", "db":"admin" }, { "role":"read", "db":"local" } 登录MongoDB shell
因为我的mongo是docker部署的。所以执行命令进入shell界面
docker exec -it mongo mongo admin’ 使用admin用户登录shell
db.auth('admin', '密码') 展示所有用户
show users 为用户增加权限
db.grantRolesToUser("admin",[{role:'clusterMonitor',db:'admin'},{role:'read',db:'local'}]) 查看是否生效
show users 退出shell
exit 二、docker部署 首先下载镜像:
docker pull percona/mongodb_exporter:0.20 启动容器
docker run -d -p 9216:9216 -p 17001:17001 --restart=always --name=mongodb-exporter percona/mongodb_exporter:0.20 --mongodb.uri=mongodb://admin:123456@127.0.0.1:27017/admin?ssl=false 三、二进制文件部署 nohup ./mongodb_exporter --mongodb.uri=mongodb://admin:123456@127.0.0.1:27017/admin?ssl=false --collect-all *这个可以配置成一个开机自启服务,这里不在赘述 四、浏览器访问 http://ip:9216/metrics 搞定!
机械臂逆运动学求解常用的方法有几何法、解析法、数值法
从求解的方式和计算的效率上来看,几何法和解析法会考虑机械臂结构不同而造成的差异,因此对于不同结构的机械臂会有特定的求解方式。
通常来说,这两种方法具有速度快、精度高的优点和通用性差、普适性低的缺点。而数值法则通常有相对统一的求解方式,具有适用性好但速度慢、数值稳定性差的特点。
对于工业机器人而言,通常处于特定的工作环境中,为了满足一定的工作性能要求而常采用解析法进行求解。
本文将使用解析法对该型机械臂进行逆运动学的求解。
下面通过Python代码的形式将这些推导的公式表示出来:
# 输入位姿矩阵T # 例如:T=np.matrix(np.array([[0.5,-0.7,-0.3,36],[-0.3,-0.6,0.6,-28.3],[-0.7,-0.2,-0.6,355.7],[0,0,0,1]])) # 输出解的列表q_list,里面的一个列表就代表一组解 # 例如:q_list=[[q1_1,q21,……],[],[],……] def ikine_6DOF(T): # 提取元素 nx = T[0, 0] ny = T[1, 0] nz = T[2, 0] ox = T[0, 1] oy = T[1, 1] oz = T[2, 1] ax = T[0, 2] ay = T[1, 2] az = T[2, 2] px = T[0, 3] py = T[1, 3] pz = T[2, 3] # 求解q1 # 见论文公式(2.
创建虚拟环境常用的两种方法
一:用conda创建虚拟环境的步骤 1:创建虚拟环境
conda create -n env python==3.6(版本号)
2:激活虚拟环境
source activate env
3:退出虚拟环境
source deactivate
4:安装所需的第三方库
conda install -n env [package]
5:查看conda环境下所有的虚拟环境
conda info --envs
二:用pycharm创建虚拟环境 1:创建虚拟环境
依次点击file-sittings-project-python interpreter-Add python interpreter-virtualenv environment
New environment location一般为当前工程目录 Base interpreter为自己创建的虚拟环境
2:使用虚拟环境
可以直接在pycharm中使用创建好的虚拟环境,安装和查看第三方库
也可以在终端中使用虚拟环境,转到pycharm中设定的虚拟环境的位置,一般在工程的根目录
常用的是第一种方法,下面详细介绍第一种方法
环境配置 环境的配置分为三步: 配置虚拟环境和安装程序所需要的包以及在pycharm中打开项目
配置虚拟环境 配置虚拟环境需要通过anaconda来完成,anaconda的下载地址为:https://docs.conda.io/en/latest/miniconda.html
windows用户下载python3.8的miniconda即可
下载完毕之后双击安装即可,具体安装过程自行百度
程序安装完毕之后打开windows的命令行(cmd),输入conda env list,可查看所有虚拟环境
1.在命令行中输入下列指令创建虚拟环境
conda create -n env python==3.6(版本号)
其中env是虚拟环境名字,3.6是python版本号
2.安装结束之后输入下列指令激活虚拟环境
source activate env
3.安装程序所需要的包
可以直接在命令行中直接执行下列命令安装程序所需的包(请根据自己程序自由选择所需安装的包)
pip install tensorflow-cpu == 2.3.0 -i https://mirror.
示波器中符号的意思是什么?
Vtop=5.05V,——波形顶端电压值 Vbase=56.9mV,——波形底端电压值 Vamp=5.01V,——波形幅度值 Vrms=1.98V,——电压均方根值 Prd=669.0us,——周期 Rise<4.00us,——上升时间 Fall<4.00us,——下降时间 +wid=125.0us,——正脉宽 -wid=544.0us,——负脉宽 +Duty=18.7%,——正占空比,一个方波正脉宽长度占整个周期的百分比 -Duty=81.2%,——负占空比,一个方波负脉宽长度占整个周期的百分比 方波,高电平与低电平的比例,可以从+wid、-wid、+Duty、-Duty这几个参数来推算
在做项目环境变量配置前,可以先到官网回忆一下环境变量的基本使用, 环境变量和模式 | Vite 官方中文文档
一、环境模式 首先环境变量是可以分模式的,常用模式如下:
.env # 所有情况下都会加载 .env.local # 所有情况下都会加载,但会被 git 忽略 .env.[mode] # 只在指定模式下加载 .env.[mode].local # 只在指定模式下加载,但会被 git 忽略 默认 dev 环境下使用 .env.development 环境变量配置, build 环境下使用 .env.production ,所以不需要在 package.json 中再指定模式了
"scripts": { "dev": "vite --mode development", // --mode development可以省略,运行 npm run dev 自动指定 "build": "vue-tsc --noEmit && vite build --mode production", // --mode production可以省略,运行 npm run build 自动指定 "preview": "vite preview" }, --mode 一般在其他特殊自定义下指定使用。
二、环境变量分类 2.
Git 如何合并commits成一个(squash) 方法一:使用git rebase方法二:使用git reset 两种方法。
方法一:使用git rebase 本地先从upstream拉一个branch
git checkout -b <main_branch> git pull upstream <main_branch> git checkout <dev_branch> 然后git rebase
git rebase -i <main_branch> 在跳出来的vim中对于需要squash的commit 前面把pick删掉写成s即可
注:这种方法如果upstream和本地对于起始commit都有update会有conflict squash不会成功
方法二:使用git reset 先通过git log查看一下要合并到哪个commit
然后简单明了使用
git reset --soft <commit_hash_to_squash_to> && git commit 再加上commit信息然后:x保存成功即可