一、安装 pymouse 版本介绍:python 版本 3.7.6,pymouse==pymouse-1.0,pyHook==pyHook-1.5.1
1、第一步 安装 pymouse pip install -i https://mirrors.aliyun.com/pypi/simple/ --upgrade pymouse 2、第二步:需要安装 PyUserinput、pyHook 若不安装PyUserinput,导入包pyMouse则报错: ModuleNotFoundError: No module named ‘windows’ 但安装 PyUserinput 之前需要先安装 pyHook,pyHook下载路径: 搜索 pyhook 下载
安装pyHook需要注意几点: ① pyHook 对应的版本最好与python版本相同,我的python版本为 3.7.6,因此下载 cp37 ② pyHook 对于3.8及3.8以后的python版本不在维护 下载下来 .whl 文件后用 pip install 进行安装
安装方式: pip install whl文件路径 3、第三步:安装 PyUserinput pip install -i https://mirrors.aliyun.com/pypi/simple/ --upgrade PyUserinput 二、PyMouse、PyKeyboard 库简单实用 1、Pymouse简单使用 from pymouse import PyMouse m = PyMouse() a = m.position() #获取当前坐标的位置 print(a) m.
psexec是sysinternals的一款强大的软件,通过他可以提权和执行远程命令,对于批量大范围的远程运维能起到很好的效果,尤其是在域环境下。通常,这个命令,常用的有如下2种方式。
l 以系统身份运行指定应用程序
这个很简单,但是很有意思,Windows系统中administrator的权限不是最大的,最大的是system,很多信息只有system才能查看,比如注册表的sam信息,administrator是看不了的,如果你非要强行修改sam的权限而不顾安全的话,拿就是另外一种情况。那么现在我们要以system的身份启动regedit.exe,命令如下:
psexec -s -i regedit.exe
-s就是以system身份,-i就是交互式,意思是让你看到注册表编辑器的这个窗口,不然他就在后台运行了。
l 创建/执行远程命令代码。
执行远程进程的前提条件是对方机器必须开启ipc , 以 及 a d m i n ,以及admin ,以及admin,否则无法执行。下面我们来看详细命令:
ð 开启ipc$
net share ipc$
ð 开启admin$
net share admin$
ð 在对方电脑上运行程序
C:>psexec \192.168.100.2 -u administrator -p 123456 -d -s calc
运行calc后返回,对方计算机上会有一个calc进程,是以系统身份运行的,因为calc前面是-s(system的意思)。窗口对方是看不到的,如果需要对方看到这个窗口,需要加参数-i。
C:>psexec \192.168.100.2 -u administrator -p 123456 -d calc
承上,就以当前身份运行calc,然后返回
C:>psexec \192.168.100.2 -u administrator -p 123456 -i -d cmd /c start http:// www.baidu.com
为对方以当前用户身份打开百度网页,并让他看到这个网页
ð 在对方电脑上运行cmd命令,且不让对方看到这个窗口
tab_name解释案例结果!逻辑 非select !trueTRUE!=不等值比较select 2!=1FALSE%取余select 3%21&按位与select 3&5 from src limit1*乘法select 2*36+加法select 2+35-减法select 3-12/除法select 3/21.5<小于select 2<3TRUE<=小于等于select 2<=3TRUE<=>等值比较select 1<=>2FALSE<>不等值比较select 2 <> 3TRUE=等值比较select 2 == 2TRUE>大于select 3 > 4FALSE>=大于等于select 3>=2TRUE^运算符查看两个参数的二进制表示法的值,并执行按位”异或”操作select 5^129abs绝对值函数select abs(-9)9acos反余弦函数select acos(2) from src limit 1;0add_months日期加减月select add_months(‘2009-08-31’, 1) from src limit 1;2009-09-30and逻辑与array构造数组构造数组[1,2,3]array_contains判断元素数组是否包含元素select array_contains(array(“aa”,“bb”,“cc”),“aa”)TRUEascii返回字符串第一个字符的ascii码select ascii(‘abc’)97asin反正弦函数select asin(2)from src limit 1;空值assert_true如果’condition’不为真,则抛出异常。SELECT assert_true(x> = 0)FROM src LIMIT 1;空值atan- 返回x的atan(arctan)(x是弧度)SELECT atan(0)FROM src LIMIT 1;0avg平均值统计函数select avg(数值字段)base64将参数从二进制转换为base 64字符串between在[NOT] BETWEEN b和c之间 - 评估a是否在b和c之间bin二进制函数select bin(4)100case条件判断函数case a when b then c [when d then e] [else f] END如果a=b就返回c,a=d就返回e,否则返回fcbrt返回double值的立方根。SELECT cbrt(27.
Spring 5 AutowireCapableBeanFactory – resolveDependency源码分析(一)
Spring 5 AutowireCapableBeanFactory – resolveDependency源码分析(二)
相关源码注释 ApplicationContext Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释
BeanFactory Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释
resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); 针对desciptor所包装的对象类型是[stream,数组,Collection类型且对象类型是接口,Map]的情况,进行解析与依赖类型匹配的 候选Bean对象,并将其封装成相应的依赖类型对象:
获取包装的参数/字段的声明的(非通用)类型【变量 type】【当decriptor所包装的对象是Stream类型】: 如果描述符是Stream依赖项描述符: 查找与valueType匹配的候选bean对象;构建成Map,key=bean名,val=Bean对象【变量 matchingBeans】自动注入匹配成功的候选Bean名集合不为null,将所有的自动注入匹配成功的候选Bean名添加到autowiredBeanNames取出除Bean对象为NullBean以外的所有候选Bean名称的Bean对象【变量 stream】如果decriptor需要排序,根据matchingBean构建排序比较器,交由steam进行排序返回已排好序且已存放除Bean对象为NullBean以外的所有候选Bean名称的Bean对象的stream对象【变量 stream】 【当decriptor所包装的对象是数组类型】: 如果依赖类型是数组类型: 获取type的元素Class对象【变量 componentType】获取decriptor包装的参数/字段所构建出来的ResolvableType对象【变量 resolvableType】让resolvableType解析出的对应的数组Class对象,如果解析失败,就引用type【变量 resolvedArrayType】如果resolvedArrayType与type不是同一个Class对象,componentType就引用resolvableType解析处理的元素Class对象如果没有元素Class对象,就返回null,表示获取不到候选bean对象查找与valueType匹配的候选bean对象;构建成Map,key=bean名,val=Bean对象【变量 matchingBeans】如果没有候选Bean对象,返回null,表示获取不到候选bean对象自动注入匹配成功的候选Bean名集合不为null,将所有的自动注入匹配成功的候选Bean名添加到autowiredBeanNames如果有传入类型转换器就引用传入的类型转换器,否则获取此BeanFactory使用的类型转换器将所有候选Bean对象转换为resolvedArrayType类型【变量 result】如果result是数组实例: 构建依赖比较器,用于对matchingBean的所有bean对象进行优先级排序【变量 comparator】如果比较器不为null,使用comparator对result数组进行排序 返回该候选对象数组【result】 【如果依赖类型属于Collection类型 且 依赖类型是否接口】: 将descoptor所包装的参数/字段构建出来的ResolvableType对象解析成Collectionl类型,然后解析出其 泛型参数的Class对象【变量 elementType】如果元素类型为null,返回null,表示获取不到候选bean对象查找与valueType匹配的候选bean对象;构建成Map,key=bean名,val=Bean对象【变量 matchingBeans】如果没有候选bean对象,返回null,表示获取不到候选bean对象自动注入匹配成功的候选Bean名集合不为null,将所有的自动注入匹配成功的候选Bean名添加到autowiredBeanNames如果有传入类型转换器就引用传入的类型转换器,否则获取此BeanFactory使用的类型转换器将所有候选Bean对象转换为resolvedArrayType类型【变量 result】如果result是List实例: 构建依赖比较器,用于对matchingBean的所有bean对象进行优先级排序【变量 comparator】如果比较器不为null,使用comparator对result数组进行排序 返回该候选对象数组【result】 【如果依赖类型是Map类型】: 将descoptor所包装的参数/字段构建出来的ResolvableType对象解析成Map类型【变量 mapType】解析出第1个泛型参数的Class对象,即key的Class对象【变量 keyType】如果keyType不是String类型,返回null,表示获取不到候选bean对象解析出第2个泛型参数的Class对象,即value的Class对象【变量 valueType】如果keyType为null,即解析不出value的Class对象或者是根本没有value的Class对象, 返回null,表示获取不到候选bean对象查找与valueType匹配的候选bean对象;构建成Map,key=bean名,val=Bean对象【变量 matchingBeans】如果没有候选bean对象,返回null,表示获取不到候选bean对象自动注入匹配成功的候选Bean名集合不为null,将所有的自动注入匹配成功的候选Bean名添加到autowiredBeanNames返回候选的Bean对象Map【matchingBeans】 /** * 针对desciptor所包装的对象类型是[stream,数组,Collection类型且对象类型是接口,Map]的情况,进行解析与依赖类型匹配的 * 候选Bean对象,并将其封装成相应的依赖类型对象 * @param descriptor 依赖项的描述符(字段/方法/构造函数) * @param beanName 声明给定依赖项的bean名 * @param autowiredBeanNames 一个集合,所有自动装配的bean名(用于解决给定依赖关系)都应添加.
数据结构顺序查找中对"哨兵"理解 定义了查找的数据表类型,首先了解下这张表的结构体。
typedef struct{ int* data; int length; }SSTable; 这里建表的时候是长度是按照正常分配的但是第一个位置空出来给哨兵的。
typeof search_(SSTable ST,int key){ ST.data[0] = key; int i= ST.TableLen;//长度 while(ST.data[i] != key){ //从后往前遍历 i --; } return i //如果i的值为0代表查找失败,否则的话就为查找的元素下标 } 比如一个查找表长度为5元素分别为{ ,1,2,3,4,5},第一个位置空留出来给要查找的值
假设为6,那么第一个位置赋值为6.
从后往前遍历,没有哨兵的情况下正常是要控制循环次数。防止数组溢出。有个i<length的判断。有哨兵的情况下只需要判断相等的情况就好了。如果没有查找的值6,到最后一次的对比的时候一定是相等的。退出循环返回下表值即可。不需要控制数组的长度。
统计一张表的总数量,是我们开发中常有的业务需求,通常情况下,我们都是使用 select count(*) from t SQL 语句来完成。随着业务数据的增加,你会发现这条语句执行的速度越来越慢,为什么它会变慢呢?
为什么会变慢?想要得到答案就需要知道 MySQL 是如何统计总数量的,先说一个前提吧,count(*) 的具体实现是由存储引擎实现的,也就是说不同的存储引擎实现的方式不一样。标题:为什么select count( * ) from t,在 InnoDB 引擎中比 MyISAM 慢?也是高频面试题。
InnoDB和MyISAM 是我们常用的 MySQL 存储引擎,所以主要对比一下 count(*) 在 InnoDB 和 MyISAM 中的实现:
在 MyISAM 存储引擎中,把表的总行数存储在磁盘上,当执行 select count() from t 时,直接返回总数据。
在 InnoDB 存储引擎中,跟 MyISAM 不一样,没有将总行数存储在磁盘上,当执行 select count() from t 时,会先把数据读出来,一行一行的累加,最后返回总数量。
知道了 InnoDB 和 MyISAM 引擎 count() 实现之后,为什么select count() from t,在 InnoDB 引擎中比 MyISAM 慢?应该有答案了吧,但是这个结论需要有一个前提,就是统计 SQL 不带过滤条件。如果 统计数量 SQL 语句为:select count(*) from t where x = 23,那么在 MyISAM 中就不一定比 InnoDB 快了。
Godot 五分钟做一个简单的响应式Godot GUI 做一个如下图所示的简单响应式GUI:
分解UI模型 我要做的最终GUI画面使这样的:
当在图纸上构思好自己的界面时,下一步要做的就是如何做出来?首先要分析该如何组成,该用什么容器组织。以上图为例:
整个界面上下左右都留白,第一想到的就是MarginContainer.利用Custom Constants或者Margin使UI距离屏幕边缘有一定距离。
插画在右侧,标志和菜单按钮,版本号在左侧,可以利用HBoxContainer并排它们。然后在右侧在添加个CenterContainer,使插画居中。
左侧的菜单按钮,logo,版本号垂直排列,可以用VBoxContainer纵向排列它们。而菜单按钮位于版本号和logo中间,可以使用VBoxContainer包含它们,然后将Alignment(对齐)更改为center。然后在垂直方向展开,已占用最大地方。这样即使屏幕压扁,菜单按钮还是会在中间,而logo和版本还是会分别在顶部和底部。
开始制作 新建场景,添加MarginContainer,命名为Mainmenu.
设置内边距,让内部元素与边框保持一定距离。
添加HBoxContainer,使插画和logo,菜单按钮,版本号横向排列。再将VBoxContainer和CenterContainer添加为HBoxContainer子节点。CenterContainer存放插画,VBoxContainer存放logo,菜单按钮,版本号,使它们纵向排列。
VBoxContainer添加5个TextureRect,把对应的图片拖放到Texture,并重命名。CenterContainer添加一个TextureRect并重命名,把插画拖到Texture属性。
此时如下图:
为了菜单按钮上下留白,再添加一个VBoxContainer,把菜单按钮包含再其中。
设置VBoxContainer的Size Flags,垂直方向展开以占用更多空间。
Alignment(对齐)属性为居中
此时:
这样就做完了,试试运行一下,并改变窗口大小。
项目下载:响应式GUI
这是一个几个星期之前的小项目,参考修改了一下网上和正点原子的例程。
点击下载源码
功能:贪吃蛇小游戏
单片机:stm32f103c8t6
用到的硬件资源:
1.LED指示灯
2.矩阵键盘
3.OLED模块
4.通用定时器
软件设计:
1.矩阵键盘(中断方式)前面文章有介绍
2.定时器中断:用于更新游戏界面
3.贪吃蛇设计:
OLED的像素点是128*64的,为了可以显示清晰,在这里把游戏的点坐标映射为32x12(map【32】【12】),每个坐标占用16个像素点,前16行像素点用于显示分数。
#define MAXLENGTH 100 //蛇的最大长度 int map[32][12]={0};//地图大小 x,y(一个坐标为4*4个像素点) 实际按4倍尺寸放大后地图大小为128*48个像素点 int score; //分数 bool eated=false; //蛇吃到食物的标记 extern u8 KeyValue; //获取按键值 struct { int snake_Grid[MAXLENGTH][2]; //二维数组,行坐标表示蛇节点,列表示当前节点的x,y坐标 int length; //蛇的长度 int direction;//蛇的方向 }snake; //定义结构体变量snake 清除界面函数
void GUI_Clear(int map[32][12])//界面清除 { int i,j; for(i=0;i<32;i++) { for(j=0;j<12;j++) { map[i][j]=0; } } } 创建地图函数:填充游戏界面的边界坐标,并将边界坐标的值存入map数组
void Creat_map(int map[32][12])//创建地图 { int i,j; for(i=0;i<12;i++) { for(j=0;j<32;j++) { if(i==0||i==11) { map[j][i]=-2; } if(j==0||j==31) { map[j][i]=-2; } } } } 绘制地图函数:用画点函数将坐标绘出来,y坐标+16是因为前16行用来显示分数,16行以后为游戏界面
参考esp-idf V4.0.1中的smart_config例程。 包括默认wifi事件的注册、事件的响应、事件信息的获取。 1.事件的注册 ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); 首先调用esp_event_loop_create_default() 创建默认事件循环。
之后使用esp_event_handler_register() 将事件处理程序注册到系统事件循环。
引用官方手册:
esp_event_handler_register() 此函数可用于注册以下各项的处理程序:(1)特定事件,(2)某个事件基础的所有事件,或(3)系统事件循环已知的所有事件。 特定事件:指定确切的event_base和event_id 特定基准的所有事件:指定确切的event_base并使用ESP_EVENT_ANY_ID作为event_id 循环已知的所有事件:将ESP_EVENT_ANY_BASE用作event_base,将ESP_EVENT_ANY_ID用作event_id 可以将多个处理程序注册到事件。将单个处理程序注册到多个事件也是可能的。但是,将同一处理程序多次注册到同一事件将导致以前的注册被覆盖。 注意 事件循环库不维护event_handler_arg的副本,因此用户应确保在调用处理程序时event_handler_arg仍指向有效位置 返回 ESP_OK:成功 ESP_ERR_NO_MEM:无法为处理程序分配内存 ESP_ERR_INVALID_ARG:事件库和事件ID的无效组合 其他:失败 参量 event_base:要为其注册处理程序的事件的基本ID event_id:要为其注册处理程序的事件的ID event_handler:在调度事件时调用的处理函数 event_handler_arg:除事件数据外,在调用时传递给处理程序的数据 此处使用ESP_EVENT_ANY_ID将WIFI事件和IP事件全部注册到响应函数event_handler,无参数传递。
2.事件的响应 关于响应函数,这里只写了AP模式的WIFI_EVENT_AP_STACONNECTED、WIFI_EVENT_AP_STADISCONNECTED 两个事件部分以做演示。
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { ESP_LOGI(TAG,"event_base:%s, event_id:%d\r\n",event_base, event_id); wifi_event_ap_staconnected_t *wifi_event_data; if (event_base == WIFI_EVENT){ switch (event_id) { case WIFI_EVENT_STA_START: //STA模式启动 /* code */ break; case WIFI_EVENT_STA_STOP: //STA模式关闭 /* code */ break; case WIFI_EVENT_STA_DISCONNECTED: //STA模式断开连接 /* code */ break; case WIFI_EVENT_AP_START: //AP模式启动 /* code */ break; case WIFI_EVENT_AP_STOP: //AP模式关闭 /* code */ break; case WIFI_EVENT_AP_STACONNECTED: //一台设备连接到esp32 wifi_event_ap_staconnected_t *AP_STACONNECTED_EVENT_DATA = (wifi_event_ap_staconnected_t *)event_data; //获取事件信息 ESP_LOGI(TAG, "
**
plt.legend()的几种用法 **
(1)设置图列位置
```python plt.legend(loc=' ')  **(2)设置图例字体大小** ```python fontsize : int or float or {‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’} (3)设置图例边框及背景
plt.legend(loc='best',frameon=False) #去掉图例边框 plt.legend(loc='best',edgecolor='blue') #设置图例边框颜色 plt.legend(loc='best',facecolor='blue') #设置图例背景颜色,若无边框,参数无效 对于边框还可以采用面向对象方式:
legend = plt.legend(["First", "Second"]) frame = legend.get_frame() frame.set_facecolor('blue') (4)设置图例标题
legend = plt.legend(["BJ", "SH"], title='Beijing VS Shanghai') 或者 plt.plot(["BJ", "SH"],loc='upper left',title='Beijing VS Shanghai') (5)设置图例名字及对应关系
legend = plt.legend([p1, p2], ["BJ", "SH"]) import matplotlib.pyplot as plt import numpy as np x = np.
下载DevExpress v20.1完整版 DevExpress v20.1汉化资源获取
40分钟教你入门DevExpress v20.1最新推出控件——甘特图,立即报名>>
DevExpress Winforms Controls 内置140多个UI控件和库,完美构建流畅、美观且易于使用的应用程序。想要体验?点击下载>>
遇到的问题
当使用DefaultEditors属性将类型的自定义编辑器添加到PropertyGrid时,除非该类型具有EditorAttribute(编辑器的实际类型似乎无关紧要),否则将禁用该编辑器。
在DevExpress版本18.1中,使用Color扩展ColorEditor正常工作;但在v19.2中,禁用了CustomColor的编辑器,启用了CustomColorAttr的编辑器。
解决方案
官方技术团队修复此错误后并更改了操作: PropertyGridControl - The Readonly attribute does not work with a custom editor。在之前没有考虑标准的DescriptorContext.IsValueEditable方法,这导致了错误的结果,现在在代码中正确使用此方法。
如果尝试将对象分配给标准PropertyGrid,则由于DescriptorContext.IsValueEditable方法返回false,因此将获得相同的结果。 反过来,此方法返回false,因为用于自定义类的类型转换器无法将字符串值转换为您的类型。 ColorEditor使用可以执行此类转换的ColorConverter。
因此,要启用对自定义类的编辑,您需要应用支持从字符串值到类型转换的类型转换器。
DevExpress技术交流群2:775869749 欢迎一起进群讨论
字节缓冲区分为直接字节缓冲区与非直接字节缓冲区 。
如果字节缓冲区为直接字节缓冲区, 则 JVM 会尽量在直接字节缓 冲区上执行本机 I/O操作,也就是直接对内核空 间进行访问,以提高运行效率 。 提高运行效率的原理就是在每次调用基于操作系统的 1/0 操作之前或之后, JVM 都会尽量避免将缓冲区的内容复制到中间缓冲区中,或者从中间缓冲区中复制内容,这样就节省了一个步骤 。
工厂方法 allocateDirect()可以创建直接字节缓冲区,通过工厂方法 allocateDirect()返回的缓冲区进行内存的分配和释放所需的时间成本通常要高于非直接缓冲区。直接缓冲区操作的数据不在 JVM 堆中 , 而是在内核空间中,根据这个结构可以分析出 ,直接缓 冲区善于保存那些易受操作系统本机 1/0 操作影响的大量、 长时间保存的数据 。 allocateDirect(int capacity)方法的作用:分配新的直接字节缓冲区。新缓冲区的位置将为零 ,其界限将为其容量 , 其标记是不确定的 。 无论它是否具有底层实现数组,其标记都是不确定的 。
allocate(int capacity)方法的作用 : 分配一个新的非直接字节缓冲区 。 新缓冲区的位置为零 ,其界限将为其容量,其标记是不确定的 。 它将具有一个底层实现数组,且其数组偏移量将为零。
直接缓冲区会直接作用于本地操作系统的 I/O ,处理数据的效率相比非直接缓冲区会快一些
使用非直接缓冲区的测试代码如下
public static void testAllocate(){ long beginTime = System.currentTimeMillis(); ByteBuffer allocate = ByteBuffer.allocate(190000000); for (int i = 0 ; i < 190000000 ; i++){ allocate.
PriorityQueue默认是自然排序,但是如果使用了比较器,那么底层会维护一个大顶堆/小顶堆,所有的插入操作都会按照大顶堆或者小顶堆的规则去维护。
这里先用一个栗子来帮助理解,后续补上源码…
public static void main(String[] args) { //小顶堆 PriorityQueue<Integer> pq = new PriorityQueue<Integer>((o1,o2)->o1.compareTo(o2)); pq.add(3); pq.add(1); pq.add(2); pq.add(4); for(Integer t:pq){ System.out.print(t+" "); } System.out.println(); while(pq.size()!=0){ System.out.print(pq.remove()+" "); } System.out.println(); PriorityQueue<String> ppq = new PriorityQueue<String>((o1,o2)->o1.compareTo(o2)); // 入队只做简单的选择排序,和队头的数据进行比较,a加入后和a比较,abcd>a所以放在a的右边 ppq.add("aaaa"); ppq.add("cccc"); ppq.add("a"); ppq.add("abcd"); for(String t:ppq){ System.out.print(t+" "); } System.out.println(); //出队会进行每次队头排序完成排序 while(ppq.size()!=0){ System.out.print(ppq.remove()+" "); } System.out.println(); } 运算结果:
1 3 2 4 1 2 3 4 a abcd aaaa cccc a aaaa abcd cccc PriorityQueue中的add()和offer() add(E e)和offer(E e)的语义相同,都是向优先队列中插入元素,只是Queue接口规定二者对插入失败时的处理不同,前者在插入失败时抛出异常,后则则会返回false。
Java中通过new创建一个对象的时候,发生了哪些事 文章目录 Java中通过`new`创建一个对象的时候,发生了哪些事一、在类的内部,变量定义的先后顺序决定了初始化的顺序二、静态数据的初始化三、概述 (包含继承) 一、在类的内部,变量定义的先后顺序决定了初始化的顺序 二、静态数据的初始化 static关键字不能应用于局部变量,它只能作用于域。
静态初始化只在必要的时刻才会进行——第一次访问静态数据,或者第一次创建对象。
三、概述 (包含继承) public static void main(String[] args){ Bettle bettle = new Bettle(); } 当运行上面的main方法的时候:
(1)加载当前class文件,向上追溯,不断加载基类的class文件
加载器开始启动并找到Beetle类的编译代码(在名为Bettle.class)的文件中。在对它进行加载的过程中,编译器注意到它有一个基类(这是由关键字extends)得知的,于是它继续进行加载。如果该基类还有其自身的基类,那么第二个基类就会被加载,如此类推。
这种方式很重要,因为导出类的static初始化可能会依赖于基类成员能否被正确初始化。
至此,必要的类都已经加载完毕,对象就可以被创建了。
(2)开始创建对象:对象的所有基本类型都会被设为默认值,对象引用被设为null
(3)基类的构造器会被调用。
基类构造器和导出类的构造器一样,以相同的顺序来经历相同的过程。
(4)基类构造器完成之后,实例变量按其次序被初始化。
(5)最后,构造器的其余部分被执行。
读取多个excel表中多个sheet中的数据 数据分为train和test,train有12个excel表格,test有4个excel表格,每一个表格中工作薄的个数不一样,每个工作薄的数据行列数也不一定相同,经过尝试,MATLAB语句更成熟一些,Python语句与库有关系,没有MATLAB那么统一,但Python的确更人性化。
读取所有表格中所有sheet中的数据,单独储存到csv文件中。程序只放了test文件的数据读取。
MATLAB程序 files = dir('*.xlsx'); files_train = files(5:16,:); files_test = files(1:4,:); files_exchange = files_train; files_train([2,3,4:12]) = files_exchange([11,12,2:10]); clear files_exchange; waiting=waitbar(0,'excuting...,please wait!'); %因为不清楚每个sheet中数据size,这里设置了最大列数2500, %经过测试,train最大是有1896列,test是有1910列。将数据储存在矩阵中, %列数必须相同,选择手动补充零,这一点不如Python,Python可以自动补充'NAN' len_max = 2500; A = []; B = []; tic for j = 1:length(files_test) filenme = files_test(j).name; [Type, Sheet]=xlsfinfo(filenme); %status指示 filename 是否为 xlsread 函数可读取的文件 %sheet 返回文件中每个电子表格的名称 for i = 1:length(Sheet) % i_1 = 12*(i-1)+1; % i_2 = 12*i; % data(i_1:i_2,:) = [xlsread("train1-3.xlsx", Sheet{i})]; data = [xlsread(filenme, Sheet{i})]; %也可以读取为cell,没有尝试成功 len = length(data); data = [data, zeros(12, len_max-len)]; B = [B; data]; end end %删除多余零列 for k = 2500 :-1: 1881 no_zero = max(max(abs(B(:, k)))); if no_zero == 0 B(:,k) = []; else break; end end waitbar(0.
前言 CSharp的特性(Attribute)是比较难以理解的技术,写代码时通常都要求写注释,为了是让其他程序猿快速理解代码含义,但是注释是写给'人'看的,突发奇想下:能不能写出给C#编译器看的注释,比如在某些代码段上打上标记,让编译器看到标记后,做出不同的运行效果?其实…这就是特性。
1.Serializable特性分析 为什么Serializable特性作为小节1讲解呢?因为它是比较常见的特性,在网络对象进行传输时和数据库进行对象保存时,使用序列化特性后的类、结构体、枚举等等都可实现序列化操作的,SerializableAttribute仅是标记而已,它并不执行序列化动作。这样为何在C#中必须要使用它呢?而其他语言好像没有C#这种技术,接下来展示序列化的代码:
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace TestPro { [Serializable] public class Person { public int Age { get; set; } public int Sex { get; set; } public string Name { get; set; } } class Program { static void Main(string[] args) { Person person = new Person(); person.Age = 18; person.Sex = 0; person.Name = "李洛克"; IFormatter formatter = new BinaryFormatter(); Stream stream = new FileStream("
最近使用vue写项目,用到的是ELement的框架,项目中有个地方用到了级联选择器,好多东西直接在官网都找不到。
一、我要实现点击清空以后,去调用一个和点击下拉选项不一样方法,做这个功能的时候,也找到了如何在方法中清空级联选择器的选项。 官网上只说明了想要清空级联选择器只需要添加一个clearable
原理就是在级联选择器上面绑定一个监听
1、首先添加一个 ref="cascaderHandle" 和clearable
2、在要清空的函数方法中this.$refs.cascaderHandle.checkedValue=""即可,这个clear是清空按钮绑定的方法
3、如何在点击级联选择器本身的那个×后,调用某个方法(或进行某个步骤)
在级联选择器@change绑定的方法中设置监听,即
if (this.$refs.cascaderHandle1.checkedValue.length === 0)
这个就是监听有没有点击级联选择器的清空那个图标
二、关于清空级联选择器的选项,还有一种方法,定义一个变量 当需要清空选项的时候,直接this.cascaderCheck=[]即可
float在内存中的数据格式及其转byte数组原理及转换过程
float在计算机的存储 四个字节,共有32位。以“符号”+“移位数”+“底数”的方式存储。
三者的计算
第一位是符号,往后8位是“移位数”,再往后23位是“底数”。
32位的格式排列就是
ABBB BBBB BCCC CCCC CCCC CCCC CCCC A表示符号,正数为0,负数为1
B表示移位数,占了8个字节,所以能表示的大小为0~255。但是,移位数肯定是有正负之分,
当读取这里的值要减去127,故float的移位数可从 -127到128.当存储这里的值要加上127,故float的移位数可从 -127到128. C表示底数,底数的计算方式,
当读取该值的时候,看例子一,先在C前面补上1.,意思就是把23个C看成是小数(比如是10100000 0000 0000 0000 0000,我们所要的数就是1.10100000 0000 0000 0000 ),然后根据移位数的值进行移位,再转成十进制的数据当存取该值的时候,例子二,把数据转为二进制,然后进行移位,直到小数点前面有且只有一位1,然后,把1.去掉,剩下的放到底数位,后面补上0。 例子一: 比如 我现在的数据是 65,72,0,0,转为二进制
01000001 01001000 00000000 00000000 那进行三部分拆分,就是 A:0,B:10000010,C:1001000 00000000 00000000
A部分为0,表示正数
B部分值为130,这移位数就为3
将C值进行转换 1.1001000 00000000 00000000,
根据B值移位2,就变成了 1100.1000 00000000 00000000,
用二进制转十进制算法(@为移位数符号) 12@3+ 12@2+ 02@1+ 02@0+ 12@-1+ 02@-3+。。。
算出结果为12.5
例子二: 比如 我现在的数据是 17.625
先将数据转成二进制(可以查看参考链接,小数进制转换),变成10001.101,
原则–直到小数点前面有且只有一位1—》 可以算出需要将这个数变成1.0001101
所以,底数就是 0001101,移位数为4+127=131,符号为正的,所以就是
01000001 10001101 00000000 00000000 byte数组就是 65,-115,0,0
使物体图,如图所示:
设置界面如下:
每一个,列表设置如下:
Sliderd 的设置如下图:
Background 的设置如下图:
Fill 的设置如下图:
Handle Slide Area 的设置如下图:
Handle 的设置如下图:
代码部分,引用是设置,如图所示:
音量滑动数值的设计代码:
Game_Maneger 部分的引用,代码如下:
目录
一、 OSI简单理解
二、 OSI基础知识
三、 OSI的七层结构
四、 OSI分层的优点
五、 OSI模型与TCP/IP模型的比较
一、 OSI简单理解 模型把网络通信的工作分为7层。1至4层被认为是低层,这些层与数据移动密切相关。5至7层是高层,包含应用程序级的数据。每一层负责一项具体的工作,然后把数据传送到下一层。由低到高具体分为:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。
第7层应用层—直接对应用程序提供服务,应用程序可以变化,但要包括电子消息传输
第6层表示层—格式化数据,以便为应用程序提供通用接口。这可以包括加密服务
第5层会话层—在两个节点之间建立端连接。此服务包括建立连接是以全双工还是以半双工的方式进行设置,尽管可以在层4中处理双工方式
第4层传输层—常规数据递送-面向连接或无连接。包括全双工或半双工、流控制和错误恢复服务 第3层网络层—本层通过寻址来建立两个节点之间的连接,它包括通过互连网络来路由和中继数据
第2层数据链路层—在此层将数据分帧,并处理流控制。本层指定拓扑结构并提供硬件寻址
第1层物理层—原始比特流的传输电子信号传输和硬件接口数据发送时,从第七层传到第一层,接受方则相反。
各层对应的典型设备如下:
OSI七层模式简单通俗理解
这个模型学了好多次,总是记不住。今天又看了一遍,发现用历史推演的角度去看问题会更有逻辑,更好记。本文不一定严谨,可能有错漏,主要是抛砖引玉,帮助记性不好的人。总体来说,OSI模型是从底层往上层发展出来的。
这个模型推出的最开始,是是因为美国人有两台机器之间进行通信的需求。
需求1:
科学家要解决的第一个问题是,两个硬件之间怎么通信。具体就是一台发些比特流,然后另一台能收到。
于是,科学家发明了物理层:
主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后在转化为1、0,也就是我们常说的数模转换与模数转换)。这一层的数据叫做比特。
需求2:
现在通过电线我能发数据流了,但是,我还希望通过无线电波,通过其它介质来传输。然后我还要保证传输过去的比特流是正确的,要有纠错功能。
于是,发明了数据链路层:
定义了如何让格式化数据以进行传输,以及如何让控制对物理介质的访问。这一层通常还提供错误检测和纠正,以确保数据的可靠传输。
需求3:
现在我能发正确的发比特流数据到另一台计算机了,但是当我发大量数据时候,可能需要好长时间,例如一个视频格式的,网络会中断好多次(事实上,即使有了物理层和数据链路层,网络还是经常中断,只是中断的时间是毫秒级别的)。
那么,我还须要保证传输大量文件时的准确性。于是,我要对发出去的数据进行封装。就像发快递一样,一个个地发。
于是,先发明了传输层(传输层在OSI模型中,是在网络层上面)
例如TCP,是用于发大量数据的,我发了1万个包出去,另一台电脑就要告诉我是否接受到了1万个包,如果缺了3个包,就告诉我是第1001,234,8888个包丢了,那我再发一次。这样,就能保证对方把这个视频完整接收了。
例如UDP,是用于发送少量数据的。我发20个包出去,一般不会丢包,所以,我不管你收到多少个。在多人互动游戏,也经常用UDP协议,因为一般都是简单的信息,而且有广播的需求。如果用TCP,效率就很低,因为它会不停地告诉主机我收到了20个包,或者我收到了18个包,再发我两个!如果同时有1万台计算机都这样做,那么用TCP反而会降低效率,还不如用UDP,主机发出去就算了,丢几个包你就卡一下,算了,下次再发包你再更新。
TCP协议是会绑定IP和端口的协议,下面会介绍IP协议。
需求4:
传输层只是解决了打包的问题。但是如果我有多台计算机,怎么找到我要发的那台?或者,A要给F发信息,中间要经过B,C,D,E,但是中间还有好多节点如K.J.Z.Y。我怎么选择最佳路径?这就是路由要做的事。
于是,发明了网络层。即路由器,交换机那些具有寻址功能的设备所实现的功能。这一层定义的是IP地址,通过IP地址寻址。所以产生了IP协议。
需求5:
现在我们已经保证给正确的计算机,发送正确的封装过后的信息了。但是用户级别的体验好不好?难道我每次都要调用TCP去打包,然后调用IP协议去找路由,自己去发?当然不行,所以我们要建立一个自动收发包,自动寻址的功能。
于是,发明了会话层。会话层的作用就是建立和管理应用程序之间的通信。
需求6:
现在我能保证应用程序自动收发包和寻址了。但是我要用Linux给window发包,两个系统语法不一致,就像安装包一样,exe是不能在linux下用的,shell在window下也是不能直接运行的。于是需要表示层(presentation),帮我们解决不同系统之间的通信语法问题。
需求7:
OK,现在所有必要条件都准备好了,我们可以写个android程序,web程序去实现需求把。
补充:
Socket:
这不是一个协议,而是一个通信模型。其实它最初是伯克利加州分校软件研究所,简称BSD发明的,主要用来一台电脑的两个进程间通信,然后把它用到了两台电脑的进程间通信。所以,可以把它简单理解为进程间通信,不是什么高级的东西。主要做的事情不就是:
A发包:发请求包给某个已经绑定的端口(所以我们经常会访问这样的地址182.13.15.16:1235,1235就是端口);收到B的允许;然后正式发送;发送完了,告诉B要断开链接;收到断开允许,马上断开,然后发送已经断开信息给B。
B收包:绑定端口和IP;然后在这个端口监听;接收到A的请求,发允许给A,并做好接收准备,主要就是清理缓存等待接收新数据;然后正式接收;接受到断开请求,允许断开;确认断开后,继续监听其它请求。
可见,Socket其实就是I/O操作。Socket并不仅限于网络通信。在网络通信中,它涵盖了网络层、传输层、会话层、表示层、应用层——其实这都不需要记,因为Socket通信时候用到了IP和端口,仅这两个就表明了它用到了网络层和传输层;而且它无视多台电脑通信的系统差别,所以它涉及了表示层;一般Socket都是基于一个应用程序的,所以会涉及到会话层和应用层。
应用层……………….计算机:应用程序,如FTP,SMTP,HTTP
表示层 ……………….计算机:编码方式,图像编解码、URL字段传输编码
会话层 ……………….计算机:建立会话,SESSION认证、断点续传
传输层 ……………….计算机:进程和端口
网络层…………………网络:路由器,防火墙、多层交换机
数据链路层 ………..网络:网卡,网桥,交换机
物理层…………………网络:中继器,集线器、网线、HUB
二、 OSI基础知识 OSI/RM参考模型的提出