1.参数
-A 全部备份
mysqldump -uroot -p -A > /data/backup/full.sql
-B 备份单库或多库
mysqldump -uroot -p -S /data/3306/mysql.sock -B soulchild > /data/backup/soulchild.sql
or
mysqldump -uroot -p -B wordpress emlog > /data/backup/wpaeml.sql
单表或多表备份
库名 表名
mysqldump -uroot -p wordpress user > /data/backup/full.sql
-d 只备份表的结构
mysqldump -uroot -p -d wordpress > /data/backup/wp.sql
mysqldump特殊功能参数
-R --triggers -E :备份过程、函数、触发器、事件等
--master-data=2:
--single-transaction
--set-gtid-purged=OFF
较为完整全备份语句:
mysqldump -uroot -p123 -A --master-data=2 --single-transaction -R --triggers -E --set-gtid-purged=OFF --max-allowed-packet=64M >/data/backup/full.sql
内存管理始终是底层软件的核心部分,尤其是对于音视频的解码显示功能。本文将通过编写一个实例驱动程序,同内核中的i915显卡驱动进行内存方面的交互来剖析 Linux内核中的通用子系统DMA_BUF。
DMA_BUF
需求背景
考虑这样一种场景,摄像头采集的视频数据需要送到GPU中进行编码、显示。负责数据采集和编码的模块是Linux下不同的驱动设备,将采集设备中的数据送到编码设备中 需要一种方法。最简单的方法可能就是进行一次内存拷贝,但是我们这里需要寻求一种免拷贝的通用方法。
实际的硬件环境是,采集设备是一个pciv驱动,编码设备就是i915驱动。现在就是要编写一个驱动程序,让i915驱动可以直接访问pciv中管理的视频数据内存。
概述
引入dma-buf机制的原因
之前内核中缺少一个可以让不同设备、子系统之间进行内存共享的统一机制。
混乱的共享方法:
V4L2(video for Linux)使用USERPTR的机制来处理访问来自其他设备内存的问题,这个机制需要借助于以后空间的mmap方法。
类似的,wayland和x11各自定义了客户端和主进程之间的内存共享机制,而且都没有实现不同设备间内存共享的机制。
内核中各种soc厂商的驱动、各种框架和子系统都各自实现各自的内存共享机制。
之前共享方式存在问题:
使用用户层的mmap机制实现内存共享方式太过简单粗暴,难以移植。
没有统一的内存共享的API接口。
dma_buf是一种怎样的存在
dma_buf是内核中一个独立的子系统,提供了一个让不同设备、子系统之间进行共享缓存的统一框架,这里说的缓存通常是指通过DMA方式访问的和硬件交互的内存。 比如,来自摄像头采集的通过pciv驱动传输的内存、gpu内部管理的内存等等。
其实一开始,dma_buf机制在内核中的主要运用场景是支持GPU驱动中的prime机制,但是作为内核中的通用模块,它的适用范围很广。
dma_buf子系统包含三个主要组成:
dma-buf对象,它代表的后端是一个sg_table,它暴露给应用层的接口是一个文件描述符,通过传递描述符达到了交互访问dma-buf对象,进而最终达成了 共享访问sg_table的目的。
fence对象, which provides a mechanism to signal when one device as finished access.
reservation对象, 它负责管理缓存的分享和互斥访问。.
dma-buf实现
整体构架
DMA_BUF框架下主要有两个角色对象,一个是exporter,相当于是buffer的生产者,相对应的是importer或者是user,即buffer的消费使用者。
假设驱动A想使用由驱动B产生的内存,那么我们称B为exporter,A为importer.
The exporter
实现struct dma_buf_ops中的buffer管理回调函数。
允许其他使用者通过dma_buf的sharing APIS来共享buffer。
通过struct dma_buf结构体管理buffer的分配、包装等细节工作。
决策buffer的实际后端内存的来源。
管理好scatterlist的迁移工作。
The buffer-usr
是共享buffer的使用者之一。
无需关心所用buffer是哪里以及如何产生的。
通过struct dma_buf_attachment结构体访问用于构建buffer的scatterlist,并且提供将buffer映射到自己地址空间的机制。
数据结构
struct dma_buf{
size_t size;
struct file *file; /* file pointer used for sharing buffers across,and for refcounting */
最近手里有个需求,需要做大屏适配,原本在本地展示正常的页面,放在大屏上展示就无法满屏了,在网上搜集了一点资料最终自己总结了下
首先在mounted生命周期中,监听window的变化
window.addEventListener('resize', () => { console.log('resize') this.resize() }) 然后在methods中增加resize方法
resize() { // 记录开发时候的尺寸 const width = 1550 ,height = 680 let w = window.innerWidth / width let h = window.innerHeight / height let scale = w < h ? w : h let body = document.body // 通过transform 去对body进行等比缩小 body.style.transform = 'scale(' + scale + ')' body.style.transformOrigin = '0 0' } 然后正常情况下等比的大屏就可以适配了
在通讯圈里,“高通9x07”已然是高频词汇。但9x07到底是个啥?能干啥?说白了就是低成本4G调制解调器芯片。成本优化且低功耗的蜂窝连接解决方案组合提供更大灵活性,从而广泛适应各类应用。
骁龙X5 LTE调制解调器(9x07)旨在为终端制造商、系统集成商和开发者提供更多选择,包括支持全球主要蜂窝网络的4G LTE连接,提供支持更低产品开发成本、更短集成时间和更简化设计的综合集成解决方案,同时减少对分离式处理器、微控制器和定位组件的需求,从而能够占用更少空间并进一步降低物料(BoM)成本。
骁龙X5 LTE调制解调器(9x07)优势:
•LTE FDD/TDD Category 4最高达150Mbps的下行速率和最高达50Mbps的上行速率
•DC-HSPA、GSM、TD-SCDMA和cdma2000/1x多模
•跨芯片组平台的可扩展软件
•先进的内置软硬件安全特性
•支持VoLTE和SRLTE
•集成1.2GHz ARM Cortex A7 应用处理器
•面向应用开发的Linux OS
•集成GPS、北斗、格洛纳斯(Glonass)和伽利略(Galileo)定位支持
•28纳米LP小型封装,支持优化的外形设计
MDM9207-1具有平台兼容属性,支持针对更低数据传输和功耗需求应用的LTE Category 1多模连接,例如智能仪表、安保、资产追踪、可穿戴设备、零售终端和工业自动化。MDM9207-1可满足物联网需求,仅用2节5号(AA)电池即可支持最长10年续航。
9x07平台产品有包括龙尚科技的U9507系列和U9300系列无线通信模块。
1、开篇 低功耗蓝牙的概念以及低功耗蓝牙为什么能做到低功耗,蓝牙基础知识概述经典蓝牙和低功耗蓝牙的区别中就可以看出来了,这里就不多说了。本篇文章主要介绍BLE应用层开发中常见的一些概念以及BLE广播包的格式。
2、相关名词解析 BLE应用开发过程中,我们常常会看到以下一些名词,很多人不知道它们是什么,这里说说我自己的理解。如果读者暂时不能理解以下概念,也没关系,可以看看后面的Android BLE开发实战相关的文章。后续的文章如果看懂了,这些不懂也问题不大。反正我的理解也不一定对~
2.1 主机和从机 主机和从机是相对的概念,又可以称为主设备和从设备、外围设备(Peripheral)和中心设备(Central)、中心和外设等等。举个简单的例子,我们在使用手机搜索、连接和控制家里的BLE设备的时候,我们的手机就是主机,设备就是从机。一个主机可以同时连接多个从机,一个从机同一时间只能被一个主机连接。
2.2 GAP GAP是Generic Access Profile的缩写,中文译为通用访问配置文件,主机和从机就是它定义的。GAP不仅定义了蓝牙通信的角色,还控制着它们的广播和连接。需要注意的是,某些设备可以配置成只发送广播而不支持连接,比如一些Beacon设备。
2.3 GATT GATT是Generic Attribute Profile的缩写,中文译为通用属性配置。
我们使用BLE的时候,主机和从机建立的连接通常称为GATT连接。GATT也给BLE设备定义了角色,GATT Server和GATT Client。通常情况下,主机就是Client,从机就是Server。这是一个C/S架构,主机向从机请求服务。GATT中还有两个尤其重要的概念,Service和Characteristic,一个Service包含多个Characteristic。BLE主从设备之间通信多数情况下就是对特定Service里的特定的Characteristic进行读写操作。每个Service和Characteristic都有一个唯一的UUID与之对应。在开发BLE应用和智能硬件时,两端的开发者需要协商好对应的UUID。
2.4 ATT ATT是Attribute Protocol,也就是属性协议。它是GATT的下层协议,它把设备的数据定义为一个个的属性,而Service和Characteristic是对属性的逻辑封装。
3、BLE广播包 介绍蓝牙广播包之前先介绍一种LTV数据格式。LTV是Length-Type-Value的缩写,它表示在一个字节数组或者字节流中,数据按照Length -> Type -> Value的顺序拍布。比如数组元素如下(十六进制):
0201060303F1FE 这里包含两组数据:020106和0303F1FE。02作为开始,代表此项数据有两个字节,01代表此项数据的类型,06是此项数据的值。0303F1FE同理。
与LTV类似的数据格式还有TLV,也就是Type-length-Value。
BLE广播包是一个最大有31个字节的数据包,它按LTV格式可以包含多个数据项。接下来介绍几个非常常用的数据类型:
Flags,广播标记位,Type为0x01,Value为一个字节,每个比特位表示设备的一个特性:
bit 0: 是否有限发现模式bit 1: 是否普通发现模式bit 2: 是否不支持 BR/EDRbit 3: 是否对 Same Device Capable(Controller) 同时支持 BLE 和 BR/EDRbit 4: 是否对 Same Device Capable(Host) 同时支持 BLE 和 BR/EDRbit 5…7: 预留 Service UUID:Service UUID有好多种,完整和不完整的16位、32位和128位UUID。其中最常用的是完整的16位UUID。UUID本身应该是128位的,但是我们可以约定只有其中16位不同,其他的112位都一样,那么我们就可以使用16位来表示一个UUID了,通过扩展即可得到128位UUID。完整的16位UUID对应的Type是0x03。
设备名称:Type 0x08和0x09分别是设备简称和全称的Type。
使用百问网IMX6ULL开发板网络启动时程序一直卡在DHCP那里,分析后发现在网络启动那里的bootargs参数里ip=dhcp,而此时开发板未连接路由器,是通过交换机和电脑连接的,此时要设置静态IP,使用以下命令,将IP这个参数映射到clinetip这个参数,并设置clinetip参数为静态IP。
setenv netargs 'setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=${clinetip} nfsroot=${serverip}:${nfsroot},v3,tcp'
setenv clinetip '192.168.2.30:192.168.2.20:192.168.2.1:255.255.255.0::eth0:off'
注:
ip参数的格式为 ip=::::::
client-ip: 你正在使用的这块板子,你要为它设置的ip
server-ip: 提供nfs服务的服务器的ip地址。如不需要NFS服务于板子,则此项可以空置
gw-ip: 网关的ip地址,如果nfs与目标板在同一个网段内,则此项可以空置
netmask: 子网掩码,如此项为空,则子网掩码为默认值255.255.255.0
hostname: 你希望给目标板设置的主机名,在linux的shell中的如bash,命令行最开始有一个形如 blacksword@laptop:~ $ 这样的一个提示符,blacksword指当前的用户,而laptop就是一个hostname. 此项可以留空
device: 如果目标板上仅一个网卡,且只接了一个PHY,同时电路的设计没有将PHY拉出两个地址来,则此项为空。 如果不指有一个网卡,则可以指定要设置的ip地址是作用于哪一个网卡的。 如指定给第一块网卡,则该参数为eth0. 第二块为eth1,依此类推。
autoconf:
自动配置未明确指定参数的方式,可以是dhcp, rarp, bootp。如果不希望使用自动配置则可以使用off值来关闭 autoconf参数可以独立作用于ip参数,如ip=dhcp即表示由dhcp服务器给内核的ip参数提供所有数据。 ip=off则表示所有参数都不配置,留待系统启动进行配置。
死机是我们使用电脑时经常会遇到的、也是最令我们头痛的问题,而最近就有很多小伙伴反映firefox火狐浏览器卡死导致死机,遇到这种情况我们具体该怎么解决呢?下面就由学习啦小编跟大家分享一下解决方法吧,欢迎大家来阅读学习。
firefox火狐浏览器卡死导致死机解决方法
有时用着用着有可能是网络的问题还有可能是开的签页太多或是电脑配置太底firefox火狐浏览器在运行时就突然停止工作了,这时你发现点关闭按钮已是于事无补,怎么办才好呢,我们的电脑有于某些程序还在开启状态,关机重启太不方便了......其实方法很简单,我们接着往下看
我们选择“开始”→“控制面板”打开控制面板窗口
在“控件面板”打开的控制面板窗口中选择查看方式为“大图标”
我们在这里找到“性能信息和功能”点击进入在左侧点击“高级工具”
在打开的“高级工具”窗口中选择“打开资源监视器”打开
在“资源监视器”窗口中选中“CUP”选项卡在“搜索句柄”文本框中输入“firefox”点击后面的搜索按钮
在下面的关联句柄中选中关于本程序的所有进程点击右键选择“结束进程”,就会看到firefox火狐的窗口被强制性的关闭,然后重新打开浏览器即可
笔记来源:尚硅谷Web前端HTML5&CSS3初学者零基础入门全套完整版
文章目录 前端简介1. 软件的分类1.1. 系统软件1.2. 应用软件1.3. 游戏软件 2. 客户端与服务器2.1. 服务器2.2. 客户端 3. 网页的特点4. 网页简史5. 浏览器和网页5.1. 浏览器的问题5.2. W3C的建立5.3. 网页的结构思想结构、表现、行为 6. 网页的基本结构6.1. 迭代6.2. 文档声明(doctype)6.3. 字符编码编码解码字符集(charset)乱码 6.4. 常见的字符集ASCIIISO-8859-1GB2312GBKBig5UTF-8UTF-16Unicode 6.5. HTML5的基本结构 前端简介 1. 软件的分类 1.1. 系统软件 WindowsLinuxmacOS 1.2. 应用软件 OfficeQQ 1.3. 游戏软件 绝地求生王者荣耀 2. 客户端与服务器 通常情况下,现在的软件一般由两个部分组成:
客户端:用户通过客户端来使用软件。服务器:服务器负责在远程处理业务逻辑。 2.1. 服务器 服务器开发的语言:
JavaPHPC#PythonNode.js…… 2.2. 客户端 客户端的形式
文字客户端:占老的方式,通过命令行来使用软件图形化界面:通过点击拖动等来使用软件。Windows中、macOS中、Android、iOS中的大部分应用。(C/S架构)网页:通过访问网页来使用软件。所有的网站都属于这个范畴。(B/S架构) 3. 网页的特点 相较于传统的图形化界面,网页具有如下一些优点:
不需要安装无需更新跨平台 网页中使用的语言:
HTML、CSS、JavaScript 4. 网页简史 蒂姆·伯纳斯·李爵士,万维网的发明人。
1991年8月6日,世界上第一个服务器和第一个网站在欧洲核子研究中心上线。
第一个网站:http://info.cern.ch/hypertext/WWW/TheProject.html
5. 浏览器和网页 有了浏览器我们只需要一个网址便可以访问任何的网站。
而浏览器中所显示的内容正是我们所说的网页。
网页原本的样子:
... <!--无障碍占位--> <div id="
简 介: 初步测试了一款非常简单的语音模块。使用ESP32的串口作为控制模块发声的控制器。在测试过程中出现读音错误的情况,具体原因还需要之后进一步进行查找。
关键词: TTS,ESP32,声音模块
§01 中文文字转语音 最初是为了支持学生制作一款他们的设计作品,需要设计到语音合成的目标板。现在从 TB购买到一款模块 ,准备进行测试。下面就是购买到的中文TTS文字转语音合成模块。
▲ 购买到的中文TTS文字转语音合成模块 1.开发资料 开发资料: 百度网盘下载了解: https://pan.baidu.com/s/1z2nrEr-MvIl9ZdkbGG1ZUQ 提取码:pa29 2.板上主要芯片 在语音模块内部的电路板上,主要有三个集成芯片。
集成芯片信息: MX25L6445: MX25L6446 3V,64Mb 串口Flash XS8002D: XS8002D 是一款带有自关断的音频IC。( 已经停产) SSOP20:表面打磨的芯片,型号不详。估计是一颗MCU。 ▲ 语音模块内聚结构以及外部接口 3.接口功能定义 【表1-1 对外接口颜色功能】 引线PIN1PIN2PIN3PIN4颜色红黄白黑功能+5VRXTXGND ▲ 内部对外接口连线的颜色 为了便于对TTS模块进行测试,将它原来的接口焊接成PIN100mil的接口。它的定义如下图所示。
▲ 外部新的接口功能定义 ▲ TTS模块功能定义 连接TTS与控制器的UART之间的方法如下图所示:
▲ TTS模块与控制串口的连接方式 串口通信协议: 波特率:9600bps 起始位:1bit 数据位:8bits 停止位:1bits 校验:无 §02 测试模块功能 1.UART接口平台 使用 ESP32-S 转接板 的接口来调试TTS模块。在PIN19,20分别定义了ESP32的UART2(PIN19-RXD2, PIN20-TXD2)。下面通过基础实验来测试ESP32-PIN19,20的基本功能。
▲ 实验ESP32测试版 (1)ESP32-UART 管脚 根据 MicroPython 中ESP32 UART模块 ,ESP32模块对应的GPIO管脚表格:
▲ ESP32 UART端口 使用UART2 对于 TTS模块进行控制。
Git 拥有一个经过精心设计的模型,这使其能够支持版本控制所需的所有特性,例如维护历史记录、支持分支和促进协作。然而,通过自顶向下的方式(从命令行接口开始)学习 Git 可能会让人感到非常困惑。一旦出现问题,就只能将当前工作保存下来,然后重新复制一份工作,继续进行处理了。如果我们能够先对其底层的数据结构有所了解,在接触命令行接口时,就会更加得心应手。
快照 Git 将顶级目录中的文件和文件夹作为集合,并通过一系列快照来管理其历史记录。在 Git 的术语里,文件被称作 Blob对象(数据对象),也就是一组数据。目录则被称之为“树”,它将名字与 Blob 对象或树对象进行映射(使得目录中可以包含其他目录)。快照则是被追踪的最顶层的树,快照也被称为提交(commit)。
历史记录建模:关联快照 在 Git 中,历史记录是一个由快照组成的有向无环图。每个快照都有一系列的“父辈”,也就是其之前的一系列快照。注意,快照可能同时有多个“父辈”,例如,经过合并后的两条分支。
o <-- o <-- o <-- o <---- o ^ / \ v --- o <-- o 数据模型及其伪代码表示 通过伪代码的表示,能够更加清晰的了解 Git 的数据模型。
// 文件就是一组数据 type blob = array<byte> // 一个包含文件和目录的目录 type tree = map<string, tree | blob> // 每个提交都包含一个父辈,元数据和顶层树 type commit = struct { parent: array<commit> author: string message: string snapshot: tree } 对象和内存寻址 Git 中的对象可以是 blob、树或提交:type object = blob | tree | commit,所有的对象都会通过 SHA-1 哈希进行寻址。
文章目录 Google play重签名问题统一签名参考 Google play重签名问题 第一次上架google play应用,如果选择了google play提供的签名方式,会在你的应用上架到google play时候用它的签名帮应用重新签名,会造成从google play下载的应用包签名和其他平台下载的应用包签名不同。
由于微信登录等第三方登录功能,需要上传唯一的包签名,也就是只有一个包可以使用微信登录。如果不把google play的重签名改成自有的签名文件,在google play下载的应用就无法使用第三方登录功能。
以下给出解决方法
统一签名 在这里可以看到应用的重签名,和自己的签名文件信息不同,现在要改成跟自己的签名信息相同。
如果替换应用签名秘钥,google将使用新的秘钥来为所有以后新安装的应用及其更新签名。对于之前已安装该应用的用户,应用更新仍将使用您的旧版秘钥来签名。针对每个应用,您只能请求一次新秘钥。
参考 关于Google Play app signing的坑 以及最终完美解决方式(替换自己的签名)GooglePlay重签名引发的第三方失效,统一解决有效上传应用至Google Play 后被重新签名,怎么获取最新的签名信息
环境:Ubuntu18.04-amd64 问题描述:在ubuntu下安装mysql时,进行apt-get操作,出现了如下报错: 参考了一篇博客,已经解决问题。现将步骤记录下来。 解决办法: 第一种情况:
进程中存在与apt相关的正在运行的进程:
首先检查是否在运行apt,apt-get相关的进程 ps aux | grep -i apt 如果存在与apt相关的正在运行的进程,kill掉进程;
sudo kill -9 <process id> 或者直接简单粗暴的:
sudo killall apt apt-get 如果进行完上面的步骤还是无法顺利执行apt-get 操作,则属于第二种情况:
第二种情况:
进程列表中已经没有与apt,apt-get相关的进程在运行,但依然报错,在这种情况下,产生错误的根本原因是lock file。 lock file用于防止两个或多个进程使用相同的数据。 当运行apt或apt-commands时,它会在几个地方创建lock files。 当前一个apt命令未正确终止时,lock file未被删除,因此它们会阻止任何新的apt / apt-get命令实例,比如正在执行apt-get upgrade,在执行过程中直接ctrl+c取消了该操作,很有可能就会造成这种情况。
要解决此问题,首先要删除lock file。 使用lsof命令获取持有lock file的进程的进程ID,依次运行如下命令: lsof /var/ lib/dpkg/lock lsof /var/ lib/apt/lists/lock lsof /var/cache/apt/archives/lock 需要注意的是,以上命令执行结果如果无返回,说明没有正在运行的进程;如果返回了相应的进程,需要kill掉。
删除所有的lock file sudo rm /var/ lib/apt/lists/lock sudo rm /var/cache/apt/archives/lock sudo rm /var/ lib/dpkg/lock 最后重新配置一下dpkg:
sudo dpkg --configure -a 如果上述命令不出任何错误,就万事大吉了。(我是到这里问题就解决了)
postgres删除大量数据 当数据库在有约束的情况下,无论进行删除或者更新操作,都会对相关表进行一个校验,判断相关表的相关记录是否被删除或者更新。
在删除大量数据时,可以先禁用触发器,然后再进行删除。最后再优化一下表空间
1.禁用触发器
ALTER TABLE table_name DISABLE TRIGGER ALL;
2.DELETE
DELETE FROM table_name WHERE ...
3.启用触发器
ALTER TABLE table_name ENABLE TRIGGER ALL;
4.优化表空间, 维护数据库磁盘,释放空间
VACUUM FULL table_name;
5.重建索引,替换查询效率
REINDEX TABLE table_name;
如果是直接清空数据的话。使用 TRUNCATE TABLE table_name; 但试过清空一个200G的数据库,一天没反应。。
基本命令 进入数据量
psql --help查询单个数据库大小
select pg_size_pretty(pg_database_size('postgres')) as size;查询所有数据库大小
select datname, pg_size_pretty (pg_database_size(datname)) AS size from pg_database;查询单个表大小
select pg_size_pretty(pg_relation_size('mytab')) as size;查询所有表大小
select relname, pg_size_pretty(pg_relation_size(relid)) as size from pg_stat_user_tables;查询单个表的总大小,包括该表的索引大小
select pg_size_pretty(pg_total_relation_size('tab')) as size;查询所有表的总大小,包括其索引大小
select relname, pg_size_pretty(pg_total_relation_size(relid)) as size from pg_stat_user_tables;查询单个索引大小
出现这个错误 :ValueError: invalid literal for int() with base 10: '' "
或者: ValueError: invalid literal for int() with base 10: '0x1388'
出现这样的错误基本是一类问题,就是转int 类型的时候出现了错误
例如遍历一个list ,把list 里面的内容转int 类型
list_a = ["1", "2", "", "3", "0x1388", "4"] for i in list_a: print int(i) 代码运行会出现这个错误 :ValueError: invalid literal for int() with base 10: '' "
因为里面有空字符串,所以你的检查下是存在,“” 或者存在空格这样的
list_a = ["1", "2", "5", "3", "0x1388", "4"] for i in list_a: print int(i) 代码运行会出现这个错误 :ValueError: invalid literal for int() with base 10: '0x1388'
本文转载自 https://blog.csdn.net/qq_23981335/article/details/106572171
仅作记录学习~
总结 BN,LN,IN,GN,WS 从学术上解释差异:
BatchNorm:batch方向做归一化,算NHW的均值,对小batchsize效果不好;BN主要缺点是对batchsize的大小比较敏感,由于每次计算均值和方差是在一个batch上,所以如果batchsize太小,则计算的均值、方差不足以代表整个数据分布;LayerNorm:channel方向做归一化,算CHW的均值,主要对RNN作用明显;InstanceNorm:一个channel内做归一化,算H*W的均值,用在风格化迁移;因为在图像风格化中,生成结果主要依赖于某个图像实例,所以对整个batch归一化不适合图像风格化中,因而对HW做归一化。可以加速模型收敛,并且保持每个图像实例之间的独立。GroupNorm:将channel方向分group,然后每个group内做归一化,算(C//G)HW的均值;这样与batchsize无关,不受其约束。SwitchableNorm:将BN、LN、IN结合,赋予权重,让网络自己去学习归一化层应该使用什么方法。Weight Standardization:权重标准化,2019年约翰霍普金斯大学研究人员提出。 详细阐述 1. BatchNorm torch.nn.BatchNorm1d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) torch.nn.BatchNorm3d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True) 参数:
num_features: 来自期望输入的特征数,该期望输入的大小为’batch_size × num_features [× width]’eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。momentum: 动态均值和动态方差所使用的动量。默认为0.1。 affine: 布尔值,当设为true,给该层添加可学习的仿射变换参数。track_running_stats:布尔值,当设为true,记录训练过程中的均值和方差; 公式:
大部分深度网络通常都会使用 BN 层去加速训练和帮助模型更好收敛。虽然 BN 层非常实用,但从研究者的角度看,依然有一些非常显眼的缺点。比如
(1)我们非常缺乏对于 BN 层成功原因的理解;
(2)BN 层仅在 batch size 足够大时才有明显的效果,因此不能用在微批次的训练中。虽然现在已经有专门针对微批次训练设计的归一化方法(GN),但图 1 所示,它很难在大批次训练时媲美 BN 的效果。
2. GroupNorm FAIR 团队的吴育昕和何恺明提出了组归一化(Group Normalization,简称 GN)的方法,GN 将信号通道分成一个个组别,并在每个组别内计算归一化的均值和方差,以进行归一化处理。GN 的计算与批量大小无关,而且在批次大小大幅变化时,精度依然稳定。通常来说,在使用 Batch Normalization(以下将简称 BN)时,采用小批次很难训练一个网络,而对于不使用批次的优化方法来说,效果很难媲美采用大批次BN时的训练结果。当使用 Group Normalization(以下将简称 GN),且 batch size 大小为 1 时,仅需要多写两行代码加入权重标准化方法,就能比肩甚至超越大批次BN时的训练效果。
DML用于对表中的记录进行增删改操作。
插入操作
#into可省略 insert into 表名 values(列的值);#插入所有列 insert into 表名 (列名)values(列的值);#插入指定列 insert into 表名 values(列的值),(列的值),(列的值);#增加多行 删除操作
-- 物理删除 此种方法不保留数据。 delete from 表名 ;#不带条件删除表值,即删除表的所有值。 delete from 表名 where 列名1=值1and列名2=值2;#带条件删除表值 delete from 表名 where 列名1=值1or列名2=值2;#带条件删除表值 #使用delete删除表的所有数据 ,但是主键自增记录还在 #使用truncate删除表的所有数据 ,将主键自增记录重置 truncate table 表名; -- 逻辑删除 即修改列的数值,例如定义1为未删除,2为删除。此种方法可保留数据。 update stu set 列名=2 where 列名2=值2; 修改操作
#修改所有行 update 表名 set 列名=值; #修改指定行 update 表名 set 列名=值 where 列名=值;
地址线一次确定一个存储单元,地址线上值可能取的所有组合确定了存储单元的个数,所以,存储单元的个数=2^n个内存单元;而数据线16根,表明通过数据线每次可以传送16位。
关于Ping和Tracert的一些总结 Ping与Tracert命令都是基于ICMP协议的,在实验过程中发现本机ping不通校园网网关,应该是禁ping的原因,但使用tracert工具却能到达,很是不解。既然都是基于icmp的,校园网服务器禁icmp协议的话,理论上tracert命令也用不了。
于是便去了解了一下两者处理过程上的区别:
ping时发出的报文类型为echo,类型码为8,回应报文的类型为echo-reply,类型码为0
tracert时,发出的报文类型和ping相同(但ttl值不同);返回的icmp报文类型为ttl-exceeded, 类型码为 Type=11
可参考如下acl
acl number 3000 rule 5 permit icmp icmp-type echo rule 10 permit icmp icmp-type echo-reply rule 15 deny icmp icmp-type ttl-exceeded 根因
Tracert和ping都是通过icmp协议来实现的,但他们的icmp类型不一样,可以使用参数icmp-type 进行区别
这样就说明我的校园网仅仅禁ping但并未禁tracert。
根据网上搜集到的资料,个人理解为Tracert根据路由表
中的路由信息来走一遍网络(如果之前使用过Tracert跟踪过同一个目标,不管目标在不在线都能tra)。
而当设备关机或者开启防火墙或者禁ping是不能ping通的。
总结就是tracert 是告诉你到达目的的路是这么走的.Ping 告诉你目的地是不是正常.那是另一回事.
eg:就像你去北京. 地图告诉你怎么走. 至于目的地是不是让你通过.查不查你的进京证. 外地车辆是不是允许你进去这另一回事.
大家好,我是 Jack。
小时候,我其实还是有点艺术细胞的,喜欢看火影忍者和七龙珠的我,虽然没学过绘画,但也笨手笨脚地画了不少作品。
特意叫我妈,把我收藏多年的小破本拿出来,分享下我儿时的快乐。
小学几年级画的记不清了,只记得一画就是小半天,还拿去学校显摆了一番。
如今,再让我拿起铅笔,画个素描,我是画不出来了。
不过,我另辟蹊径,用起了算法。我lbw,没有开挂!
Anime2Sketch Anime2Sketch 是一个动画、漫画、插画等艺术作品的素描提取器。
给我个艺术作品,我直接把它变成素描作品:
耗时1秒临摹的素描作品:
Anime2Sketch 算法也非常简单,就是一个 UNet 结构,生成素描作品,可以看下它的网络结构:
import torch import torch.nn as nn import functools class UnetGenerator(nn.Module): """Create a Unet-based generator""" def __init__(self, input_nc, output_nc, num_downs, ngf=64, norm_layer=nn.BatchNorm2d, use_dropout=False): """Construct a Unet generator Parameters: input_nc (int) -- the number of channels in input images output_nc (int) -- the number of channels in output images num_downs (int) -- the number of downsamplings in UNet.
用AI算法玩起了素描 大家好,我是 python朵朵
小时候,我其实还是有点艺术细胞的,喜欢看火影忍者和七龙珠的我,虽然没学过绘画,但也笨手笨脚地画了不少作品。
特意叫我妈,把我收藏多年的小破本拿出来,分享下我儿时的快乐。
小学几年级画的记不清了,只记得一画就是小半天,还拿去学校显摆了一番。
结果不少小朋友说是印着画描出来的,当时还因此,闹了不愉快。
小孩子爱展示的心理,没得到满足,现在想想,还挺好笑。
如今,再让我拿起铅笔,画个素描,我是画不出来了。
不过,我另辟蹊径,用起了算法。我lbw,没有开挂!
Anime2Sketch Anime2Sketch 是一个动画、漫画、插画等艺术作品的素描提取器。
给我个艺术作品,我直接把它变成素描作品:
耗时1秒临摹的素描作品:
Anime2Sketch 算法也非常简单,就是一个 UNet 结构,生成素描作品。
UNet 应该都很熟悉了,就不多介绍了。
项目地址:https://github.com/Mukosame/Anime2Sketch
环境部署也很简单,只需要安装以下三个库:
1
2
3
4
torch>=<span class="hljs-number">0.4</span><span class="hljs-number">.1</span>
torchvision>=<span class="hljs-number">0.2</span><span class="hljs-number">.1</span>
Pillow>=<span class="hljs-number">6.0</span><span class="hljs-number">.0</span>
然后下载权重文件,即可。
权重文件放在了GoogleDrive,为了方便大家,我将代码和权重文件,还有一些测试图片,都打包好了。
直接下载,即可运行(提取码:a7r4):
https://pan.baidu.com/s/1h6bqgphqUUjj4fz61Y9HCA
进入项目根目录,直接运行命令:
1
2
python3 test.py --dataroot test_samples --load_size 512 --output_dir results
运行效果:
“画”得非常快,我在网上找了一些图片进行测试。
鸣人和带土:
柯南和灰原哀
絮叨 使用算法前:
这样的素描,没有灵魂!
使用算法后
拿了一些真人的图片进行了测试,发现效果很差,果然真人的线条还是要复杂一些的。
Leecode刷题常用函数 1.accumulate
定义在#include中,作用:累加求和
accumulate带有三个形参:头两个形参指定要累加的元素范围,第三个形参则是累加的初值。
int sum = accumulate(vec.begin() , vec.end() , 42); 2,sort 排序+Lambda表达式
sort(intervals.begin(), intervals.end(), [](vector<int> a, vector<int> b) { return a[1] < b[1]; 3.哈希表写法
unordered_map <key, value> ori 遍历:
for(const auto &p:sin) { if(cur[p.first]<p.second) { //return false; } } 4.compare
C++string的compare()比较函数
两个字符串相同,返回0。 调用字符串小与被调用字符串,返回-1。 调用字符串大于被调用字符串,返回1。 字符串说的大小通常和字典顺序是一致的。 字符串小的在字典里靠前,字符串大的在字典里靠后。即返回值是-1的话,调用字符串比被调用字符串靠前;返回值是1的话,调用字符串比被调用字符串靠后。
compare()比较时逐字符比较的,一旦能比较出结果,就不再比较了。 例如“abc”和“adf”,首先a和a比较,比不出结果;则b和d比较,结果就是“abc”小于“adf”,返回-1,即字典里“abc”在“adf”前面。例如“abc”和“abcd”比较,若“abc”都比完了,“abcd”还没完,说明“abc”小,返回值为-1,字典里“abc”靠前。总之记住这个比较规则和字典顺序一致即可.
5.size()和length()
对于.length()和.size(),其实是没有区别的,是因为容器都含有.size()方法,但是对于string类来说,.length()更加直观,所以新加了这个函数,但是其实他俩相当于是同义词。
5.哈希表排序写法
我们首先假设我们要操作的map、unordered_map对象是m。
第一种做法是先建立一个vector<pair<type, type>>的容器。
std::vector<std::pair<int, int>> tmp; for (auto& i : m) tmp.push_back(i); std::sort(tmp.begin(), tmp.end(), [=](std::pair<int, int>& a, std::pair<int, int>& b) { return a.
自己根据go-zero单体框架实现的一个精简版框架https://github.com/wanmei002/go-zero-learn, 新手直接看go-zero 框架可能会绕,看这个好理解
框架运行起来 先说下思路:
注册必要的中间件给每个路由处理函数用中间件处理给路由生成字典树开始监听端口 启动入口 入口函数 server.Start() ,实际上运行的是 Server.opts.start。
在 go-zero/rest/engine.go 文件中的 bindRoute 方法, 这个里面注册了中间件,
并对路由处理函数用中间件处理。中间件原理请看这篇文章
```go func (c Chain) Then(h http.Handler) http.Handler { if h == nil { h = http.DefaultServeMux } for i := range c.constructors { h = c.constructors[len(c.constructors)-1-i](h)// 倒序运行中间件 } return h } ``` 和开始生成路由字典树,具体文章看这里go-zero 单体应用框架学习—3 路由生成字典树。
开始监听端口:
func (s *engine) StartWithRouter(router httpx.Router) error { if err := s.bindRoutes(router); err != nil { return err } if len(s.
目录
ubuntu 18.04 按计划执行,设置步骤如下
1、配置 crontab 文件
2、开启crontab 日志记录
3、测试是否生效
ubuntu 18.04 按计划执行,设置步骤如下 在Ubuntu中按计划执行网上给出了两种按计划执行的方法
修改/etc/crontab这种方法只有root用户能用,这种方法更加方便与直接直接给其他用户设置计划任务,而且还可以指定执行shell等等crontab -e这种所有用户都可以使用,普通用户也只能为自己设置计划任务。然后自动写入/var/spool/cron/usename 不知道什么原因我在使用crontab -e 执行后添加了按计划执行的语句后却没有生效。 修改 /etc/crontab 成功了。介意切换到root 用户下执行下面语句。
1、配置 crontab 文件 命令:sudo vim /etc/crontab
设置好自己需要执行的脚本,或者文件时间,设置完成后保存。(为了测试,我这里设置的是每分钟执行一次脚本)
重启服务
命令:sudo service cron restart #重启按计划执行crontab 解析:
在 /etc/crontab 下一共有五个字段,分别为:
* * * * * user-name command to be executeb
分 时 天 月 周 用户名 需要执行的命令
分 :取值范围在0~59 时 :取值范围在0~23
天 :取值范围在1~31
月 :取值范围在1~12
周 :取值范围在(0~6)或(1~7),其中0或者7表示星期日,1~6表示星期一道星期六
注: sudo service cron stop #关闭按计划执行crontab
管道模式(Pipeline Pattern) 是责任链模式(Chain of Responsibility Pattern)的常用变体之一。在管道模式中,管道扮演着流水线的角色,将数据传递到一个加工处理序列中,数据在每个步骤中被加工处理后,传递到下一个步骤进行加工处理,直到全部步骤处理完毕。
PS:纯的责任链模式在链上只会有一个处理器用于处理数据,而管道模式上多个处理器都会处理数据。
何时使用管道模式 任务代码较为复杂,需要拆分为多个子步骤时,尤其是后续可能在任意位置添加新的子步骤、删除旧的子步骤、交换子步骤顺序,可以考虑使用管道模式。
愉快地使用管道模式 背景回放 最开始做模型平台的时候,创建模型实例的功能,包括:“输入数据校验 -> 根据输入创建模型实例 -> 保存模型实例到相关 DB 表”总共三个步骤,也不算复杂,所以当时的代码大概是这样的:
public class ModelServiceImpl implements ModelService { /** * 提交模型(构建模型实例) */ public CommonReponse<Long> buildModelInstance(InstanceBuildRequest request) { // 输入数据校验 validateInput(request); // 根据输入创建模型实例 ModelInstance instance = createModelInstance(request); // 保存实例到相关 DB 表 saveInstance(instance); } } 然而没有过多久,我们发现表单输入数据的格式并不完全符合模型的输入要求,于是我们要加入 “表单数据的预处理”。这功能还没动手呢,又有业务方提出自己也存在需要对数据进行处理的情况(比如根据商家的表单输入,生成一些其他业务数据作为模型输入)。
所以在 “输入数据校验” 之后,还需要加入 “表单输入输出预处理” 和 “业务方自定义数据处理(可选)”。这个时候我就面临一个选择:是否继续通过在 buildModelInstance 中加入新的方法来实现这些新的处理步骤?好处就是可以当下偷懒,但是坏处呢:
ModelService 应该只用来接收 HSF 请求,而不应该承载业务逻辑,如果将 提交模型 的逻辑都写在这个类当中,违反了 单一职责,而且后面会导致 类代码爆炸。将来每加入一个新的处理步骤或者删除某个步骤,我就要修改 buildModelInstance 这个本应该非常内聚的方法,违反了 开闭原则。 所以,为了不给以后的自己挖坑,我觉得要思考一个万全的方案。这个时候,我小脑袋花开始飞转,突然闪过了 Netty 中的 ChannelPipeline —— 对哦,管道模式,不就正是我需要的嘛!
在linux的socket编程中,经常要处理EINTR错误,其值为4,用strerror(errno)调用返回的错误描述为:Interrupted
system call. 这里给出一个connect连接中对EINTR处理的网址:
另外转载网络上其他兄弟对EINTR错误的处理:
1.
accetp()是慢系统调用,在信号产生时会中断其调用并将errno变量设置为EINTR,此时应重新调用accept()。所以使用时应这样:(网址:)
while(1)
{
if ((connfd = accept(....)) == -1)
{
if (errno == EINTR)
{
continue;
}
perror("accept()");
exit(1);
}
//do something with the connfd
......;
}
2. 引用网址 ,其中摘引一段socket的读处理,我把排版做了相应改动:
int my_read(int fd,
void *buffer, int length)
{
int bytes_left;
int bytes_read;
char *ptr = NULL;
bytes_left = length;
while (bytes_left > 0)
{
bytes_read = read(fd, ptr, bytes_read);
if (bytes_read < 0)
为了防止LaTeX模板中,中文宋体加粗被覆盖为黑体,可以
在documentclass中这是字体类别为fanfol
\ifXMU@istwoside \LoadClass[zihao=-4,a4paper,twoside,openright,UTF8,space=auto,fontset=fandol]{ctexbook} \else \LoadClass[zihao=-4,a4paper,oneside,openany,UTF8,space=auto,fontset=fandol]{ctexbook} \fi 但是出现中文逗号为半角问题。
头文件不变
\ifXMU@istwoside \LoadClass[zihao=-4,a4paper,twoside,openright,UTF8,space=auto]{ctexbook} \else \LoadClass[zihao=-4,a4paper,oneside,openany,UTF8,space=auto]{ctexbook} \fi 可单独字体设置:
\newCJKfontfamily\sonti{SimSun}[BoldFont=FandolSong-Bold] \setCJKmainfont{SimSun}[BoldFont=FandolSong-Bold]
1.到Bochs官方下载源码包,因为用到了调试功能。 Bochs 2.4.5下载地址 http://sourceforge.net/projects/bochs/
2.安装G++编译器
sudo apt-get install g++
如果不安装G++编译器, 在执行configure时就会出现一些错误。
3.执行配置,开启调试和反汇编
./configure --enable-debugger --enable-disasm
4.ERROR: X windows gui was selected, but X windows libraries were not found.
出现这个错误时,请安装xorg-dev包
sudo apt-get install xorg-dev
5.Package gtk+-2.0 was not found in the pkg-config search path.Perhaps you should add the directory containing `gtk+-2.0.pc'to the PKG_CONFIG_PATH environment variableNo package 'gtk+-2.0' foundERROR: pkg-config was not found, or unable to access the gtk+-2.0 package.Install pkg-config and the gtk+ development package,or disable the gui debugger, or the wxWidgets display library (whichever is being used).
一、导入键盘事件
1.导入语句
想使用selenium中的键盘事件,首先我们必须导入Keys包,需要注意的是包名称Keys首字母需要大写。Keys类中提供了几乎所有的键盘事件包括组合按键如 Ctrl+A、 Ctrl+C 等。
from selenium.webdriver.common.keys import Keys 2.键盘事件
下面是一些常用的键盘事件:
Keys.BACK_SPACE # 回退键(BackSpace) Keys.TAB # 制表键(Tab) Keys.ENTER # 回车键(Enter) Keys.SHIFT # 大小写转换键(Shift) Keys.CONTROL # Control键(Ctrl) Keys.ALT # ALT键(Alt) Keys.ESCAPE # 返回键(Esc) Keys.SPACE # 空格键(Space) Keys.PAGE_UP # 翻页键上(Page Up) Keys.PAGE_DOWN # 翻页键下(Page Down) Keys.END # 行尾键(End) Keys.HOME # 行首键(Home) Keys.LEFT # 方向键左(Left) Keys.UP # 方向键上(Up) Keys.RIGHT # 方向键右(Right) Keys.DOWN # 方向键下(Down) Keys.INSERT # 插入键(Insert) DELETE # 删除键(Delete) NUMPAD0 ~ NUMPAD9 # 数字键1-9 Keys.
环境:
AIX:192.168.1.235
Centos:192.168.1.121
一、修改配置文件
配置文件路径:/etc/ssh/sshd_config
修改如下内容:
#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile .ssh/authorized_keys
将其注释全部取消
二、生成密钥对
命令:ssh-keygen
在~/.ssh目录下生成了id_rsa id_rsa.pub两个文件
其中id_rsa.pub即为本机公钥,需要将其复制到远程主机上
三、复制密钥
命令:scp id_rsa.pub 主机IP:~/.ssh/hostname.pub
在AIX上:scp id_rsa.pub 192.168.1.121:~/.ssh/aix.pub
在Centos上:scp id_rsa.pub 192.168.1.235:~/.ssh/centos.pub
四、将公钥追加进authorized_keys文件
在./ssh下创建一个文件authorized_keys
将对方公钥追加进该文件
AIX上:touch authorized_keys
cat centos.pub > authorized_keys
centos上:touch authorized_keys
cat aix.pub > authorized_keys
原文:http://eric1026.blog.51cto.com/4754515/1886937
python 版本问题导致的启动失败;
首先会报
“ImportError: No module named supervisor.supervisord” 错误,
没有正常启动,这种原因是python多版本导致的。
网上找到的方法都是 编辑 /usr/bin/supervisord 或者 /usr/local/bin/supervisord将第一行
#!/usr/local/bin/python 改成 #!/usr/local/bin/python2.6
其实这是不完整的解决办法,因为安装的过程有些时候使用的2.6,有些使用了2.7. 这样修改完之后
会导致supervisord启动,但supervisorctl无法连接,一般情况报在supervisord.conf中设置的supervisor.sock找不到。
"unix:///var/run/supervisor.sock no such file" 或者有些方法为touch一个sock文件出来会报 "refuse connection"
正常的做法是将surpervisor重装,centos 为例子, yum -y remove supervisor,pip uninstall supervisor 彻底移除。
然后安装时就指定python版本,
修改 /usr/bin/easy_install 第一行,#!/usr/local/bin/python2.7
重装使用easy_install 安装即可。
Cause: org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException; lineNumber: 54; columnNumber: 17; 元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"。Caused by: org.xml.sax.SAXParseException; lineNumber: 54; columnNumber: 17; 元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)"。 报错原因:
在mybatis配置中,是有顺序的(properties,settings,typeAliases....environments...mappers)
typeAliases 的配置位置应该在 properties的下方,其实可见configuration已经报错了,就是配置顺序不对导致的
大家在使用find命令中的mtime参数时候,会看到官方的解释如下:
-mtime n
File's data was last modified n*24 hours ago. See the comments for -atime to understand how rounding affects the
interpretation of file modification times.
但是在各种参考的使用方式中有用+号,-号,不带符号的用法,那么这里又有什么区别呢?
注意这里的n,如果n为带有+号的值,意思为删除n天前所有的文件,比如n=+1且今天是15号,那么删除14号以前的数据,不包括14号,如果是负号(n=-1)则为删除一天内的文件,比如今天15号,那么删除15号的数据,如果是(n=-2)则代表删除一天前到今天的所有数据,比如今天15号,那么从14号开始删除。如果不带有符号,那么则删除指定前n天中这一天的数据,比如(n=1)且今天是15号,则删除14号这一天所有数据。
注意这里的一天是指当前系统时间算起的,而不是0-24小时算一天
把内容输出出来,可能不会将含有空格的
说一下单引号、双引号和不加引号区别总结说明:
单引号:
可以说是所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看到的是什么就会输出什么。
双引号:
特殊符号,有了原本的特殊意思,$LANG $() ``
把双引号内的内容输出出来;如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容来。
双引号内命令或变量的写法为 `命令或变量`或$(命令或变量)。
无引号:
与双引号类似,支持通配符。字符串视为一个整体输出, 如果内容中有命令、变量等,会先把变量、命令解析出结果,然后在输出最终内容来,如果字符串中带有空格等特殊字符,则不能完整的输出,需要改加双引号,一般连续的字符串,数字,路径等可以用,不过最好用双引号替代之。
范例:
##单引号1
2[root@oldboy32-vm1 ~]# echo '$LANG $PATH $(whichawk) {a..d}'
$LANG $PATH $(which awk) {a..d}
##双引号1
2[root@oldboy32-vm1 ~]# echo "$LANG $PATH$(which awk) {a..d}"
en_US.UTF-8/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin /bin/awk{a..d}
##不加引号1
2
3
4
5
6[root@oldboy32-vm1 ~]# echo $LANG $PATH $(whichawk) {a..d}
en_US.UTF-8/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin /bin/awka b c d
[root@oldboy32-vm1 ~]# ls *.txt
a.txt cn.txt oldboy_jia.txt oldboy.txt oldgirl.txt zh.txt
[root@oldboy32-vm1 ~]# ls "*.txt"
基于linux的I2C驱动与调试(传统ID匹配方式) 1.Linux I2C驱动框架1.1. I2C驱动的主要对象1.1.1. I2C总线1.1.2. I2C设备1.1.3. I2C驱动1.1.4. I2C适配器1.1.5. 总结一下 1.2. I2C框架分析1.3. I2C流程分析 2.Linux I2C驱动框架源码剖析2.1.注册I2C设备2.2.注册I2C驱动2.3. I2C适配器的构建2.4. I2C数据传输 3.I2C背景了解3.1.物理接口3.2通信特征 4. I2C时序图4.1. I2C起始信号4.2. I2C终止信号4.3. I2C应答信号4.4. I2C写时序4.5. I2C读时序 5. I2C实际操作图解5.1.写操作5.2.读操作5.3. 驱动代码 6.总结 1.Linux I2C驱动框架 I2C驱动框架可以分为四部分,I2C核心、I2C设备、I2C驱动、I2C适配器,其中I2C总线位于I2C核心中。
1.1. I2C驱动的主要对象 2C总线用于管理I2C设备和I2C驱动,维护一个设备链表和驱动链表,定义了设备和驱动的匹配规则,定义了匹配成功后的行为,其在内核中的定义如下。
1.1.1. I2C总线 struct bus_type i2c_bus_type = { .name = "i2c", .match = i2c_device_match, .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, .pm = &i2c_device_pm_ops, }; 1.1.2. I2C设备 I2C设备描述了I2C设备的硬件信息,例如I2C设备的地址、I2C设备在接在哪一个I2C控制器上,其结构体定义如下
struct i2c_client { unsigned short flags; /* div.
消息中间件的场景 如果是在分布式系统中,两个服务之间需要通过这种异步队列(生产消费者模式)的方式来处理任务,那单进程级别的队列就无法解决这个问题了。 因此,引入了消息中间件,也就是把消息处理交给第三方的服务,这个服务能够实现数据的存储以及传输,使得在分布式架构下实现跨进程的远程消息通信。 所以,简单来说: 消息中间件是指利用高效可靠的消息传输机制进行平台无关的数据交流,并且基于数 据通信来进行分布式系统的集成。 可以先从基本的消息中间件需求开始思考 最基本的是要能支持消息的发送和接收需要涉及到网络通信就一定会涉及到NIO消息中心的消息存储(持久化/非持久化)消息的序列化和反序列化是否跨语言消息的确认机制,如何避免消息重发 高级功能 消息的有序性是否支持事务消息消息收发的性能,对高并发大数据量的支持是否支持集群消息的可靠性存储是否支持多协议 安装和启动 下载解压 tar -xzf kafka_2.13-2.8.0.tgz cd kafka_2.13-2.8.0 bin/kafka-server-start.sh config/server.properties 启动后会在zookeeper上创建如下目录
kafka常见应用场景 消息传递 Kafka具有更好的吞吐量,内置的分区,复制和容错能力
网络活动跟踪 将网站活动(页面浏览量,搜索或用户可能采取的其他操作)发布到中心主题,每种活动类型只有一个主题。这些提要可用于一系列用例的订阅,包括实时处理,实时监控,以及加载到Hadoop或脱机数据仓库系统中以进行脱机处理和报告
日志汇总 Kafka提取了文件的详细信息,并将日志或事件数据作为消息流进行了更清晰的抽象。这允许较低延迟的处理,并更容易支持多个数据源和分布式数据消耗。与Scribe或Flume等以日志为中心的系统相比,Kafka具有同样出色的性能,由于复制而提供的更强的耐用性保证以及更低的端到端延迟
kafka的发送和确认消息 kafka对于消息的发送,可以支持同步和异步,从本质上来说,kafka都是采用异步的方式来发送消息到broker,但是kafka并不是每次发送消息都会直 接发送到broker上,而是把消息放到了一个发送队列中,然后通过一个后台线程不断从队列取出消息进 行发送,发送成功后会触发callback。kafka客户端会积累一定量的消息统一组装成一个批量消息发送出 去,触发条件是配置batch.size和linger.ms
kafka消息分发策略 在kafka中,一条消息由key、value两部分构成,在发送一条消息 时,我们可以指定这个key,那么producer会根据key和partition机制来判断当前这条消息应该发送并 存储到哪个partition中。我们可以根据需要进行扩展producer的partition机制。
消息默认的分发机制 默认情况下,kafka采用的是hash取模的分区算法。如果Key为null,则会随机分配一个分区。这个随机 是在这个参数”metadata.max.age.ms”的时间范围内随机选择一个。对于这个时间段内,如果key为 null,则只会发送到唯一的分区。这个值值哦默认情况下是10分钟更新一次 kafka消息消费原理 在多个partition以及多个consumer的情况下,消费者是如何消费消息的?
1. 如果consumer比partition多,是浪费,因为kafka的设计是在一个partition上是不允许并发的, 所以consumer数不要大于partition数
2. 如果consumer比partition少,一个consumer会对应于多个partitions,这里主要合理分配 consumer数和partition数,否则会导致partition里面的数据被取的不均匀。最好partiton数目是 consumer数目的整数倍,所以partition数目很重要,比如取24,就很容易设定consumer数目
3. 如果consumer从多个partition读到数据,不保证数据间的顺序性,kafka只保证在一个partition 上数据是有序的,但多个partition,根据你读的顺序会有不同
4. 增减consumer,broker,partition会导致rebalance,所以rebalance后consumer对应的 partition会发生变化
coordinator执行Rebalance以及管理consumer的group 当consumer group的第一个consumer启动的时候,它会去和kafka server确定谁是它们组的coordinator。之后该group内的所有成员都会和该 coordinator进行协调通信。消费者向kafka集群中的任意一个broker发送一个 GroupCoordinatorRequest请求,服务端会返回一个负载最小的broker节点的id,并将该broker设置 为coordinator
JoinGroup的过程 在rebalance之前,需要保证coordinator是已经确定好了的,整个rebalance的过程分为两个步骤, Join和Sync
对于每个consumer group子集,都会在服务端对应一个GroupCoordinator进行管理, GroupCoordinator会在zookeeper上添加watcher,当消费者加入或者退出consumer group时,会修 改zookeeper上保存的数据,从而触发GroupCoordinator开始Rebalance操作
2020年是5G商用元年。但是,如果我们在物联网行业内搞一场“2020年最热门通信技术”的评选,5G很可能无法独占冠军。
因为,有一匹黑马,在这一年迅速崛起,吸引了整个行业的关注,也成为大众热议的话题。
没错,这匹黑马,就是今天这篇文章的主角——LTE Cat.1。
根据数据统计,2020年全球LTE Cat.1新增连接数为1500万个。乍一看并不是很多,但它的增长速度极快。行业资讯机构TSR预测,未来几年LTE Cat.1模组会保持3000万台以上的年均出货量。更有专家大胆预测,今年(2021年)就能达到5000万。
LTE Cat.1为什么会迅速蹿红?它和其它蜂窝物联网技术相比,有哪些优势?我们现在常说的Cat.1和Cat.1bis,又有什么区别?
别急,让我们从头开始说起。
▉ LTE Cat.1的发展历程
2009年3月,标准组织3GPP发布了Release 8 版本,正式把LTE推到了世人面前。
当时,3GPP一共定义了5个终端类别,分别是LTE Cat.1、Cat.2、Cat.3、Cat.4、Cat.5。所谓的Cat,是英文单词“Category”的缩写,意思是“类别、种类”。
之所以要搞出这么多UE Category(终端类别),是因为3GPP非常看好物联网市场的发展前景,希望设计出不同速率等级的终端类型,满足物联网不同落地场景的需求。
从上图可以看出,LTE Cat.1的上行速率只有大约5Mbps,专门面向对速率要求不高的物联网应用。
LTE Cat.1推出之后,并没有获得太多关注。当时,蜂窝物联网的使用场景还不多,用户比较陌生,市场也没有打开。
几年后,随着LTE网络覆盖迅速形成规模,厂商们开始重新将视线放到了LTE Cat.1的身上。
刚开始的时候,有手机终端厂商针对LTE Cat.1“简配”、低成本的特点,将其用于4G老人智能机。后来,蜂窝物联网应用场景快速增加,LTE Cat.1迎来了机会。
2015年4月,第一代智能手表产品正式发售,拉开了价值千亿的可穿戴电子产品市场竞争帷幕。
在激烈的市场争夺过程中,可穿戴设备厂商发现,LTE Cat.1并没有办法用于可穿戴设备。原因在于,Cat.1和传统LTE终端一样,设计有两根天线。而可穿戴设备对体积要求很高,必须小而又小,所以无法接受双天线。即便是强行塞入,分集接收效果也会大打折扣。
当时,官方具备1Rx(单接收天线)接收规格的终端能力等级,只有Cat.0/Cat.M1/Cat.NB1。但是,这些技术最高只能实现1Mbps的极限吞吐速率,无法满足可穿戴场景的用户体验。
于是,设计一种新的适用于可穿戴品类的单天线终端能力等级,就被提上了议事日程。
2016年6月至2017年3月,3GPP RAN#73~#75标准全会就该单天线终端能力新等级做了讨论与定义。最终,在2017年3月9日,3GPP Release 13 LTE Cat.1bis核心部分正式冻结,LTE Cat.1bis诞生。
除了天线数量之外,LTE Cat.1bis和LTE Cat.1并无太大区别,两者都是上行速率5Mbps,下行10Mbps,链路预算基本一致。
这个“bis”,在英文里有“重复、两次、再来一次”的意思。
LTE Cat.1bis,既能满足中速人联/物联品类的数据吞吐量需求,又能提供相比传统LTE更优的成本与更小的尺寸。更关键的是,它可以在现有4G接入网几乎零改造的前提下,进行快速部署,大幅削减落地成本。
然而,如此完美的LTE Cat.1bis技术,在推出之后的前两年,不仅没有爆发,反而更加沉寂,几乎没有产生实质产业效益。这是为什么呢?
原因大概有两个。
一方面,是因为LTE Cat.1bis的标准化速度太慢。2018年9月,LTE Cat.1bis才完成合规认证所必要的测试部分(Testing part)冻结,根本没赶上2017年7月的全球首款蜂窝版可穿戴产品上市这波行情。
另一方面,R13 Cat.1bis推出之后,业界根本没来得及准备合适的芯片平台。没有芯片,咋推出产品?
阴差阳错之下,Cat.1bis最终缺席了原本属于它的可穿戴/中速物联广阔舞台。
▉ Cat.1bis的逆袭
到了2019年底,情况发生了根本性的变化。之前没有的终端芯片平台,现在有了!
2019年11月16日,在第7届中国移动全球合作伙伴大会上,紫光展锐重磅发布了新一代物联网芯片平台——展锐8910DM,这是全球首颗LTE Cat.1bis物联网芯片平台。
从功能上来看,展锐8910DM又不仅是一颗LTE Cat.1bis芯片。它采用28nm工艺,具备显著的低功耗优势,支持LTE Cat.1bis和GSM双模,上下行速率分别是5Mbps和10Mbps,拥有高集成度,同时集成了蓝牙通讯和Wi-Fi室内定位,可实现更稳定的连接,支持VoLTE。
展锐8910DM的推出,解决了用户在物联网连接中通信、运算、存储、定位等多方面的需求和痛点,引领了行业标准制定和行业生态构建,填补了低功耗窄带物联网与传统宽带物联网之间的蜂窝通信芯片方案空白。
芯片平台诞生之后,外部环境也发生了微妙变化,为LTE Cat.1bis的爆发创造了非常有利的条件。
什么变化?当然是5G的商用。
minikube的安装部署 环境(centos7 ip->192.168.44.133) 1.安装docker
docker安装
2.配置docker使用systemd作为默认cgroup驱动,使docker与kubenetes的驱动一致,否则会报错
处理错误参考链接
cat << EOF >> /etc/docker/daemon.json
{
“exec-opts”:[“native.cgroupdriver=systemd”]
# “exec-opts”:[“native.cgroupdriver=cgroupfs”]
}
3.启动docker
systemctl start docker systemctl enable docker 4.设置阿里的kubeadm源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes Repo
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
enable=1
EOF
5.安装kubeadm等
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
6.下载minikube的软件包
curl -Lo minikube http://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.2.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
7.关闭交换分区
swapoff -a
8.启动minikube( minikube delete删除minikube结点)
minikube start --vm-driver=“none”
接着上一章的信号完整性之Cadence Sigrity Power SI_S参数提取(三),今天总结一下Ansys SIwave的S参数提取,顺便看一下两个不同软件对于同一个仿真流程有哪些相同点和不同点:
之前和大家分享过关于信号完整性之串扰仿真(一),由于一些基础的设计我们都是按照SIwave提供的流程指导进行设置的,所以前面几步就不进行重复了,大家可以点击下方link查看之前的文章:
link.https://blog.csdn.net/weixin_41808082/article/details/116047072?spm=1001.2014.3001.5501
前面的7个步骤设置完成后,我们进行今天的S参数仿真流程:
8.端口建立 选择仿真的网络,然后在网络的器件两端建立端口。这里我们可以定义信号的TX和RX,来查看信号的传输质量。我们选择网络之后,软件会自动的在网络的两端上添加端口,我们需要设置一下信号特征阻抗(50ohm)和参考网络(GND),设置如下:
上面介绍的是一种自动选择网络添加端口,还有一种是手动添加端口。首先选择器件的封装,然后选择仿真网络的pin和参考网络的pin,点击creat port,就会建立一个新的port,操作如下:
端口设置好之后,可以从这里查看设置端口的情况,可以删除端口,修改端口的名称或者enable:
9.仿真参数设置 参数设置包括设置频率范围和频率的变化方式(Distribution),扫频方式的选择包括插值扫频(Discrete Sweep)、离散扫频(Interpolation Sweep),还有需要勾选Export Touchstone,软件会自动保存SNP文件,点击Launch开始仿真,设置如下:
10.仿真结果查看 点击launch之后,下面会显示进度条,查看仿真是否有error:
仿真完成之后,可以查看每个端口之间的S参数结果,如下:
以上资料主要参考《Cadence 高速电路设计》、《ANSYS信号完整性分析与仿真实例》
如有错误,希望各位大神留言指正,顺便点赞👍关注,感谢!!!
simulink可调节的定时器的实现 定时器初步实现计时进阶版结论 定时器 由于在网上找到的定时器都是在启动后,只能一直进行计时,不能进行实时的操作,像单片机的定时器一样。因此,把我的学习心得写下来,希望对大家有所帮助
初步实现计时 在网上找到一些大神写的定时器如下图1所示:
对于方波发生器周期设置为1ms,占空比为0.5。在应用中可以根据自己的需要进行调节,周期越小,精度越高。仿真结果如下图2所示:
可以通过改变S的大小改变输出信号和真实时间的关系,这里的关系是1:1。由于占空比的问题,计时如图所示有脉冲,将switch的Threshold改为-1(小于零的值均可)。结果如下图3所示:
进阶版 如图4所示,该模型可以通过Set对定时器进行启停控制,通过T进行循环计时控制。
将其进行封装成subsystem,如下图5所示,设置Set为1,启动计时,修改T值改变循环计时大小(T值为inf时,一直向上计时),仿真结果如图6,此时是不是已经和单片机中定时器的向上计数一样了。(对于循环计时的时长和T还有方波发生器的周期,S值的关系需要大家自己推一下,这里我就不说了,多仿真几次也能搞明白)
结论 第一次写博客,如果有错误的地方,感谢大家的批评指正。大家有更好地想法也可以多交流,多分享。
自己根据go-zero单体框架实现的一个精简版框架https://github.com/wanmei002/go-zero-learn, 新手直接看go-zero 框架可能会绕,看这个好理解
中间件的添加 在 server.Server 结构体有个一方法 Use
// Use adds the given middleware in the Server. func (e *Server) Use(middleware Middleware) { e.ngin.use(middleware) } type Middleware func(next http.HandlerFunc) http.HandlerFunc func (s *engine) use(middleware Middleware) { s.middlewares = append(s.middlewares, middleware) } 最后 中间件(Middleware) 都添加到了 Server.ngin.middleware 属性里
中间件的原理 详细讲解请看我的另一篇文章https://blog.csdn.net/wanmei002/article/details/106174126
结构: type Middleware func(next http.HandlerFunc) http.HandlerFunc
http.HandlerFunc 结构
type HandlerFunc func(ResponseWriter, *Request) // ServeHTTP calls f(w, r). func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) { f(w, r) } http.
数据集提取 本数据集采用的是cluster-trace-v2018
详情可参考该文献:https://blog.csdn.net/weixin_41988248/article/details/92431588 CSV数据集提取操作见:https://blog.csdn.net/lucky_shi/article/details/105321149 关于read_csv包的用法见:https://blog.csdn.net/dc19971118/article/details/107721340 从阿里数据集来看,我们可以把它的数据大概分为两种信息,一种是机器 容器 任务和实例的元信息,以另一种是利用率的信息,如果是做分析,分析阿里集群的,后者是重要的,但对于做仿真实验的人来说,前一个信息的重要性显然更高,而本人采用阿里数据集是做仿真实验,所以接下来对于数据集的知识会偏向前者。语言采用python
首先是怎么把数据从数据集中把数据提取出来,本人采用了python的数据分析包(pandas):
temp_list = pd.read_csv(filepath_or_buffer=file_name, nrows=self.instance_num, usecols=task_cols) instance_data = temp_list.tolist() 然后你可以像我一样把它封装成一个对象列表,也可以直接把数据列表传上去,这个主要看个人爱好
container_list = list() for data in container_data: temp_container = ContainerData() temp_container.__set_container_data__(data) container_list.append(data) return container_list 然后是四个表的信息,
**注:参考文献中的数据种类是对的,但是其某列的数据类型并不对应表某行数据类型,以下为整理好的对应数据:
machine_meta文件:
# 选中的列分别是:0机器ID 1时间索引 2第一级故障域 3第二集故障域 4机器的CPU数 5机器的内存大小 6状态 cols = [0, 1, 2, 3, 4, 5, 6] container_meta文件:
# 从数据集中提取数据: 0容器ID 1机器ID 2时间戳 3部署域 4状态 5需要的cpu数量 6cpu限制数量 7内存大小 cols = [0, 1, 2, 3, 4, 5, 6, 7] batch_task文件:
https://blog.csdn.net/qlj324513/article/details/81541282
一、Nginx优点:
1、工作在网络7层之上,可针对http应用做一些分流的策略,如针对域名、目录结构,它的正规规则比HAProxy更为强大和灵活,所以,目前为止广泛流行。
2、Nginx对网络稳定性的依赖非常小,理论上能ping通就能进行负载功能。
3、Nginx安装与配置比较简单,测试也比较方便,基本能把错误日志打印出来。
4、可以承担高负载压力且稳定,硬件不差的情况下一般能支撑几万次的并发量,负载度比LVS小。
5、Nginx可以通过端口检测到服务器内部的故障,如根据服务器处理网页返回的状态码、超时等,并会把返回错误的请求重新提交到另一个节点。
6、不仅仅是优秀的负载均衡器/反向代理软件,同时也是强大的Web应用服务器。LNMP也是近些年非常流行的Web架构,在高流量环境中稳定性也很好。
7、可作为中层反向代理使用。
8、可作为静态网页和图片服务器。
9、Nginx社区活跃,第三方模块非常多,相关的资料在网上比比皆是。
Nginx常规的和HTTP请求和相应流程图:
Nginx缺点:
1、适应范围较小,仅能支持http、https、Email协议。
2、对后端服务器的健康检查,只支持通过端口检测,不支持url来检测。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而不满。
二、LVS优点:
1、抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的,对内存和cpu资源消耗比较低。
2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率。
3、工作稳定,因为其本身抗负载能力很强,自身有完整的双机热备方案,如LVS+Keepalived,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived。
4、无流量,LVS只分发请求,而流量并不从它本身出去,这点保证了均衡器IO的性能不会收到大流量的影响。
5、应用范围比较广,因为LVS工作在4层,所以它几乎可以对所有应用做负载均衡,包括http、数据库、在线聊天室等等。
LVS DR(Direct Routing)模式的网络流程图:
LVS的缺点:
1、软件本身不支持正则表达式处理,不能做动静分离;而现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。
2、如果是网站应用比较庞大的话,LVS/DR+Keepalived实施起来就比较复杂了,特别后面有Windows Server的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived就简单多了。
三、HAProxy优点:
1、HAProxy是支持虚拟主机的,可以工作在4、7层(支持多网段)
2、HAProxy的优点能够补充Nginx的一些缺点,比如支持Session的保持,Cookie的引导;同时支持通过获取指定的url来检测后端服务器的状态。
3、HAProxy跟LVS类似,本身就只是一款负载均衡软件;单纯从效率上来讲HAProxy会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。
4、HAProxy支持TCP协议的负载均衡转发,可以对MySQL读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,大家可以用LVS+Keepalived对MySQL主从做负载均衡。
5、HAProxy负载均衡策略非常多,HAProxy的负载均衡算法现在具体有如下8种
① roundrobin
表示简单的轮询,每个服务器根据权重轮流使用,在服务器的处理时间平均分配的情况下这是最流畅和公平的算法。该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。最大支持4095个后端主机;
② leastconn
连接数最少的服务器优先接收连接。leastconn建议用于长会话服务,例如LDAP、SQL、TSE等,而不适合短会话协议。如HTTP.该算法是动态的,对于实例启动慢的服务器权重会在运行中调整。
③ static-rr
每个服务器根据权重轮流使用,类似roundrobin,但它是静态的,意味着运行时修改权限是无效的。另外,它对服务器的数量没有限制。该算法一般不用;
④ source
对请求源IP地址进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个客户端IP地址总是访问同一个服务器。如果哈希的结果随可用服务器数量而变化,那么客户端会定向到不同的服务器;该算法一般用于不能插入cookie的Tcp模式。它还可以用于广域网上为拒绝使用会话cookie的客户端提供最有效的粘连;该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
⑤ uri
表示根据请求的URI左端(问号之前)进行哈希,用可用服务器的权重总数除以哈希值,根据结果进行分配。只要服务器正常,同一个URI地址总是访问同一个服务器。一般用于代理缓存和反病毒代理,以最大限度的提高缓存的命中率。该算法只能用于HTTP后端;该算法一般用于后端是缓存服务器;该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
⑥ url_param
在HTTP GET请求的查询串中查找<param>中指定的URL参数,基本上可以锁定使用特制的URL到特定的负载均衡器节点的要求;该算法一般用于将同一个用户的信息发送到同一个后端服务器;该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
⑦ hdr(name)
在每个HTTP请求中查找HTTP头<name>,HTTP头<name>将被看作在每个HTTP请求,并针对特定的节点;如果缺少头或者头没有任何值,则用roundrobin代替;该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
⑧ rdp-cookie(name)
为每个进来的TCP请求查询并哈希RDP cookie<name>;该机制用于退化的持久模式,可以使同一个用户或者同一个会话ID总是发送给同一台服务器。如果没有cookie,则使用roundrobin算法代替;该算法默认是静态的,所以运行时修改服务器的权重是无效的,但是算法会根据“hash-type”的变化做调整。
haproxy的工作模型图:
HAPorxy缺点:
1. 不支持POP/SMTP协议
2. 不支持SPDY协议
3. 不支持HTTP cache功能。现在不少开源的lb项目,都或多或少具备HTTP cache功能。
MIT 计算机教育中缺失的一课 笔记:命令行环境 写在前面:本篇内容来自于 MIT 推出的课程:计算机教育中缺失的一课,这门课程介绍了命令行、强大的文本编辑器的使用、使用版本控制系统提供的多种特性等等。中文课程主页:https://missing-semester-cn.github.io/
本篇内容为第五节:命令行环境。本节的主要内容如下:
如何同时执行多个不同的进程并追踪它们的状态、如何停止或暂停某个进程以及如何使进程在后台运行。一些能够改善 shell 及其他工具的工作流的方法,这主要是通过定义别名或基于配置文件对其进行配置来实现的如何使用 SSH 操作远端机器 任务控制 结束进程 Shell 会使用 UNIX 提供的信号机制执行进程间通信。当一个进程接收到信号时,它会停止执行、处理该信号并基于信号传递的信息来改变其执行。就这一点而言,信号是一种_软件中断_。
当我们输入 Ctrl-C 时,shell 会发送一个 SIGINT (interrupt program) 信号到进程。另外一个退出程序的信号:SIGQUIT (quit program) ,可以通过 Ctrl-\ 触发。
尽管 SIGINT 和 SIGQUIT 都常常用来发出和终止程序相关的请求。SIGTERM 则是一个更加通用的、也更加优雅地退出信号。为了发出这个信号我们需要使用 kill 命令, 它的语法是: kill -TERM <PID>。
暂停和后台执行进程 在终端中,键入 Ctrl-Z 会让 shell 发送 SIGTSTP 信号。此时,程序被挂起,并没有结束。
使用 jobs 命令,可以查看当前会话中的进程。当程序被挂起时,可以使用 fg 命令,将挂起的程序继续执行,或者使用 bg 命令,将程序放到后台继续执行。可以通过 jobs 打印结果中的进程标号,来引用某一个进程,如进程标号为 [1],后续可以通过 bg %1 的方式来将该进程在后台运行,也可以通过 kill %1 的方式杀掉该进程。
执行命令时,在最后添加 & ,可以直接让程序在后台执行。但是注意,这个进程仍然是终端的子进程,所以关闭终端时,这个进程也会被终止(此时发送的信号为 SIGHUP)。为了防止这种情况,可以在程序最前使用 nohup 程序:nohup command command_options,此时关掉终端,程序仍然会继续执行。
21.05.10 文章目录 21.05.10什么是AOP怎样理解面向切面编程术语一个切面的三个关键的要素aop的实现AsjpectJ的切入点给表达式使用aspectj实现aop的基本步骤:@Aspect 什么是AOP AOP(Aspect-Oriented Programming,面向切面编程)是对传统传统 OOP(Object-Oriented Programming,面向对象编程)的补充,属于一种横向扩展。其将与核心业务无关的代码,如日志记录、性能监控、事务处理等从业务逻辑代码中抽离出来,进行横向排列,从而实现低耦合,提高开发效率。
怎样理解面向切面编程 使用aop的目的:是个已经存在的一些类和方法,增加额外的功能,前提是不改变原来类的代码
1)需要在分析项目功能时,找出切面
2)合理的安排切面的执行时间(在目标方法前,还是目标方法后)
3)合理的安放切面执行的位置,在哪个类,哪个方法增加增强功能
术语 1)Aspect:切面,表示增强的功能,就是一堆代码,完成某个一个功能。给业务功能,常见的切面功能有日志,事务,统计信息,参数检查,权限验证
2)JoinPoint:连接点,连接业务方法和切面的位置,就某类中的业务方法
3)Pointcut:切入点,指多个连接点方法的集合。多个方法
4)目标对象:给哪个类增加功能,哪个就是目标对象
5)Advice:通知,通知表示切面功能执行的时间
一个切面的三个关键的要素 1)切面的功能代码,切面干什么
2)切面的执行位置,使用Pointcut表示切面执行的位置
3)切面的执行时间,使用Advice表示时间,在目标方法之前,还是目标方法之后
aop的实现 aop是一个规范,是动态的一个规范化,一个标准
sop的技术实现框架:
1.spring:spring在内部实现了aop规范,能做aop的工作
spring主要在事务处理时使用aop
我们项目开发中很少使用spring的aop实现(笨重)
2.aspectJ:一个开源的专门做aop的框架,spring框架中集成了aspectJ框架,通过spring就能使用aspectj的功能。
aspectj框架事项aop的两种方式:
1)使用xml的配置文件:配置全局事务
2)使用注解,我们在项目中要做aop功能,一般都是用注解,aspectj有5个注解
@Before @AfterReturning @Around @AfterThrowing @After
AsjpectJ的切入点给表达式 使用aspectj实现aop的基本步骤: 1.新建maven项目
2.加入依赖
1)spring依赖
2)aspectj依赖
3)junit单元测试
3.创建目标类:接口和他的实现类。要做的是给类中的方法增加功能
4.创建切面类:普通类
1)在类的上面加入@Aspect
2)在类中定义方法,方法就是切面要执行的功能代码
5.创建spring的配置文件:声明对象,把对象交给容器统一管理
声明对象可以使用注解或者xml配置文件 < bean >
1)声明目标对象
2)声明切面类对象
3)声明aspectj框架中的自动代理生成器标签
自动代理生成器:用来完成代理对象的自动创建功能的
6.创建测试类,从spring容器中获取目标对象(实际就是代理对象)
通过代理执行方法,实现aop的功能增强
<!--aspectj依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.1</version> </dependency> @Aspect aspect框架中的注解
作用:表示当前类是切面类
背景叙述
一个本地客户端(就是exe安装包)的开发,因此会复用一些web端系统的接口,在复用时肯定就是拿到返回结果后的处理了,因为web端系统的返回结果原本是给前端用的,一般都是JSON(JSONObject)对象,因此在客户端拿到返回结果后需要对数据进行处理,下面就针对某个示例进行记录;
示例:
传入一个value值,去web端系统中查询这个value值在字典中的中文名称是什么;
业务逻辑代码
public String getNameByValue(String value) { User currentUser = UserUtil.getCurrentUser(); if (StringUtils.isNotBlank(currentUser.getUser_id())) { // 开始拼装请求 String url = SYS_BASE_URL + "/dict/dictionary?code=blockType"; restTemplate.getInterceptors().add(interceptor); String result = restTemplate.getForObject(url, String.class); // 设置接收参数的数据模型 ResponseData<List<BlockTypeInfo>> resourceData = FastJsonUtil.toBean(result, ResponseData.class); if (resourceData.getHttpCode() == 200) { // 首先转化成List<BlockTypeInfo>的数据结构 - 但是里面的对象数据仍然是JSONObject类型的,不可被正常操作 List<BlockTypeInfo> blockTypeInfoList = FastJsonUtil.toBean(JSON.toJSONString(resourceData.getData()), List.class); // 循环List列表中的元素,将JSONObject类型BlockTypeInfo数据进一步转化为真正的BlockTypeInfo对象 for (int i = 0; i < blockTypeInfoList.size(); i++){ BlockTypeInfo blockTypeInfo = FastJsonUtil.toBean(JSON.toJSONString(blockTypeInfoList.get(i)), BlockTypeInfo.class); // 匹对每个字典数据的value值是否和用户输入的一致 if (value.
uniapp小程序获取盒子高度 第一步:
/** * system * uni方法配置 */ const sysInfo = uni.getSystemInfoSync() export default { data () { return { sysInfo, statusBarHeight: sysInfo.statusBarHeight, ios: /^iOS/g.test(sysInfo.system), brand: sysInfo.brand, circleRect: sysInfo.windowHeight !== sysInfo.safeArea.bottom } } } 第二步:引入
我这里是用混入的方式,也可直接引入方法
第三步:使用
// 计算滚动容器高度 __changeScrollHeight () { const query = uni.createSelectorQuery().in(this) query .select('.wb-header-wrap') // 要计算高度的盒子的类名 .boundingClientRect(data => { if (data) { // 需要的盒子高度 页面高度-data.height .wb-header-wrap的高度 this.scrollHeight = ((this.sysInfo.safeArea && this.sysInfo.safeArea.height) || this.sysInfo.screenHeight) - data.height } }) .
文章目录 一、基本概念1.实体2.属性3.关系 二、实例 常用的在线画图工具:https://www.processon.com
一、基本概念 ER图分为实体、属性、关系三个核心部分。
1.实体 ER图的实体(entity)即数据模型中的数据对象,例如人、学生、音乐都可以作为一个数据对象,每个实体都有自己的实体成员(entity member)或者说实体对象(entity instance),例如学生实体里包括张三、李四等。
实体在ER图中用长方形来体现
2.属性 ER图的属性(attribute)即数据对象所具有的属性,例如学生具有姓名、学号、年级等属性,属性分为唯一属性(即主码)和非唯一属性,唯一属性指的是唯一可用来标识该实体实例或者成员的属性,一般来讲实体都至少有一个唯一属性。
属性用椭圆形来表示,主码会在属性名上加一条下划线来表示
3.关系 ER图的关系(relationship)用来表现数据对象与数据对象之间的联系,例如学生的实体和成绩表的实体之间有一定的联系,每个学生都有自己的成绩表,这就是一种关系。
关系用菱形来表示。
ER图中关联关系有三种:
1对1(1:1) :1对1关系是指对于实体集A与实体集B,A中的每一个实体至多与B中一个实体有关系;反之,在实体集B中的每个实体至多与实体集A中一个实体有关系。
1对多(1:N) :1对多关系是指实体集A与实体集B中至少有N(N>0)个实体有关系;并且实体集B中每一个实体至多与实体集A中一个实体有关系。
多对多(M:N) :多对多关系是指实体集A中的每一个实体与实体集B中至少有M(M>0)个实体有关系,并且实体集B中的每一个实体与实体集A中的至少N(N>0)个实体有关系。
表示关系的种类可以在连线处用数字来表示,例如
二、实例
一个初创公司的老板带着他们的技术负责人来做技术交流,他们列了一长串问题,有微服务技术选型方面的,有技术难点方面的。这些问题如果不能快速解决,那么就会影响产品质量、上线进度,进而直接影响业务。
这是很多企业常常面临的问题,业务有所发展是好现象,证明你所在的企业保持着向上发展的良好势头。这时候微服务分布式就成为很多企业不得不面临的选择,因此微服务分布式成为了考验很多技术骨干及架构师能力的必要条件。
所以今天为大家带来了一份阿里大牛的微服务分布式项目实战笔记总结:
笔记总览: 因为笔记的内容实在太多,下面就只以截图展示部分内容了。有想获取完整版笔记的小伙伴:一键三连(点赞+收藏+关注) 后,添加微信:mxm9843 即可免费获取到
内容展示: 内容太多,就不一一截图展示了。有想获取完整版笔记的小伙伴:一键三连(点赞+收藏+关注) 后,添加微信:mxm9843 即可免费获取到
转化具体代码如下:
/** * Object 对象转 List */ public static <T> List<T> castList(Object obj, Class<T> clazz) { List<T> result = new ArrayList<T>(); if (obj instanceof List<?>) { for (Object o : (List<?>) obj) { result.add(clazz.cast(o)); } return result; } return null; } 接口调用方式:
List<String> list = castList(objectName, String.class);
IDEA创建package包和class类文件 一、如何创建package包文件夹,而不是只创建Directory文件夹
创建好Maven项目,添加好java文件夹和resources文件夹以后,就需要进一步创建package包和class文件了。
但是当我们new的时候,却只能创建普通Directory文件夹,而不是代码工程的package包文件夹。
1.首先创建一个普通的文件夹
2.让这个文件夹成为一个package包文件夹
这个文件夹就会变颜色,就可以在这个包里创建class类文件了。
普通的Directory文件夹变成Package包文件夹以后,就只能创建二级的package包文件夹,就不能在包文件夹里创建普通Directory文件夹了。
二、如何新建第一个class类文件
注意:class类文件只能存在于package包文件夹中,不能创建在一般的Directory文件夹中。
只有在package包文件夹上new,才可以看到class文件的选项,普通的Directory文件夹是看不到的。
配置自动启动Run Dashboard 找到.idea下面的workspace.xml文件 2.在下面的代码中加入一段配置代码 源代码位置
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
<option name="contentProportion" value="0.22874807" />
</component>
添加以下配置代码
<option name="configurationTypes">
<set>
<option value="SpringBootApplicationConfigurationType" />
</set>
</option>
3.大功告成,idea启动后Run Dashboard 在项目中自动启动。
最终代码如下:
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />