IPv6隧道技术——6to4实验分析

文章目录 实验拓扑基本配置配置6to4隧道 6to4网络主机通过IPv4网络如何实现互通?6to4网络主机通过IPv4网络如何访问普通IPv6站点的主机?如果一个6to4网关后有多个6to4网络,请问如何规划区分不同子网? 实验拓扑 地址规划如图所示,R1、R2、R3与R4之间IPv4网络互相可达,要求R1、R4之间通过部署6to4隧道实现IPv6站点互 R1、R4后连接的IPv6站点分别是站点1、站点2要求R1后的站点1可以访问R3后的普通IPv6站点 基本配置 # AR1 sys sys AR1 ipv6 //全局开启IPv6 int g0/0/0 ipv6 enable //接口下开启IPv6 ip ad 10.1.12.1 24 # 配置IPv6站点 int lo 0 ipv6 enable ipv6 ad 2002:0A01:0C01::1 64 int lo 1 ipv6 enable ipv6 ad 2002:0A01:0C01:1000::1 64 # 配置IPv4内的IGP ospf 1 router-id 1.1.1.1 area 0 net 10.1.12.1 0.0.0.0 ------------------------------------------------------ # AR2 sys sys AR2 int g0/0/0 ip ad 10.1.12.2 24 int g0/0/1 ip ad 10.

注解篇——@Autowired和@Component

@Autowired是标注在类的成员变量或方法上,完成的是bean的注入。 @Component是标注在一个类上的,作用是将被标注的类注册在spring容器中,将类的实例化交给spring管理,完成的是bean的注册。

老卫带你学---leetcode刷题(787. K 站中转内最便宜的航班)

leetcode刷题(787. K 站中转内最便宜的航班) 问题: 有 n 个城市通过 m 个航班连接。每个航班都从城市 u 开始,以价格 w 抵达 v。 现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到从 src 到 dst 最多经过 k 站中转的最便宜的价格。 如果没有这样的路线,则输出 -1。 示例1 输入: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 1 输出: 200 解释: 从城市 0 到城市 2 在 1 站中转以内的最便宜价格是 200 示例2 输入: n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] src = 0, dst = 2, k = 0 输出: 500

Qt connect通信遇到过的问题

1、一般调用的信号函数和槽函数,不要用自己定义的结构体(如果有,拆开传吧...) 2、我遇到过这个情况, connect(thread_Encoder, SIGNAL(send_current_encoder(long encoder)), this,SLOT(recive_current_encoder(long encoder)), Qt::DirectConnection); connect(thread_Encoder, SIGNAL(send_current_encoder(long)), this, SLOT(recive_current_encoder(long)), Qt::DirectConnection); 第一行通信不上,第二行可以,不知道为什么。 我就是在这种问题中浪费时间,这学习工作以来,经常被这种莫名其妙的问题折腾。 有些人学习工作一帆风顺,真的只是运气好,没遇过弯路而已。 3、强烈推荐一个东西,可以判断信号有没有连上 bool ok = QObject::connect(model .....) 这会节省很多调试的时间...

windows qt5.12.0mingw下编译zlib quazip动态库

一 环境 windows64 qt.5.12.0-mingw 二 编译zlib 2.1)源码下载 http://www.zlib.net/ 点击此处下载,本次下载版本为1.2.11 2.2)解压 zlib-1.2.11.tar.gz 右键解压 G:/test/zlib 2.3)mingw32编译zlib 1.在QT安装菜单中找到QT5.12 for DeskTop工具,运行 2.打开mingw 控制台进入解压目录 cd G:\test\zlib\zlib-1.2.11 然后执行如下指令 copy win32\Makefile.gcc makefile.gcc mingw32-make -f makefile.gcc 3.编译结束拷贝生成zlib1.dll 4.新建zlib文件夹,子目录建立include和lib,把zlib1.dll拷贝到lib目录下,zlib.h zconf.h拷贝到include目录下,留到下一步使用 三 编译quazip 3.1)源码下载 https://sourceforge.net/projects/quazip/ 版本:quazip-0.7.3.zip 3.2)解压 quazip-0.7.3.zip 3.3)配置quazip项目,源码包含pro,使用qtCreator打开 3.4)打开quazip.pro文件,将SUBDIRS=quazip qztest这行代码最后的qztest删除。 3.5)把上一步生成的zlib文件夹拷贝到quazip-0.7.3\quazip目录下 3.6)打开quazip文件夹下的quazip.pro文件,在win32代码块下添加两行代码,将zlib的头文件和库文件包含进来(具体路径根据实际修改) INCLUDEPATH += $$PWD/zlib/include LIBS += -L $$PWD/zlib/lib -lzlib1 3.6)将项目改为Release模式,执行qmake,然后在构建,至此编译结束。 3.7)新建libquazip文件夹,子目录建立include和lib,把quazip.dll拷贝到lib目录下,quazip-0.7.3\quazip所有头文件拷贝到include目录下,留到下一步使用 四 测试程序 4.1)新建qt widget测试程序 4.2)把quazip复制到程序目录 4.3)在pro 加入 刚才复制的quazip INCLUDEPATH += $$PWD/quazip/include win32:{ CONFIG(release, debug |release){ LIBS += -L$$PWD/quazip/lib -lquazip } CONFIG(debug, debug | release){ LIBS += -L$$PWD/quazip/lib -lquazipd } } 4.

使用vue开发项目的时候,异步请求数据,连续触发多次请求导致的渲染的数据列表数据错误的问题解决办法。

问题描述: 在vue类型的项目开发中,我们一般都是发起异步请求从服务器获取数据后,根据数组数据使用v-for来动态渲染数据列表。 但是,如果一个请求在pending中,再次发送一个请求,最后导致渲染的list,数据重复,或是错误的问题。 原因,就是多次请求了异步接口,一个接口没有返回,另外一个接口就发出去了。因为,ajax是一个异步操作。导致,在回调的时候,两次请求成功后的回调都会执行。就导致数据,错误了。 什么情况下发生这种现象呢? 譬如下拉滚动加载更多 或是 tab切换。 类似,这种,点击tab标签,根据list数据来渲染列表。 当快速切换tab标签时(可以把调试的网速降低,更容易看到这种情况),导致前一个标签的内容也会显示在第二个标签的内容里。 怎么解决呢? 面对这种多次触发异步请求的处理,常用的解决办法如下: 1、在请求发出后,处于loading状态时,禁用再次触发异步的操作按钮。 譬如,表单提交了,就把表单提交按钮disable禁用,不然再次提交。 2、请求发出后,处于loading状态是,显示mask遮罩,不然点击下面的其他的操作。 譬如在微信小程序中使用: wx.showLoading({ title: '加载中', mask: true }) 3、终极大招,使用闭包 具体就上面这个问题,分析一下。 我在修改前的代码如下: // 获取列表数据 fetchList () { this.loading = true wx.showLoading() let para = { curUserId: this.userId, page: this.page, customerName: this.keyword, orderStatus = this.active } fetchReportRecordList(para) .then((res) => { wx.hideLoading() const data = res.data this.total = data.total this.list = [...this.list, ...data.rows] this.loading = false }) .catch(() => { this.

visualvm下载和安装

visualvm下载和安装 官网下载地址: https://visualvm.github.io/index.html 电脑登录不上,可以使用手机打开, 附带我下载好的visualvm2.0.3版本的网盘地址:(适用于Jdk1.8) 链接:https://pan.baidu.com/s/19Jw7Jl0YthCwI75yO_66Lg 提取码:zwwm 安装后双击打开: 报错: visualvm cannot find java1.8 or higher 去这个文件修改jdk地址为你本地 的jdk安装位置 插件下载地址: https://visualvm.github.io/pluginscenters.html

看完让你彻底理解 WebSocket 原理

1、前言 最近有同学问我有没有做过在线咨询功能。同时,公司也刚好让我接手一个 IM 项目。所以今天抽时间记录一下最近学习的内容。 本文主要剖析了 WebSocket 的原理,以及附上一个完整的聊天室实战 Demo (包含前端和后端,代码下载链接在文末)。 2、WebSocket 与 HTTP WebSocket 协议在2008年诞生,2011年成为国际标准。现在所有浏览器都已经支持了。WebSocket 的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话。 HTTP 有 1.1 和 1.0 之说,也就是所谓的 keep-alive ,把多个 HTTP 请求合并为一个,但是 Websocket 其实是一个新协议,跟 HTTP 协议基本没有关系,只是为了兼容现有浏览器,所以在握手阶段使用了 HTTP 。 下面一张图说明了 HTTP 与 WebSocket 的主要区别: WebSocket 的其他特点: 建立在 TCP 协议之上,服务器端的实现比较容易。 与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。 数据格式比较轻量,性能开销小,通信高效。 可以发送文本,也可以发送二进制数据。 没有同源限制,客户端可以与任意服务器通信。 协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。 3、WebSocket 是什么样的协议,具体有什么优点 首先,WebSocket 是一个持久化的协议,相对于 HTTP 这种非持久的协议来说。简单的举个例子吧,用目前应用比较广泛的 PHP 生命周期来解释。 HTTP 的生命周期通过 Request 来界定,也就是一个 Request 一个 Response ,那么在 HTTP1.

深层网络梯度消失-爆炸原因

声明:文章仅作知识整理、分享,如有侵权请联系作者删除博文,谢谢! 网上有很多关于梯度消失-爆炸这方面的文章,相似的也比较多,最近对不同文章进行整理,修改部分文章公式错误,形成整理。 1、概念 目前优化神经网络的方法都是基于BP,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。其中将误差从末层往前传递的过程需要链式法则(Chain Rule)的帮助,因此反向传播算法可以说是梯度下降在链式法则中的应用。 而链式法则是一个连乘的形式,所以当层数越深的时候,梯度将以指数形式传播。梯度消失问题和梯度爆炸问题一般随着网络层数的增加会变得越来越明显。在根据损失函数计算的误差通过梯度反向传播的方式对深度网络权值进行更新时,得到的梯度值接近0或特别大,也就是梯度消失或爆炸。梯度消失或梯度爆炸在本质原理上其实是一样的。 1.1、梯度消失 经常出现,产生的原因有:一是在深层网络中,二是采用了不合适的损失函数,比如sigmoid。当梯度消失发生时,接近于输出层的隐藏层由于其梯度相对正常,所以权值更新时也就相对正常,但是当越靠近输入层时,由于梯度消失现象,会导致靠近输入层的隐藏层权值更新缓慢或者更新停滞。这就导致在训练时,只等价于后面几层的浅层网络的学习。 梯度消失的影响: 1)浅层基本不学习,后面几层一直在学习,失去深度的意义。 2)无法收敛,相当于浅层网络。 1.2、梯度爆炸 根据链式法则,如果每一层神经元对上一层的输出的偏导乘上权重结果都大于1的话,在经过足够多层传播之后,误差对输入层的偏导会趋于无穷大。这种情况又会导致靠近输入层的隐含层神经元调整变动极大。梯度爆炸一般出现在深层网络和权值初始化值太大的情况下。另外,初始学习率太小或太大也会出现梯度消失或爆炸。 梯度爆炸的影响: 1)模型不稳定,导致更新过程中的损失出现显著变化; 2)训练过程中,在极端情况下,权重的值变得非常大,以至于溢出,导致模型损失变成 NaN等等。 2、产生梯度消失和梯度爆炸的原因 梯度消失的根源—–深度神经求导网络和反向传播。目前深度学习方法中,深度神经网络的发展造就了我们可以构建更深层的网络完成更复杂的任务,深层网络比如深度卷积网络,LSTM等等,而且最终结果表明,在处理复杂任务上,深度网络比浅层的网络具有更好的效果。但是,目前优化神经网络的方法都是基于反向传播的思想,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化。下面将从这3个角度分析一下产生这两种现象的根本原因: 比较简单的深层网络如下: 2.1、深层网络 如图所示的含有3个隐藏层的神经网络,梯度消失问题发生时,接近于输出层的hidden layer 3等的权值更新相对正常,但前面的hidden layer 1的权值更新会变得很慢,导致前面的层权值几乎不变,仍接近于初始化的权值,这就导致hidden layer 1相当于只是一个映射层,对所有的输入做了一个同一映射,这是此深层网络的学习就等价于只有后几层的浅层网络的学习了。 图中是一个四层的全连接网络,假设每一层网络激活后的输出为fi(x),其中i为第i层, x代表第i层的输入,也就是第i−1层的输出,f是激活函数,那么,得出: 简单记为: BP算法基于梯度下降策略,以目标的负梯度方向对参数进行调整,参数的更新为w←w+Δw,给定学习率α,得出: 如果要激活函数的导数、网络初值(w,b)连续相乘表现为w的更新第一隐藏层量。避免网络不work的权值信息过程就是调整这部分连乘结果,根据链式求导法则使其保持在1附近。学习率决定的网络学习的快慢,过大或过小也会直接影响网络的参数更新梯度信息过程。 ,很容易看出来: ,即第一层的输入。 所以说af4/af3就是对激活函数进行求导,如果此部分大于1,那么层数增多的时候,最终的求出的梯度更新将以指数形式增加,即发生梯度爆炸,如果此部分小于1,那么随着层数增多,求出的梯度更新信息将会以指数形式衰减,即发生了梯度消失。 如果说从数学上看不够直观的话,下面几个图可以很直观的说明深层网络的梯度问题: 图中的曲线表示权值更新的速度,对于下图两个隐层的网络来说,已经可以发现隐藏层2的权值更新速度要比隐藏层1更新的速度慢。 那么对于四个隐层的网络来说,就更明显了,第四隐藏层比第一隐藏层的更新速度慢了两个数量级: 总结:从深层网络角度来讲,不同的层学习的速度差异很大,表现为网络中靠近输出的层学习的情况很好,靠近输入的层学习的很慢,有时甚至训练了很久,前几层的权值和刚开始随机初始化的值差不多。因此,梯度消失、爆炸,其根本原因在于反向传播训练法则,属于先天不足。 2.2、激活函数 以下图的反向传播为例(假设每一层只有一个神经元且对于每一层: 偏置b可以推导出: 而sigmoid的导数为: 同理,使用tanh作为损失函数,它的导数图如下,可以看出,tanh比sigmoid要好一些,但是它的倒数仍然是小于1的。tanh数学表达为: 如果接近输出层的激活函数求导后梯度值大于1,那么层数增多的时候,最终求出的梯度很容易指数级增长,就会产生梯度爆炸;相反,如果小于1,那么经过链式法则的连乘形式,也会很容易衰减至0,就会产生梯度消失。 2.3、初始化权值太大 如上图所示,当: ,也就是w比较大的情况。根据链式相乘(反向传播)可得,则前面的网络层比后面的网络层梯度变化更快,很容易发生梯度爆炸的问题。 3、总结 深层网络出现梯度消失或爆炸,主要是由于链式求导发现传播引起。参数的更新为w←w+Δw,给定学习率α,得出: 激活函数的导数、网络初值(w,b)连续相乘表现为w的更新量。避免网络不work的过程就是调整这部分连乘结果,使其保持在1附近。学习率决定的网络学习的快慢,过大或过小也会直接影响网络的参数更新过程。 参考文章: 1、https://zhuanlan.zhihu.com/p/25631496 2、https://zhuanlan.zhihu.com/p/72589432

解决Windows 10输入法无法安装报0x800F0954的问题

这次Windows10需要增加安装多语言输入法,但是在选择"系统设置/时间和语言/语言/<所选语言>/基本输入法/下载"以后,持续报错0x800F0954。 查了相关错误码,Windows10应该是通过系统更新Windows Update服务来完成下载和安装的。 这次由于有本地更新服务器,怀疑一些系统的基础包没有全,所以选择恢复官方更新服务器。 https://blog.csdn.net/asd77882566/article/details/80024043 WIN+R执行regedit,在键 HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU 找到UseWUServer,右键修改,将值改为0 可以把相关服务和本地缓存都重置一遍。参考 https://answers.microsoft.com/en-us/windows/forum/all/error-0x800f0954/56b02d24-e16b-4eaa-bd39-2d26e1f75898 net stop bits net stop wuauserv net stop appidsvc net stop cryptsvc ren C:\Windows\SoftwareDistribution SoftwareDistribution.old ren C:\Windows\System32\catroot2 catroot2.old net start bits net start wuauserv net start appidsvc net start cryptsvc 再点击下载,就正常开始下载了,虽然慢一点。 最后别忘把键值改回1来。

使用生成器函数和Promise改善异步流程

最近在学习JavaScript异步相关的知识,在学到Generator(生成器函数)、Promise 和 async-awiat 等相关对异步优化的内容时遇到了一些一时没有理解的东西。本文仅作为学习过程中的笔记分享,第一次发文章,如果错误请不吝指出。 话不多说,进入正题,先写一下在 Generator 中要用到的函数,随便写几个就行。 function getValue(val, duration){ return new Promise(resolve => { setTimeout(() => { resolve(val); }, duration); }) } function delay(duration){ return new Promise(resolve => {//delay函数不resolve出任何东西,或者说resolve出undefined setTimeout(resolve, duration); }) } function getJSON(url){ return get(url).then(JSON.parse); } 然后是 Generator 函数主体 function *f(){ var data = yield getJSON('data.json')//(1) yield delay(1000);//(2) var b = yield getValue(10, 3000);//(3) } Generator 函数会在遇到 yield 时生成一个值并暂停执行,如果要继续执行,则要调用next(),yield 的运算结果是生成器 next() 里面的参数。 为了执行 Generator函数 f ,声明一个函数 g 作为函数 f 的调用。

Vue 事件参数传递

Vue 事件参数传递 原文链接:https://blog.learnzs.com/2019/08/17/223/ vue绑定事件的有时候需要传递很多参数,在此整理几种传递方式 1. 默认传参 <zs-input @change="handleChange($event)"></zs-input> 或(第一个参数会默认传进去) <zs-input @change="handleChange"></zs-input> 使用: handleChange(event){ console.log(event) } 2. 赋值传参 如果手动赋值或覆盖掉默认的参数 <zs-input @change="handleChange('hello')"></zs-input> 使用: handleChange(event){ console.log(event) // hello } 3. 混合传参 当需要使用默认值和手动传参同事出现时一般使用这种方式 <zs-input @change="handleChange($event, 'hello')"></zs-input> 使用: handleChange(event, val){ console.log(event, val) } 4. 多默认值混合传参 当默认参数有多个是,使用上述方式同样会出现问题,这时就需要使用本方式 <zs-input @change="handleChange(arguments, 'hello')"></zs-input> 使用: handleChange(args, val){ console.log(args, val) }

leetcode_128_最长连续序列

最长连续序列 描述 困难 给定一个未排序的整数数组,找出最长连续序列的长度。 要求算法的时间复杂度为 O(n)。 示例: 输入: [100, 4, 200, 1, 3, 2] 输出: 4 解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。 解题 一开始的想法是,利用字典保存数据,以数组中的数为键,其长度为值(具体看代码) 遍历每个数,如果这个数的前一个数存在于字典之中,在字典中这个数的值为其前一个数的值加1 否则,这个数的值为1 然后判断这个数的后面的连续的数是否在数组中,如果存在,更新字典 但是,超时了 class Solution: def longestConsecutive(self, nums: List[int]) -> int: nums_set = set(nums) nums_dic = {} longest_length = 0 for num in nums: # 如果其前一个数存在于字典中 if num - 1 in nums_dic: nums_dic[num] = nums_dic[num - 1] + 1 else: nums_dic[num] = 1 # 判断这个数后面的连续的数是否存在于数组中 while num + 1 in nums_set: nums_dic[num + 1] = nums_dic[num] + 1 num += 1 longest_length = max(longest_length, nums_dic[num]) return longest_length 仍然是遍历每个数,判断这个数的前一个数是否存在于数组中

python爬虫 - 翻页url不变网页的爬虫探究!

python爬虫-翻页url不变网页的爬虫探究 url随着翻页改变的爬虫已经有非常多教程啦,这里主要记录一下我对翻页url不变网页的探究过程。学术菜鸡第一次写CSDN,请大家多多包容~ 如果对你有一点点帮助,请帮我点个赞吧! 翻页url不变 与 翻页url改变 有什么区别? url其实就是链接,翻页url改变的链接就是翻页请求在url中体现的链接,比方说很多爬虫初学者的第一个爬虫实例:爬取豆瓣电影top250的信息。 注意看这个网站的链接!! 这里可以看到控制页数的参数start直接在url中体现了,改变start=之后的数值就能够实现翻页。start=25对应的页面就是从26开始的电影,start=0对应的页面就是从1开始的电影。那么只需要控制start之后的数字以25为步长递增就可以通过for函数实现翻页。 但是有时候会遇到明明你点击了翻页,但url却不改变的情况,比如这个: 这种情况没有办法在python中直接通过改变url实现翻页。 找到翻页命令 事实上,控制网页翻页总得有一个参数,只是在翻页url改变的情况中,这个翻页参数体现在了url中,这使得我们可以通过直接改变url的方式实现翻页。对于翻页url不变的情况,我们其实只需要找到翻页命令所在的位置,然后控制这条命令即可。 下面介绍我找到翻页命令的一种方式: 打开开发者模式在打开开发者模式的情况下点击翻页找到翻页后返回的内容表单 (一般是XHR格式)查看其headers (注意pages,start,p等字眼)提取相应的部分,在python中编写语句实现控制就可以控制翻页了 爬取去哪儿酒店信息实例 打开开发者模式,并点击翻页找到返回的第二页内容的表单可以点击list-preview打开表单预览,确认这个list确实是服务器返回的第二页酒店内容这里可以看到list里面的内容确实就是第二页的酒店内容,那么我们就要寻找这个list是怎么返回的,即它是通过向服务器发送什么命令返回的!!查看list的headers 可以发现在Request Headers之下多了一个新的模块,叫做Request Payload(我之前在CSDN上看到很多帖子,都是讲From Data或者Query String Parameters,但是我却一直没找到这两个模块,只有Request Payload,后来经过高人指点才知道,其实在Request Payload内也有可能隐藏着翻页的信息,所以我在想不一定要局限在具体的模块名字,关键是找到翻页之后服务器返回的信息表单,找它的headers有什么与第一页headers不同的地方) 将Request Payload的内容打开观察 观察Request Payload里的内容,发现这条指令其实是向服务器发送了一些要求,比如说要求了需要查找的酒店所在城市是西安,还指定了查询的日期。可以看到这里有一条start:20的命令,经过对比第一页list的同一位置(start:0)发现start:i就是控制返回不同页面的命令。 至此我们已经发掘到了翻页url不变网站的翻页命令,下面只需要在爬虫构造headers的时候,加上Request Payload里要求的内容,其中start控制内容由函数参数控制。这样就实现了控制爬取页数的操作。除此之外,不难发现我们甚至还可以控制通过控制Request Payload中的city方便地实现对不同城市酒店的爬取。 代码 下面附上完整代码,由于去哪儿网页时常加载失败,所以如果前两次出现“No targets found”很有可能是由于链接网页失败,多试几次就好了。 通过修改main()里的city,可以爬取不同城市的酒店信息。通过修改getlist()里z的范围,可以改变爬取页数。我没有对正则提取的内容做任何模糊处理,理论上复制这个代码就可以运行。大多数城市直接输入城市拼音就可以爬到(链接失败就多试几次),但是北京得用beijing_city。如果有的城市试了很多次都链接失败,可以上去哪儿网手动搜索看看url里的city是怎样的,手动添加一下就可以了。 #-*- codeing = utf-8 -*- #@Time : 2020/8/4 9:25 上午 #@Author : Tango #@File : hotel_general.py #@Software : PyCharm import time import re import requests from bs4 import BeautifulSoup import xlwt import json findname = re.

C | C语言学习(二)占位符、常量、scanf()、进制变换

1.打印占位符: 占位符说明%d输出一个有符号的10进制int型(signed int)%f输出一个float型(默认保留六位小数)(float)%.2f输出一个float型,保留两位小数 (C语言中存在四舍五入,C++不存在)%lf输出一个double型(double)%u输出一个无符号的10进制int型(unsigned int)%hd输出一个short int型%ld输出一个long int型%ud输出一个long long int型%c输出一个char型 %s输出字符串,遇到\0停止(char *)%p输出16进制形式的内存地址%e以科学计数法形式输出%o(字母o)输出无符号8进制的int类型(unsigned int)%x(%X)输出16进制的int类型,字母以小写输出(字母以大写输出)(unsigned int)%hu输出unsigned short类型%lu输出 unsigned long类型%llu输出 unsigned long long类型 printf 附加格式: 字符含义举例-左对齐 int a=10 ; printf("%-5d\n",a); //输出结果:10___ m(m是一个整数)数据最小宽度 int a=10 ; printf("%5d\n",a); //输出结果:___10 0(数字0)与m搭配使用,不可和-搭配使用,将输出的数前面加上0,直到数据宽度为m int a=10 ; printf("%05d\n",a); //输出结果:00010 m.n(m与n都是一个整数) m指域宽,即对应的输出项在输出设备上所占的字符数。 n 指精度,用于说明输出的实型数的小数位数。 对数值型的来说,未指定 n 时,隐含的精度为 n = 6 位。 float b = 3.1415f; printf("%4.2f\n", b); //输出结果:3.14 2.定义常量的两种方式: a.#define 名称 值 b.const 数据类型 名称=值; 注意:方法a结尾没有分号;方法b在C语言中不安全。 #define PI 3.14 const float PI = 3.

2021秋招知识点记录;

1、大疆FPGA量化精度试题:请问对12.918做无损定点化,最小位宽是多少? 误差(error)计算公式:小数位-(先量化为整数(小数乘以量化系数:2^n,四舍五入)再反量化(整数除以量化系数:2^n)) 精度(precision):量化系数分之一,1/2^n; 误差小于精度一半,则代表可以无损顶点化; 全志: 1、为什么使用DMA,DMA传输最大突发长度多少? 2、AXI协议介绍? 3、动态和静态功耗? 跨时钟域: 快到慢: 1、在快时钟域采集脉冲,生成展宽信号signal_a; 2、在慢时钟域用两级触发器同步展宽信号,在用上升沿检测同步后的信号; 3、在快时钟域检测到慢时钟域的检测信号后,拉低展宽信号 同步FIFO,判断空满: 1、复位后满信号(fifo_full)为低; 2、判断如果读fifo(rd_fifo)有效,表示 5个always搞定 紫光同创面试官咨询:FPGA内的dsp内部结构; 开立医疗:输入图像数据是8位无符号整型,输入特征是8位有符号;计算结果是32位有符号数; 外企: NXP:使用英语两分钟介绍研究生阶段的生活;谈谈行业有哪些竟品公司;科技公司的Marketing engineer,注重项目工程经验; 诺瓦海外支持:1、讲讲你的兄弟,

Python模块——os模块详解

本文大纲 os模块是Python中整理文件和目录最为常用的模块,该模块提供了非常丰富的方法用来处理文件和目录。本着只讲最有用的态度,下方我将os模块中一些我经常用的的方法,给大家详细列举出来了,希望减少大家的学习负担。 知识串讲 1)模块的安装和导入 # 导入 import os 2)os.getcwd() 作用:获取当前的工作路径; os.getcwd() 结果如下: 3)os.listdir(path) 作用:传入任意一个path路径,返回的是该路径下所有文件和目录组成的列表; path = r"C:\Users\黄伟\Desktop\publish\os模块\test_os模块" os.listdir(path) 结果如下: 3)os.walk(path) 含义 :传入任意一个path路径,深层次遍历指定路径下的所有子文件夹,返回的是一个由路径、文件夹列表、文件列表组成的元组。我代码中写的方式属于元组拆包;元组拆包:就是将一个元组中的每个值,赋值给不同的变量; path = r"C:\Users\黄伟\Desktop\publish\os模块\test_os模块" for path,dirs,files in os.walk(path): print(path) print(dirs) print(files) print("\n") 结果如下: 4)os.path.exists(path) 含义:传入一个path路径,判断指定路径下的目录是否存在。存在返回True,否则返回False; path1 = 'C:\\Users\\黄伟\\Desktop\\publish\\os模块\\huang_wei' if os.path.exists(path1): print("指定文件夹存在") else: print("指定文件夹不存在") 结果如下: 5)os.mkdir(path) 含义:传入一个path路径,创建单层(单个)文件夹;注意:如果文件夹已经存在,就会报错。因此创建文件夹之前,需要使用os.path.exists(path)函数判断文件夹是否存在; os.getcwd() path1 = os.getcwd()+"\\huang_wei" os.mkdir(path1) 结果如下: 6)os.makedirs(path) 含义:传入一个path路径,生成一个递归的文件夹;注意:如果文件夹存在,就会报错。因此创建文件夹之前,需要使用os.path.exists(path)函数判断文件夹是否存在; os.getcwd() path1 = os.getcwd()+"\\huang_wei" os.mkdir(path1) 结果如下: 7)os.rmdir(path) 含义:传入一个path路径,删除指定路径下的文件夹;注意:该方法只能删除空文件夹,删除非空文件夹会报错; path1 = os.getcwd()+"\\huang_wei" os.rmdir(path1) ---------------------------------- path2 = os.

Alexa Prize 2019 冠亚军方案介绍

本文将介绍 Alexa Prize Socialbot Challenge 2019 的冠亚军参赛方案 第一名通过构造大量的对话模版,并维持用户信息表和状态表,来实现个性化主题对话 第二名通过深度生成模型(GPT-2 等预训练模型)来生成对话,并构造对话树(treelet)来实现对话控制 最终专家评分排名情况如下 awardfinal scoreteamschoollast$500,0003.81EmoraThe Emory University#4$100,0003.17Chirpy CardinalStanford University-$50,0003.14AlquistCzech Technical University#2 1st Emora Emora: An Inquisitive Social Chatbot Who Cares For You Introduction Emora 能够针对各种热门话题和用户进行个性化聊天。 设计目标不仅是创建有趣且流畅的对话,而且还超越了基于信息的聊天范围,使 Emora 感觉更像是用户的贴心朋友,而非简单的 QA。 遵循此目标,Emora 不仅支持先前 Alexa Prize 比赛中的热门话题(如电影,音乐和体育),还能在更具个性化的话题(如学校,工作和业余爱好) 进行丰富的对话。 为了促进混合式对话,作者赋予了 Emora 观点和个性,通过积极询问用户的观点和个人信息来维持对话的进行,同时通过分享 Emora 自己的态度和个人资料与用户建立联系。 Architecture ASR (Automatic Speech Recognizer) 返回语音识别结果(包括多个候选文本) NLP pipeline 负责特征提取,并进行相关文本分类任务(情感识别、主题/意图分类等) Dialogue Manager 基于当前对话状态、提取的特征以及用户的话语,选择最合适的回复Amazon 服务可以有效存储和检索特定主题的信息(关系数据库RDS,检索服务ElasticSearch) Profanity Detector Service 检查回复中是否有敏感内容,没有则调用 Amazon Lambda function 合成语音返回给用户若包含敏感内容,则随机从通用回复集合中选择一个返回 NLP Pipeline 进行特征提取和文本分类任务(情感识别、主题/意图分类等),用于后续对话管理和主题管理

轻量化神经网络专题文献综述

本文列出了一些经典的轻型神经网络架构设计的集合,广泛用于移动设备等。轻量级网络的评论文章通常包含模型压缩和处理技巧,可参阅以下系列文章 https://github.com/senbinyu/Computer_Vision_Literatures 1. 综述文献推荐 Cheng Yu et al., 2017, A survey of model compression and acceleration for deep neural networks Cheng Jian et al., 2018, Recent advances in efficient computation of deep convolutional neural networks Li Yahui et al., 2018, Lightweight Network Research Based on Deep Learning: A Review 2. 各种网络的综述 shuffleNet, 2018 v1, Zhang Xiangyu 在ResNeXt中,使用组转换(几个通道); 在mobileNet中,是一个极端的情况,每个通道是一个组,分别进行传输。 在mobileNet-va论文中,1 * 1转换(逐点转换)占94%的MAdds。 ShuffleNet试图避免此问题。 而且,尚未利用不同信道之间的关系。 (组内的卷积不利于通道间信息交流) 通道转换(channel shuffle) 使用1 * 1组转换来替换1 * 1标准转换,以保存MAdds。 组数目,g通常不会太大,例如1,2,3,4,8等。太多的组可能导致每个组中的输入通道太少,从而可能导致性能变差。分成不同的group,然后洗牌式调换,permute,但是又不能用过多的group,否则会导致每组的通道太少

C++的optional解析

optional用法 1 问题引出 编程中我们可能会遇到要处理可能为空的变量,比如说容器,基本类型,或者说对象实例,我们简单看个例子: #include <string> #include <vector> #include <memory> struct Some { int some_i_ = 0; std::string some_str_; }; Some getSome(const std::vector<Some>& svec, int i) { auto iter = std::find_if(svec.begin(), svec.end(), [i](const Some& s) { return s.some_i_ == i; } ); if (iter != svec.end()) { return *iter; } return Some(); } int main() { std::vector<Some> someVec; someVec.push_back({1, "1"}); Some s = getSome(someVec, 1); s = getSome(someVec, 2); return 0; } 这里代码很简单,我们根据条件获取vector中一个元素,这个元素是个结构体,当满足条件时可以返回,但是没有找到时仍然要返回一个对象,到我们main函数甚至要花一些力气来判断有没有找到。如果没有找到在getSome返回空就好了,这样我们就来介绍optional

leetcode_56_合并区间_57_插入区间

文章目录 合并区间描述解题 插入区间描述解题 合并区间 描述 中等 给出一个区间的集合,请合并所有重叠的区间。 实例1: 输入: [[1,3],[2,6],[8,10],[15,18]] 输出: [[1,6],[8,10],[15,18]] 解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6]. 实例2: 输入: [[1,4],[4,5]] 输出: [[1,5]] 解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间 解题 看到这道题,就在数轴上画了起来 图中第一种情况,[1,3]和[2,6]重叠了[2,3],所以合并 判断条件是 2小于3 所以有重叠 可以设置第一个区间的范围为start和end 一旦end大于下一个区间的左端,就是有重叠,那么这两个区间合并的结果的左端就是start,右端是end和第二个区间的右端较大的值,也符合图上第二种情况 所以要满足上述情况,需要提前将各区间按照左端排序,就不用考虑start大小的问题 class Solution: def merge(self, intervals: List[List[int]]) -> List[List[int]]: if len(intervals) == 0: return [] intervals.sort(key=lambda x: x[0]) start = intervals[0][0] end = intervals[0][1] result = [] for interval in intervals[1:]: # 当前区间存在重叠,当前区间起始位置小于上一区间的结束位置 if interval[0] <= end: end = max(end, interval[1]) # 当前不存在重叠 else: result.

【ROS学习】catkin_make 编译的小问题总结

写在前面 本博客旨在记录一些自己在编译 ROS 包的时候遇到的问题与解决方法 一、package.xml 下编译依赖<build_depend> 标签不全 执行 catkin_make 指令,出现如下报错: Traceback (most recent call last): File "/opt/ros/kinetic/share/genjava/cmake/../../../lib/genjava/genjava_gradle_project.py", line 14, in <module> genjava.main(sys.argv) File "/opt/ros/kinetic/lib/python2.7/dist-packages/genjava/genjava_main.py", line 82, in main gradle_project.create(args.package, args.output_dir) File "/opt/ros/kinetic/lib/python2.7/dist-packages/genjava/gradle_project.py", line 152, in create raise IOError("could not find %s among message packages. Does the package have a <build_depend> on message_generation in its package.xml?" % msg_pkg_name) IOError: could not find lidar_localization among message packages. Does the package have a <build_depend> on message_generation in its package.

shell报错:-bash: [: ==: 期待一元表达式 解决方法 ([: ==: unary operator expected)

shell报错:-bash: [: ==: 期待一元表达式 解决方法 对shell脚本有不理解的可以查看https://blog.csdn.net/wulimingde/category_10285021.html 问题脚本: 1 #!/bin/bash 2 PRICE=$(expr $RANDOM % 1000) 3 TIMES=0 4 echo "商品的实际价格范围0~999,猜猜看是多少?" 5 while true 6 do 7 read -p "请输入你猜测的价格数目:" INT 8 let TIMES++ 9 if [ $INT -eq $PRICE ] 10 then 11 echo "恭喜你答对了,实际价格是 $PRICE" 12 echo "你总共猜测了 $TIMES 次" 13 exit 0 14 elif [ $INT -gt $PRICE ] 15 then 16 echo "太高了!" 17 else 问题报错: ./caizhi.sh: 第 9 行:[: -eq: 期待一元表达式

cv基础算法02-VGG

东阳的学习记录,坚持就是胜利! 文章目录 研究意义网络结构5个结构的相同点和不同点深度的增加并不会带来参数数量的大量增加Vgg16结构示意图Vgg的pytorch官方实现 Vgg的特点模型训练细节数据增强尺度扰动 模型初始化 模型测试细节多尺度测试稠密测试Multi-Crop测试Multi-crop & Dense 结果分析单尺度评估多尺度评估 模型融合(什么是模型融合)论文的关键点/创新点思考与展望 研究意义 开启小卷积核时代:3*3卷积核成为主流模型作为各类图像任务的骨干网络结构:分类、定位、检测、分割一系列图像任务大都有VGG为骨干网络的尝试 网络结构 VGG的网络结构如下: 由上图可以看到,论文共给出了5个结构(其中D为Vgg16, E为Vgg19)。 5个结构的相同点和不同点 相同点: 5个maxpool(降低分辨率)maxpool后,特征图通道数翻倍直至达到最大值5123个FC层进行分类输出maxpool之间采用多个卷积层堆叠,对特征进行提取和抽象 为什么从11层开始?(具体原因不知道) Goodfellow et al. (2014) applied deep ConvNets (11 weight layers) to the task of street number recognition 不同点: A:11层卷积 A-LRN:基于A增加一个LRN B: 第1,2个block中增加1个卷积33卷积 C: 第3, 4, 5个block分别增加1个11卷积,表明增加非线性有益于指标提升(每增加一层卷积伴随着一个ReLU层) D:第3, 4, 5个block的11卷积替换为33, E:第3, 4, 5个block再分别增加1个3*3卷积 深度的增加并不会带来参数数量的大量增加 下图为参数数量及其计算过程 Vgg16结构示意图 Vgg的pytorch官方实现 class VGG(nn.Module): def __init__(self, features, num_classes=1000, init_weights=True): super(VGG, self).__init__() self.features = features self.avgpool = nn.

《啊哈!算法》第二章 - 第一节 - 解密QQ号(Java实现)

《啊哈!算法》第二章 - 第一节- 解密QQ号(Java实现) 解密QQ号——队列 解密QQ号——队列 新学期开始了,小哈是小哼的新同桌(小哈是个小美女哦~),小哼向小哈询问 QQ号, 小哈当然不会直接告诉小哼啦,原因嘛你懂的。所以小哈给了小哼一串加密过的数字,同时 小哈也告诉了小哼解密规则。 规则是这样的:首先将第 1个数删除,紧接着将第 2个数放到 这串数的末尾,再将第 3个数删除并将第 4个数放到这串数的末尾,再将第 5个数删除…… 直到剩下后一个数,将后一个数也删除。按照刚才删除的顺序,把这些删除的数连在一 起就是小哈的 QQ啦。 现在你来帮帮小哼吧。小哈给小哼加密过的一串数是“6 3 1 7 5 8 9 2 4” 可以发现解密QQ号的过程就像是给数字 “ 排队 ”,我们每次从数字的最前面拿走两个数字,第 1 个扔掉,第 2 个放到数字的尾部。具体过程是这样的: 刚开始这串数是 “ 6 3 1 7 5 8 9 2 4 ” 第 1 次:删除 6 并将 3 放到数字末尾,这串数更新为 “ 1 7 5 8 9 2 4 3 ”; 第 2 次:删除 1 并将 7 放到数字末尾,即更新为 “ 5 8 9 2 4 3 7 ”;

位示图

位示图是利用二进制的一位来表示磁盘中的一个盘块的使用情况。当其值为“0”时,表示对应的盘块空闲;为“1”时,表示已经分配。有的系统把"0"作为盘块已分配的标记,把“1”作为空闲标志。(它们的本质上是相同的,都是用一位的两种状态标志空闲和已分配两种情况。)磁盘上的所有盘块都有一个二进制位与之对应,这样,由所有盘块所对应的位构成一个集合,称为位示图。 1. 定义: 位示图(bitmap)又叫位图,它的最小单元是一个bit。每个bit有两种取值1或0。 位示图是一种非常常用的结构,在索引,数据压缩等方面有广泛应用。 2. 实现 在C/C++中没有位示图这种数据类型,下面我们利用int来实现一个位示图类 每个int有sizeof(int)*8个bit #include<cassert> #include<iostream> using namespace std; #define INT_BIT sizeof(int) #define MAX 1024*1024*1024 #define SHIFT 5 #define UNIT INT_BIT << 3 // INT_BIT * 2^3 #define MASK 0x1f class BitSet { public: BitSet(int maxSize = MAX) :_msize(maxSize) { pBitset = new int[_msize / UNIT + 1]; } ~BitSet() { if (pBitset){ delete[] pBitset; } } void set(int i) { assert(i<_msize); // i >> SHIFT = i / (2^5) // i & MASK = i % int j = i; if (j>UNIT){ j >>= SHIFT; } pBitset[j] |= 1 << (i & MASK); } void clear(int i) { assert(i<_msize); int j = i; if (j>UNIT){ j >>= SHIFT; } pBitset[j] &= ~(1 << (i & MASK)); } bool test(int i) { assert(i<_msize); int j = i; if (j>UNIT){ j >>= SHIFT; } return (pBitset[j] & (1 << (i & MASK))); } private: int _msize; int *pBitset; }; int main() { BitSet bitset(100); int i = 80; bitset.

五分钟读完一篇文章之仿射变换

仿射变换(Affine Transformation)作为图像图形学领域常用的一种变换模型,主要描述一种二维坐标点对之间线性变换, 它保持二维图形的“平直性”(straightness,即变换后直线还是直线)和“平行性”(parallelness,即变换后平行线还是平行线)。 仿射变换的定义 仿射变换通过一系列原子变换的复合来实现,其中包括:尺度(Scale,也叫“缩放”)、旋转(Rotation)、平移(Translation)、偏移(Shear,也叫“剪切”)和翻转(Flip)。同时值得注意的是,三对不共线的二维对应坐标点之间确定唯一的仿射变换。 仿射变换可以分解为一个线性变换接上一个平移变换组成(显然,仿射变换不符合“齐次可加性”),所以仿射变换是线性变换的超集。 一般情况下,为了计算方便(将平移分量融入仿射变换矩阵)会使用齐次坐标,将原二维坐标增加一个维度,所以大部分情况下仿射变换的变换矩阵如上公式所示,从公示中可以很清晰的看出其含有六个自由度(a,b,c,d,e,f) 。 仿射变换的参数估计 因为仿射变换矩阵含有六个自由度,所以理论上讲我们至少需要三对不共线的二维对应坐标点,才可以求解仿射变换矩阵(单个二维坐标点含有x分量与y分量,可以列出两个线性方程)。当多对坐标点求解时构成超定方程组,可以基于最小二乘或者SVD等方法进行求解。 与透视(投影)变换的区别 仿射变换是一种二维坐标到二维坐标之间的映射,而透视(投影)变换是将目标经透视投影到一个新的平面,它是二维(x,y)空间到三维(X,Y,Z)空间,再到另一个二维(x’,y’)空间的映射。 总结 图中两种仿射变换矩阵排列方式不同,是因为左乘与右乘矩阵互为转置的原因。图像方面仿射变换的详细介绍可以参考:数字图像处理(冈萨雷斯-第三版)。

MTK6580(Android6.0)-camera 驱动分析

一、MTK6580 平台 Camera 驱动整体框架 mtk平台三大件调试中,camera的调试难度最大,问题也就最多,为此特地分析了一下整个camera驱动部分 实现过程,以下为camera驱动框架序列图: 从图中可以看出,整个框架分为三个部分hal部分逻辑调用,kernel层的通用驱动sensorlist.c 和具体IC的驱动 xxxx_mipi_raw.c,kernel起来后不会直接去访问硬件sensor,而是会注册相关的驱动,之后Android系统起来后 会启动相关的服务如:camera_service,在camera服务中会直接去访问hal,kernel驱动,进而操作camera。 为此本文也穿插了部分hal层的调用,至于camera_service后面章节会继续补充。 二、 Camera 驱动的具体实现 ========================HAL 层部分初始调用======================== 文件:vendor/mediatek/proprietary/hardware/mtkcam/common/module_hal/devicemgr/CamDeviceManagerBase.cpp [cpp] view plain copy int32_t CamDeviceManagerBase:: getNumberOfDevices() { … mi4DeviceNum = enumDeviceLocked(); … } int32_t CamDeviceManagerBase:: getNumberOfDevices() { … mi4DeviceNum = enumDeviceLocked(); ... }文件:vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6580/devicemgr/CamDeviceManagerImp.cpp [cpp] view plain copy int32_t CamDeviceManagerImp:: enumDeviceLocked() { … //—————————————————————————— #if ‘1’==MTKCAM_HAVE_SENSOR_HAL // IHalSensorList*const pHalSensorList = IHalSensorList::get(); size_t const sensorNum = pHalSensorList->searchSensors(); #endif … return i4DeviceNum; } int32_t CamDeviceManagerImp:: enumDeviceLocked() { … //—————————————————————————— if ‘1’==MTKCAM_HAVE_SENSOR_HAL // IHalSensorList*const pHalSensorList = IHalSensorList::get(); size_t const sensorNum = pHalSensorList-&gt;searchSensors(); endif .

5.整数规划

整数规划 1.定义 规划中的变量(部分或全部)限制为整数时,称为整数规划。若在线性规划模型中,变量限制为整数,则称为整数线性规划。目前所流行的求解整数规划的方法,往往只适用于整数线性规划。目前还没有一种方法能有效地求解一切整数规划。 2.分类 变量全限制为整数时,称纯(完全)整数规划。变量部分限制为整数的,称混合整数规划。 3.特点 整数规划解和实数规划解可能一致,也可能不一致,甚至可能无解。 这里给出两个例子: 4.三种常用方法 隐枚举法—求解“0-1”整数规划匈牙利法—解决指派问题(“0-1”规划特殊情形)蒙特卡洛法—求解各种类型规划。 5.隐枚举法—求解“0-1”整数规划 定义:引入变量y取0或1,称为0 − 1变量,或称二进制变量。 好处:可以把相互排斥的条件转换成普通条件 6.指派问题 数学模型 matlab代码: c=[3 8 2 10 3;8 7 2 9 7;6 4 2 7 5 8 4 2 3 5;9 10 6 9 10]; c=c(:); a=zeros(10,25); for i=1:5 a(i,(i-1)*5+1:5*i)=1; a(5+i,i:5:25)=1; end b=ones(10,1); intcon=1:25; [x,fval] = intlinprog(c,intcon,[],[],a,b,zeros(25,1),ones(25,1)); x=reshape(x,[5,5]),fval 结果: 蒙特卡洛法—求解各种类型规划 示例1: matlab代码: clc, clear x=unifrnd(0,12,[1,10000000]); y=unifrnd(0,9,[1,10000000]); pinshu=sum(y<x.^2 & x<=3)+sum(y<12-x & x>=3); area_appr=12*9*pinshu/10^7 示例2: matlab求解

java大数据开发训练营--前端基础h5+css+js

题记: 文章内容输出来源:拉勾教育大数据开发高薪训练营 本篇文章是java学习课程中的一部分笔记。 本博文主要是记录一些基础的知识点,通过实操更容易理解 这章主要讲的是前端的基础知识, HTML HTML语法 特点 HTML文件不需要编译,直接使用浏览器阅读即可 HTML文件的扩展名是*.html 或 *.htmHTML结构都是由标签组成标签名预先定义好的,我们只需要了解其功能即可。标签名不区分大小写 <A name="属性值" age="18" >标签体</a> 通常情况下标签由开始标签和结束标签组成。例如: <a 属性名="属性值" href="01_html">标签体</a> 如果没有结束标签,建议以/结尾。例如: <img /> 基本标签 1.标题标签 HTML提供 <hn> 系列标签,用于修饰标题,包含: <h1>、<h2>、<h3>、<h4>、<h5>、<h6> 。 <h1> 定义最大的标 题。 <h6> 定义最小的标题 特点: 1. 加了标题的文字会变的加粗,字号也会依次变大。 2. 一个标题独占一行。 2.段落标签 <p></p> 标签会自动在其前后创建一些空白。 标签语义:可以把 HTML 文档分割为若干段落 换行标签<br> 在 HTML 中,一个段落中的文字会从左到右依次排列,直到浏览器窗口的右端,然后才自动换行。如果希望某段文本强制换行显示,就需要使用换行标签 ,<br> 标签插入一个简单的换行符。 标签语义:强制换行。 特点: 1. 是个单标签。 2. 标签只是简单地开始新的一行,跟段落不一样,段落之间会插入一些垂直的间距。 3. 字体标签 <font> 规定文本的字体、字体尺寸、字体颜色。 4.文本格式化标签 为文字设置粗体、 斜体 或下划线等效果,这时就需要用到 HTML 中的文本格式化标签,使 文字以特殊的方式显示。

windows10 关闭指定端口

今天在Windows10电脑上安装zk和dubbo,运行Tomcat总是包端口占用异常,重启了一次电脑后觉得一直重启不是个好办法,于是学会了用命令关闭进程的技能 查看指定端口的使用情况 使用命令: netstat -ano | findstr 端口号 1 如下所示: 查看端口时可能会出现以下两种情况,即倒数第二个参数可能是LISTENING,或者TIME_WAIT , 当参数为 TIME_WAIT时,表示占用此端口的那个进程正在改变状态,稍等一下可能这个进程就结束了。参数为LISTENING 时,就需要手动关闭这个进程了,最后一个参数是这个进程的进程号,即图中8168 手动关闭进程 方法一: 运行命令: tasklist | findstr 进程号 1 查看进程的详细信息,第一个参数是启动该进程的程序,即图中java.exe,使用任务管理器将其关闭 方法二: 运行命令: taskkill -PID 进程号 -F 1 执行此命令强制关闭指定进程号的进程

spring aop运行时执行栈分析

问题: 1.spring aop的切面方法是怎样被添加的? 2.spring aop的切面方法是怎样被执行的? spring aop的切面方法是怎样被添加的? 首先定义3个MethodInterceptor Advisor : ExposeInvocationInterceptor【spring默认添加的,why?】ScfMethodLogger【通过继承StaticMethodMatcherPointcutAdvisor】AspectJAroundAdvice【aspectJAdviceMethod是LoggerAspect】 spring启动时,首先会最大努力寻找所有的bean定义,包括上面的Advisor定义。然后spring容器对bd进行实例化和初始化,初始化后,容器会执行代理proxy配置,此时就会把上面的advisor添加到执行chain里。 代码的参考位置: org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean spring aop的切面方法是怎样被执行的? 调用栈如下: org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation(this$123)#proceed org.aopalliance.intercept.MethodInterceptor#invoke(this$123)【MethodInterceptor:ExposeInvocationInterceptor】 org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation(this$123)#proceed org.aopalliance.intercept.MethodInterceptor#invoke(this$123)【MethodInterceptor:ScfMethodLogger】 org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation(this$123)#lllll org.aopalliance.intercept.MethodInterceptor#invoke(this$123)【MethodInterceptor:AspectJAroundAdvice】 org.springframework.aop.aspectj.AspectJAroundAdvice#lazyGetProceedingJoinPoint【封装this$123为ProceedingJoinPoint,即MethodInvocationProceedingJoinPoint$10986】 org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethod(org.aspectj.lang.JoinPoint, org.aspectj.weaver.tools.JoinPointMatch, java.lang.Object, java.lang.Throwable) org.springframework.aop.aspectj.AbstractAspectJAdvice#argBinding org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethodWithGivenArgs java.lang.reflect.Method#invoke【this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);】 com.zhuanzhuan.hunter.zeus.po.aspect.LoggerAspect#doAround【参数是MethodInvocationProceedingJoinPoint$10986】 org.aspectj.lang.ProceedingJoinPoint#proceed()【ProceedingJoinPoint:MethodInvocationProceedingJoinPoint$10986】 this.methodInvocation.invocableClone()【this.methodInvocation=this$123,return CglibMethodInvocation$14252】 CglibMethodInvocation$14252.proceed org.springframework.aop.framework.ReflectiveMethodInvocation#invokeJoinpoint org.springframework.aop.support.AopUtils#invokeJoinpointUsingReflection real method 为什么要invocableClone? public abstract org.aopalliance.intercept.MethodInvocation invocableClone() Create a clone of this object. If cloning is done before proceed() is invoked on this object, proceed() can be invoked once per clone to invoke the joinpoint (and the rest of the advice chain) more than once.

彻底清除RecycleView,防止复用

RecycleView的优点不用多说,不过成也复用败也复用 需求思路问题思路2解决方案 需求 自己工程里引用IM即时通讯,正常情况下一个界面一个layout,也就是一个RecycleView,对应一个adpter,对应一组数据,但是功能需求需要在该界面添加,只看某某功能 。 思路 点击只看某某时,重新为layout设置数据 问题 按照上面思路,的确可行,但是,如果数据中只有文本和图片还好,如果还有自定义消息或者其他就会出现,严重的复用(覆盖现象)---- 我碰到的是,图片总是会覆盖自定义消息的现象。 思路2 第一次进来时,能够正常加载显示,但是点击只看某某 时(切换数据),重新渲染最初的数据就会出现覆盖情况。两者的区别只有,在界面渲染时一个是重新渲染,一个是从0渲染。那么解决问题的方法就是:数据切换时,让RecycleView从0渲染。 解决方案 mDataSource为数组 swapAdapter()强制转换adpter 以下方法可以清空recycleview,避免我遇到的问题出现的复用 public void cleanData(){ //清除复用 if (mDataSource != null) { mDataSource.clear(); if (mRecycleView != null) { mRecycleView.removeAllViews(); mRecycleView.removeAllViewsInLayout(); mRecycleView.swapAdapter(this,true); // mRecycleView.setRecycledViewPool(new RecyclerView.RecycledViewPool()); //也可以,只是个人认为下面这个更好 mRecycleView.getRecycledViewPool().clear(); notifyDataSetChanged(); } } }

微服务项目(maven父子级项目)怎么打包

项目层级结构: common中的是没有main方法的工具类,service中的是有main方法的业务代码。 打包须知 这种微服务项目或者说是maven父子级项目打包要解决的问题就是具体业务代码依赖工具类代码,利用idea的maven插件可以很方便做到。 在cloud_parent,common,service这些上层文件夹管理模块中,添加<packaging>pom</packaging>在没有main方法的工具模块中只添加<packaging>jar</packaging>在具体的业务代码模块中添加: <packaging>jar</packaging> <build> //maven的打包插件 <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> //打包规则,打包时将resource文件夹打包进去 <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.yml</include> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.yml</include> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build> 根据maven的继承特性,我在service文件夹模块中添加 这样,只需在每个有mian方法的具体的业务模块中的pom中添加: <build> //maven的打包插件 <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> 最终打包:只需对最顶层模块进行clean,install,在每个模块对应的target目录中找到jar包。 最后附上maven配置:

电信光纤天翼网关将默认的路由模式修改为桥接模式

前两年将家里的电信宽带升级到光纤,光猫也随之进行了升级,当时升级好后,电信工作人员介绍说新的光猫带有wifi功能,如果连接路由器可以不用配置路由器的拨号设置,说是升级到光纤后可以直接连接网线上网,不用再拨号了。当时也没怎么在意,网线连上路由器之后,果然没做宽带的账号设置就可以正常上网了。 最近在使用一个软件客户端的时候需要设置宽带拨号的方式更换IP才能使用某个功能,然后才发现家里的宽带升级到光纤后,无法使用原来的拨号方式上网了。通过网络搜索,是因为升级光纤后,将连接的模式设置为路由模式,导致无法使用拨号上网。方案则可以通过天翼网关将路由模式修改为桥接模式,然后就可以使用拨号上网。但是家里的天翼网关和网上的不大一样,花了一些时间才将连接模式修改为桥接模式实现拨号上网。 现在将操作的一些步骤做下记录,以便其他博友遇到该问题的时候可以提供一些指引。 天翼网关账号信息 首先查看家里的光猫背后,找到天翼网关的配置地址(192.168.1.1)、账号(useradmin)和密码(******),如下图所示: 浏览器登录天翼网关 电脑通过网线与光猫连接,然后后打开浏览器,访问配置地址(http://192.168.1.1),输入光猫后面的账号(useradmin)和密码(******)登录。 按照网友的说法,登录进去找到,通过“网络”-》“宽带设置”就可以修改连接模式。但是我们登录成功后,界面如下并没找到设置的菜单以及对应的页面。博主陷入了怀疑中,怀疑自己的光猫和网友的不一致,是不是无法自己修改连接模式,然后疯狂的搜索尝试求证。 修改天翼网关连接模式 通过不断的搜索,发现另一个设置的地址(http://192.168.1.1:8080/),浏览器访问,输入光猫后面的账号(useradmin)和密码登录。注意:有网友说需要获取并使用超级账号telecomadmin才能设置,博主这里直接使用光猫后面的账号即可设置。 登录成功后,在“状态”-》“配置向导”中设置连接模式,默认是路由方式,下图是博主修改为桥接方式后的截图。 测试拨号上网 上网的模式修改为桥接模式之后,在电脑上使用拨号连接测试下,win10系统通过控制面板,设置拨号上网,如下所示: 输入宽带账号和密码之后,宽带连接成功,如下图所示。至此我们通过天翼网关将默认的路由模式修改为桥接模式实现了拨号上网。博主使用的软件客户端使用拨号方式更换IP的功能也能够正常使用。 通过以上步骤,将电信光纤的路由模式修改为桥接模式,实现了拨号上网。中间也遇到一些问题,天翼网关的登录地址未使用正确,修改天翼网关的页面与网上描述的不一致,导致花了很多时间,甚至怀疑自己家的天翼网关无法修改连接模式,只能由电信工作人员远程才能修改。通过不断的尝试,最终找到方法将家里的电信光纤设置为桥接模式实现了拨号上网。这里以博客的方式做一个记录,同时也希望可以帮助到其他博友。

shiro SecurityUtils.getSubject().getPrincipal()得到null 的解决方法

1 问题的由来 自定义的Realm 继承 AuthorizingRealm ,本想在doGetAuthenticationInfo 认证方法中通过Object o = SecurityUtils.getSubject().getPrincipal() 得到前端传来的信息的,然后通过instanceof 判断 o 的到底是什么类,来判断到底是用户登录还是管理员登录。 结果发现SecurityUtils.getSubject().getPrincipal() 得到的是null 2 解决方法 采用装饰类的思路解决 由于 Controller 层中 subject.login(authenticationToken); 登录的时候传递给Shiro的类是UsernamePasswordToken 类,该类对象会原封不动作为 token 传递到 doGetAuthenticationInfo 方法里。既然如此就可以将 UsernamePasswordToken 类进行装饰,然后给它加一个新的成员变量传递我想传递的信息,这样在 doGetAuthenticationInfo 方法中就可以获取到了。 装饰类源码如下: package com.wu.demoblog.decorate; import lombok.Data; import org.apache.shiro.authc.UsernamePasswordToken; /** * UsernamePasswordToken 的装饰类,为它添加一些东西后再使用 * @Author :吴用 * @Date :2020-08-14 22:19 * @Version :1.0 */ @Data public class UsernamePasswordTokenChild extends UsernamePasswordToken { private Object msg; //这里是新加的成员变量 // 注意构造方法是不继承的,所以需要自己写一下,用 idea 可以快速构建下面这些构造方法 public UsernamePasswordTokenChild() { super(); } public UsernamePasswordTokenChild(String username, char[] password) { super(username, password); } public UsernamePasswordTokenChild(String username, String password) { super(username, password); } public UsernamePasswordTokenChild(String username, char[] password, String host) { super(username, password, host); } public UsernamePasswordTokenChild(String username, String password, String host) { super(username, password, host); } public UsernamePasswordTokenChild(String username, char[] password, boolean rememberMe) { super(username, password, rememberMe); } public UsernamePasswordTokenChild(String username, String password, boolean rememberMe) { super(username, password, rememberMe); } public UsernamePasswordTokenChild(String username, char[] password, boolean rememberMe, String host) { super(username, password, rememberMe, host); } public UsernamePasswordTokenChild(String username, String password, boolean rememberMe, String host) { super(username, password, rememberMe, host); } } 在 Controller 层使用该对象,把自己想要的信息放进该对象中,在 Realm 中将 token 强转成该类对象,然后就可以通过 getMsg() 方法提取出来自己在Controller层放入的内容了。

【Git系列】GitLab使用教程(详细)

转载自:https://blog.csdn.net/justlpf/article/details/80681853 目录 一、基本操作 1.登录: 2.修改密码: 二、项目管理 1.新建项目 2.编辑或删除项目 三、用户管理(管理员使用,非管理员跳过此步骤) 1.新建用户 2.编辑和删除用户 四、组管理(管理员使用,非管理员跳过此步骤) 1.新建组 2.编辑或删除组 3.添加组成员 4.修改成员的权限(owner用户操作) 5.从组管理添加项目 五、权限说明 一、基本操作 1.登录: 在浏览器地址栏输入http://10.6.2.160/ 回车,进入登陆界面。 在上图红框区域登陆自己的账户密码。 2.修改密码: 登录成功后点击左侧工具栏目Profile Settings ------ Password -------修改密码-------Save password。 Tips: 点击GitLab的logo,可以从任何界面回到本页 二、项目管理 可以根据需要选择新建项目、新建组合新建用户 1.新建项目 如下图所示新建项目: 创建时可以选择在自己用户下创建或者某个群组内创建 a. 项目名称,项目名称可以为字母、数字、空格、下划线、中划线和英文点号组 成,且必须以字母或数字开头,不能使用中文 b. 项目描述 c.可见性(库类别) 私有库:只有被赋予权限的用户可见 内部库:登录用户可以下载 公开库:所有人可以下载 根据实际情况填写完各项之后,点击创建项目,项目创建成功 提示通过SSH方式拉取推送项目代码必须要导入SSH key,这个稍后再介绍。 项目地址有HTTP和SSH两种方式-------可发送给开发人员下载和初始化项目 2.编辑或删除项目 主页左边菜单栏--------Project 右上角的齿轮状按钮--------编辑项目 右下角删除项目。 或者点击Admin Area 三、用户管理(管理员使用,非管理员跳过此步骤) 1.新建用户 点击顶端的Admin Area按钮 可以进入管理页面 1) 姓名(可以是中文) 2) 用户名(可以为字母、数字、空格、下划线、中划线和英文点号组成,且必须以字母或数字开头,不能使用中文) 3) 邮箱地址(首次接收密码) 4) 建项目的数量限制

自动化测试的知识

自动化测试的知识 Selenium是一个用于测试网站的自动化测试工具,支持各种浏览器包括Chrome、Firefox、Safari等主流界面浏览器,同时也支持phantomJS无界面浏览器。 说起无界面浏览器呢,有一个叫做 phantomjs 的玩意。 网上有很多selenium + phantomjs 达到完全模拟浏览器操作的案例。 如果你喜欢,更多用法可以参考文末地址。 但是呢本文不推荐它,为甚? 因为你使用phantomjs 的时候就会发现: selenium已经放弃PhantomJS了,建议使用火狐或者谷歌无界面浏览器。 所以还是先 【弃用掉PhantomJS早点改用推荐的Headless Chrome比较好】 headless也是一款无界面无痕的浏览器。 chome59以上版本对应的Chromedriver可以支持headless模式。 这些放到以后再说吧,今天就先到这里了。

QT-GraphicScene大于GraphicView时,场景居中问题

使用环境: PySide2 + QT5.12.8 + Python3.7 + Windows10 QT或者PyQt解决思路类似。 问题描述: 由于项目需要,场景需要较大的区域,因此初始化时,场景的面积大于视图窗口的面积,这种情况下,会出现滚动条,且软件会默认将视图聚焦与场景中间,而不是左上角,不符合通常的软件操作习惯,因此需要设置将视图窗口聚焦于场景左上角。 解决方案: 下述代码仅作参考,关键代码为self.graphView.centerOn(0, 0),通过这句代码将视图中心设置为左上角。 from PySide2.QtWidgets import QApplication, QMainWindow, QGraphicsScene, QGraphicsView class UIMainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(UIMainWindow, self).__init__(*args, **kwargs) self.showMaximized() # 最大化窗口 self.graphView = QGraphicsView(self) # 视图窗口大小小于窗口大小 self.graphScene = QGraphicsScene() self.desktop = QtWidgets.QApplication.desktop() self.setSceneRect(0, 0, self.desktop.width() * 1.2, self.desktop.height() * 1.2) # 设置场景范围,令其大于窗口大小 self.graphView.setScene(self.graphScene) # 下面这句代码必须在上行代码之后,否则无效 self.graphView.centerOn(0, 0) # 在设置好场景后,将view视图中心设置为左上角 self.setCentralWidget(self.graphView) …… 参考文献 [1] QGraphicsView大于QGraphicsScene时出现滚动条时,改变scene的显示位置 以上,欢迎交流。

idea 枚举快速_快速可枚举的枚举

idea 枚举快速 I had a very basic knowledge of Codable which was limited to how to convert JSON data into primitive types such as String, Int, Bool, etc. or how to work with nested JSON objects and Arrays. I have been using it for quite a long time and it was sufficient for the project code to work. But Codable is more powerful than this. 我对Codable有非常基础的知识,其知识仅限于如何将JSON数据转换为基本类型(例如String , Int , Bool等)或如何使用嵌套的JSON对象和数组。 我已经使用了很长时间了,足以使项目代码正常工作。 但是Codable比这更强大。 In this article, we will discuss a scenario where the JSON we receive has an enum type.

神经网络骨架network backbones

本文将列出神经网络几种骨架结构的历史沿袭,对从框架上了解backbones有重要帮助。阅读时间约10分钟。更多的机器视觉文献回顾可参阅: https://github.com/senbinyu/Computer_Vision_Literatures network backbones是神经网络最重要的体系结构。 1. Review papers 以下列出一些综述文章,推荐阅读第二篇 Neena Aloysius and Geetha M, A Review on Deep Convolutional Neural Networks, 2017 A bit old and not include many state-of-art research, refer to paper A Review on Deep Convolutional Neural Networks Elhassouny, Azeddine et al, Trends in deep convolutional neural Networks architectures: a review, 2019. Recommand. Reviewed most of the CNN backbones, refer to paper Trends in deep convolutional neural Networks architectures: a review

lotus导出钱包

lotus导出钱包 1,查看钱包2,导出钱包3,验证钱包 1,查看钱包 lotus wallet list # lotus wallet list t3... lotus wallet balance 2,导出钱包 # lotus wallet export t3... > /root/wallet.keyinfo 3,验证钱包 cat ntwk-calibration/lotus/Makefile | grep lotus-shed # cd ntwk-calibration/lotus/ # make lotus-shed # cp lotus-shed /usr/local/bin/ 验证钱包 # lotus-shed keyinfo info wallet.keyinfo bls t3...

【springBoot】项目热部署(包括简单类的修改)

步骤 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> application.yml spring: devtools: restart: enabled: true #设置开启热部署 additional-paths: src/main/java #重启目录 exclude: WEB-INF/** freemarker: cache: false #页面不加载缓存,修改即时生效 idea配置 File-Settings-Compiler-Build Project automaticallyctrl + shift + alt + / ,选择Registry,勾上 Compiler autoMake allow when app running

运行python文件报(unicode error) ‘unicodeescape‘ codec can‘t decode bytes in position 2-3: truncated \UXXX

在我写的python读取文件的代码是这样的: with open('C:\Users\Administrator\Desktop\cat.jpg','wb') as f: f.write(resp.content) 执行的时候会报这样的错误 原因分析:在windows系统当中读取文件路径可以使用\,但是在python字符串中\有转义的含义,如\t可代表TAB,\n代表换行,所以我们需要采取一些方式使得\不被解读为转义字符。对于此问题,目前有是那种解决的办法: 1、在路径前面加r,即保持字符原始值的意思。 with open(r'C:\Users\Administrator\Desktop\cat.jpg','wb') as f: f.write(resp.content) 2、替换为双反斜杠 with open('C:\\Users\\Administrator\\Desktop\\cat.jpg','wb') as f: f.write(resp.content) 3、替换为正斜杠 with open('C:/Users/Administrator/Desktop/cat.jpg','wb') as f: f.write(resp.content)

Android HAL 层框架分析以及代码示例

目录 一 硬件抽象层概述 二 开发Android硬件驱动程序 三 开发Android硬件抽象层模块 3.1 硬件抽象层模块文件 命名规范 3.2 硬件抽象层模块结构体 以及 硬件抽象层设备结构体 定义规范 3.3 编写硬件抽象层模块接口 四 为Android硬件抽象层编写JNI方法供硬件服务程序调用 4.1 JNI实现 4.2 声明JNI注册方法 4.3 添加JNI方法代码 五 开发Android硬件访问服务 5.1 定义硬件访问服务接口 5.2 实现硬件访问服务 最后 启动硬件访问服务 一 硬件抽象层概述 Android系统的硬件抽象层(Hardware Abstract Layer, HAL)运行在用户空间中,它向下屏蔽硬件驱动模块的实现细节,向上提供硬件访问服务。通过硬件抽象层,Android系统分为两层来支持硬件设备,其中一层实现在用户空间(User Space),另外一层实现在内核空间(Kernel Space)。传统的Linux系统把对硬件的支持完全是实现在内核空间,即把对硬件的支持完全实现在硬件驱动模块中。 问题:Android系统为什么要把对硬件的支持划分为两层来实现呢?把硬件抽象层和内核驱动整合在一起放在内核空间不可行吗?从技术实现的角度来看,是可以的,然而从商业的角度来看,把对硬件的支持逻辑都放在内核空间,可能会损害厂家的利益。我们知道Linux内核源代码是遵循GPL协议的,如果我们在Android系统所使用的Linux内核中添加或者修改了代码,那么就必须将其公开,所以,如果Android系统想Linux系统一样,把对硬件的支持完全完全是现在linux硬件驱动中,那么就是说这些实现是开源的,相当于暴露的硬件的实现细节和参数,损伤了厂商的利益。因此,Android才会想到把对硬件的支持分成硬件抽象层和内核驱动层,内核驱动层只提供简单的访问硬件逻辑,例如读写硬件寄存器的通道,至于从硬件中读到了什么值或者写了什么值到硬件中的逻辑,都放在硬件抽象层中去了,这样就可以把商业秘密隐藏起来了。也正是由于这个分层的原因,Android被踢出了Linux内核主线代码树中。 先来一张代码概览图: 二 开发Android硬件驱动程序 为了方便描述,我们将为一个虚拟的字符硬件设备开发去驱动程序,这个虚拟的字符硬件设备只有一个寄存器,它的大小为4个字节,可读可写,由于这个字符设备是虚拟的,而且只有一个寄存器,因此我们将它命名为 fake register,并且将其对应的驱动名称命名为 freg。 具体驱动程序 : #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/ioctl.h> #include <linux/mm.h> #include <asm/uaccess.h> #include <linux/blkdev.h> #include <linux/init.

LTE网络中的EPS和PDN

LTE网络是一个只有PS域的全IP的移动网络,没有CS域,因此UE必须连接到至少一个PDN (Packet Data Network) 才能执行数据通信的工作。在EPS系统中,PDN指的是外部的数据网络(相对于LTE运营商而言),例如互联网、企业专用网等,使用APN作为PDN的标示。P-GW位于EPC和PDN的边界,EPS Bearer存在于UE和P-GW之间。通常情况下,EPS承载可以看作是UE和P-GW之间的逻辑电路,EPS承载取代了UMTS网络中的PDP。 在UE的第一条Initial Attach中就包含了附着请求(attach request)和PDN连接请求(PDN connectivity request), PDN连接请求的目的是会在UE和P-GW之间建立默认承载(default bearer),默认承载会保持连接直到UE分离(detach)LTE网络。 一般来说,每个PDN连接都对应着一个默认承载(Default Bearer)和一个IP address,只有当UE和PDN都支持IPv4、IPv6双协议栈时,一个PDN连接才有可能对应2个Default Bearer和IP Address,UE在此PDN连接的有效期内将会一直保持此Default Bearer。如果UE存在与多个PDN的连接,那么UE就有多个Default Bearer和IP地址。默认承载的QoS参数可以来自于HSS中获取的签约数据,也可以通过PCRF交互或者基于本地配置来改变这些值。为了给相同IP地址的UE提供不同QoS保障的业务,需要在UE和PDN之间建立一个或多个专有承载(Dedicated EPS Bearer),每个专有承载有自己的QoS,运营商可以根据PCRF(Policy And Charging Resource Function)定义的策略将不同的数据流映射到相应的专有承载上。专有承载的创建或修改只能由网络侧来发起,并且承载的QoS参数总是由核心网来分配。 PDN连接请求可带参数是APN(可选)、UE支持的PDN类型(IPv4,IPv6,IPv4v6等)、PCO(DNS地址请求)、静态IP(可选)。如果APN为空,就采用缺省APN,缺省APN是由HSS提供的,也就说缺省APN由SIM卡决定。是否支持静态IP也是由采用SIM卡决定的。 EPS承载不完全等同于UMTS网络中的PDP。相同点是用户数据的传输一定位于某个EPS承载或者PDP上。不同点是:(1)每个PDP都一个IP地址,而EPS承载的IP地址是它所归属的PDN连接的IP地址;(2)EPS承载有QoS的保障,而PDP是没有的。 PDN PDN(Packet Data Network分组数据网络),严格意义上讲可以分为内部 PDN 和外部 PDN:内部 PDN 即 EPS 系统中的分组数据网络,是 EPS 系统实体(e.g. MME、HSS、SGW、PGW、PCRF)之间的网络通信;而外部 PDN 即 EPS 系统之外的分组数据网络,例如:3GPP 网络 CDMA1X、Internet(互联网)、IoT(Internet of Things,物联网)、IMS(VoLTE 业务)、行业应用(e.g. 银行专线、证券专线),以及非 3GPP 网络 WiMAX 等。内、外 PDN 通过 PGW 作为网关。 为了方便描述,在普遍的语境中,“PDN” 一般指代的都是外部 PDN,所以我们也常常简要的将 PGW 阐述为 EPS 和 PDN 之间的网关。若将 EPS 作为一个整体,那么从 PDN 的角度来看,EPS 就可以抽象的理解为是 UE 到 PDN 之间的接入网。

阿里云、腾讯云、华为云哪个好?迄今最全面的云服务评测报告出炉

腾讯云、阿里云、华为云,这几家云计算厂商到底哪家强,各家有各家的说法,今天就来跟你聊一聊,各家厂商的云计算技术到底怎么样。我选取了国内知名度比较高的几家厂商,通过弹性计算能力(云计算的核心能力)、数据库能力、存储能力、人工智能(大数据)、CDN 业务、域名服务等几个方面来评判,看看哪个才是适合你的云计算厂商。 免责声明:本文所发表的观点,由于个人能力和资源所限,仅代表个人意见和客观结果,如有不同意见,欢迎探讨。本文的写作初衷是为了给广大云计算用户在选择云产品时做为参考。 AWS(中国) AWS 作为云计算的老大哥,在弹性计算方面,发展其了以EC2 为首的计算服务矩阵,提供了10 项不同的产品,联合来使用,满足用户对于计算能力的要求。但是产品缺乏场景,无法满足用户的直接需求,需要用户自行构建一些计算的服务。给 4.5 分。 在数据库方面,AWS 提供的数据库类型是相当丰富的,六种常见的SQL 数据库(Amazon Aurora、PostgreSQL、MySQL、MariaDB、Oracle和Microsoft SQL Server)、特有的DynamoDB、基于Redis 和Memcahed 的ElastiCache 产品,给你以最完美的用户体验。给 5 分。 在存储方面,AWS 的S3 存储服务可以说是鼎鼎大名,不少人都听说过或使用过,AWS 还推出其块存储和弹性文件存储系统,以及PB 级文件存SnowBall。不过本身由于产品类型的限制,对应某些特定场景下的用户需求,无法很好的满足,需要用户进行一定的妥协,给 4 分。 在安全方面,AWS 提供身份认证系统、证书系统、WAF 系统、密钥管理系统等多项安全、合规方面的服务,来帮助用户更好的规范化自己的业务,实现更好的业务拓展。给 4 分。 在大数据方面,AWS 投入了大量的精力研发了EMR、QuickSight、Lex、Polly等产品,来帮助用户去更好的进行大数据研发和人工智能的研究。给 4 分。 在CDN 方面,AWS 在全球范围内建设了近70 个CloudFront 节点,足够满足用户出海的需求,可惜的是没有一个国内节点,如果当前业务主力仍在国内,可能并不适合使用AWS 的CloudFront。给 3.5 分。 AWS 并没有提供域名注册的服务,不过其提供的DNS 服务Route 53 也属于非常出名的,很多大型企业都在使用该服务,给个及格分 3 分。 Azure (中国) 在云计算的基础能力-弹性计算上,Azure 似乎更倾向于由用户自行实现场景化,所提供的计算服务较为基础,只有虚拟机、虚拟机规模集(集群)、应用服务、批处理等6 项服务,由用户自身借助虚拟机实现场景化,给 4.5 分。 在数据库方面,Azure 着重其SQL Server 产品,围绕SQL Server 提供了不少的服务。不过也没有忘记广大Linux 用户的需求,提供了MySQL 产品和Redis 缓存,以及其所特有的DocumentDB,给 5 分。