目录
1.环境
2.环境库下载
2.1 Ceres Solver2.0.0
2.2 Eigen3.3.8
2.3 gflags
2.4 glog
2.5 suitsparse-metis-for-windows
3.环境库配置
3.1 Eigen编译
3.2 gflags编译
3.3 glog编译
3.4 Suitesparse编译
3.5 Ceres Solver编译
4.环境变量配置
5.VS2019环境配置
6.测试
6.1 helloworld测试
6.2 bundle_adjuster测试
7.参考博客
亲测可用 2023-04-27。
1.环境 Windows10Visual Studio 2019 CommunityCMake GUI 3.19.8 2.环境库下载 2.1 Ceres Solver2.0.0 下载地址 :http://ceres-solver.org/installation.html
2.2 Eigen3.3.9 Eigen(开源库)是一个高层次的C ++库,有效支持线性代数,矩阵和矢量运算,数值分析及其相关的算法。
下载地址:http://eigen.tuxfamily.org/index.php?title=Main_Page
2.3 gflags gflags是google开源的一种命令行解析工具,主要用于解析用命令行执行可执行文件时传入的参数。
下载地址:https://github.com/gflags/gflags
2.4 glog glog是google提供的轻量级日志库,它提供了基于C++样式流和各种帮助程序宏的日志记录API,你可以很简单的将信息传输到LOG来记录消息。
下载地址:https://github.com/google/glog
2.5 suitsparse-metis-for-windows 此库非必须安装。但安装后可以提高Ceres对稀疏矩阵的计算性能,提供更多的优化算法,此库安装后会使Ceres库的安装过程变得繁琐,但仍建议安装。这个库的原生版本本身对Windows的支持不好,所以在Windows上要使用这个专门针对Windows的衍生版本。另外,这个库还存在一个名为CXSparse的简化版本。
下载地址:https://github.com/jlblancoc/suitesparse-metis-for-windows
3.环境库配置 首先建立一个文件夹,建议除C盘的其他盘,例如:E:\ceres_install,将压缩包解压到该文件夹内,另外为每个库按照“库名-build”的命名方式新建文件夹,用以存放生成后的工程文件,如下图所示(请忽略图中opencv4.5路径,根据自身情况而定,此次仅作演示):
转自:https://blog.csdn.net/keeng2008/article/details/119174331
初步进行了一些排版优化。
HTTP/3 在 HTTP/2 的基础上,增强了安全上的限制,且使用 UDP 传输降低丢包导致的头部阻塞、降低因为 TCP 的协议限制而导致的连接耗时高等问题,但是目前各大浏览器的支持范围不够广,暂时不建议在网页相关的服务上进行升级。但是其提高了传输效率,有必要在传输数据量较大的应用上进行升级,建议对 HTTP/3 支持的改造设计与研究,在规范成熟时发布支持 HTTP/3 协议的版本。
前期在调研 quic 选型中,选择了 Cronet 作为客户端访问 quic 协议的网络库。为了方便现有项目中能快速的支持 quic 网络协议,下面会对比 OkHttp 与 Cronet 网络库的使用区别。
一、不同网络库的使用方法差异 1.1. OkHttp使用方法 支持 http1,http2; 使用广泛方便 ,可定义拦截器添加业务逻辑,支持同步和异步使用执行。与 Retrofit 结合定义 api,可理解性强。
val builder: OkHttpClient.Builder = OkHttpClient.Builder() builder.addInterceptor(LoggingInterceptor()) val client = builder.build() var url = "http://www.baidu.com/" // 可设置发送数据:.post(RequestBody()) val request: Request = Request.Builder().url(url).build() val call = client.newCall(request) call.enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { Log.
首先安装nodejs,然后安装express MVC框架 1. npm install -g express 由于我写的是一个proxy代理服务所以我也安装了 http-proxy-middleware 【npm install -g http-proxy-middleware】
2.如果执行express,未能识别指令主要原因是因为环境变量中没有express.exe,识别不了express关键字,执行如下代码即可,是为了去安装express“脚手架”。npm install express express-generator -g
3.安装之后,执行express --help还是存在问题,出现这个问题的原因是:你本电脑有个配置来判断是否可以运行脚本,本电脑的配置是不可支持脚本的,express这就属于运行脚本。所以你得修改本机配置,点开电脑的windows powerShell 记住用 管理员身份运行。 查看本机的默认配置 PS C:\windows\system32> Get-ExecutionPolicy Restricted 这里注意,Restricted 就是你为啥不能执行脚本的原因,所以你得改成可运行脚本的RemoteSigned 修改成为RemoteSigned
PS C:\windows\system32> set-ExecutionPolicy RemoteSigned -Scope CurrentUser 执行策略更改 执行策略可帮助你防止执行不信任的脚本。更改执行策略可能会产生安全风险,如 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies 帮助主题所述。是否要更改执行策略? [Y] 是(Y) [A] 全是(A) [N] 否(N) [L] 全否(L) [S] 暂停(S) [?] 帮助 (默认值为“N”): Y 执行完之后,express 指令正常使用。测试express执行时默认给我创建了一个项目......
4.执行指令express -t ejs(指定模板引擎) mytest(项目名),创建node web项目
我首先先创建的NODEWORK,然后在这个目录下创建myproxy项目
1、dt.jar SUN对于dt.jar的定义:Also includes dt.jar, the DesignTime archive of BeanInfo files that tell interactive development environments (IDE's) how to display the Java components and how to let the developer customize them for the application。中文翻译过来就是:dt.jar是BeanInfo文件的DesignTime归档,BeanInfo文件用来告诉集成开发环境(IDE)如何显示Java组件还有如何让开发人员根据应用程序自定义它们。这段文字中提到了几个关键字:DesignTime,BeanInfo,IDE,Java components。其实dt.jar就是DesignTime Archive的缩写。那么何为DesignTime。
何为DesignTime?翻译过来就是设计时。其实了解JavaBean的人都知道design time和runtime(运行时)这两个术语的含义。设计时(DesignTIme)是指在开发环境中通过添加控件,设置控件或窗体属性等方法,建立应用程序的时间。与此相对应的运行时(RunTIme)是指可以象用户那样与应用程序交互作用的时间。那么现在再理解一下上面的翻译,其实dt.jar包含了swing控件中的BeanInfo,而IDE的GUI Designer需要这些信息。那让我们看一下dt.jar中到底有什么?下面是一张dt.jar下面的内容截图:
从上面的截图可以看出,dt.jar中全部是Swing组件的BeanInfo。那么到底什么是BeanInfo呢?
何为BeanInfo?JavaBean和BeanInfo有很大的关系。Sun所制定的JavaBean规范,很大程度上是为IDE准备的——它让IDE能够以可视化的方式设置JavaBean的属性。如果在IDE中开发一个可视化应用程序,我们需要通过属性设置的方式对组成应用的各种组件进行定制,IDE通过属性编辑器让开发人员使用可视化的方式设置组件的属性。一般的IDE都支持JavaBean规范所定义的属性编辑器,当组件开发商发布一个组件时,它往往将组件对应的属性编辑器捆绑发行,这样开发者就可以在IDE环境下方便地利用属性编辑器对组件进行定制工作。JavaBean规范通过java.beans.PropertyEditor定义了设置JavaBean属性的方法,通过BeanInfo描述了JavaBean哪些属性是可定制的,此外还描述了可定制属性与PropertyEditor的对应关系。BeanInfo与JavaBean之间的对应关系,通过两者之间规范的命名确立:对应JavaBean的BeanInfo采用如下的命名规范:<Bean>BeanInfo。当JavaBean连同其属性编辑器相同的组件注册到IDE中后,当在开发界面中对JavaBean进行定制时,IDE就会根据JavaBean规范找到对应的BeanInfo,再根据BeanInfo中的描述信息找到JavaBean属性描述(是否开放、使用哪个属性编辑器),进而为JavaBean生成特定开发编辑界面。
dt.jar里面主要是swing组件的BeanInfo。IDE根据这些BeanInfo显示这些组件以及开发人员如何定制他们。
2、rt.jar rt.jar是runtime的归档。Java基础类库,也就是Java doc里面看到的所有的类的class文件。
rt.jar 默认就在Root Classloader的加载路径里面的,而在Claspath配置该变量是不需要的;同时jre/lib目录下的其他jar:jce.jar、jsse.jar、charsets.jar、resources.jar都在Root Classloader中。
3、tools.jar tools.jar 是系统用来编译一个类的时候用到的,即执行javac的时候用到
javac XXX.java
实际上就是运行
java -Classpath=%JAVA_HOME%\lib\tools.jar xx.xxx.Main XXX.java
javac就是对上面命令的封装 所以tools.jar 也不用加到classpath里面。
4、其他jar包 jar包 用途 axis.jar SOAP引擎包(Simple Object Access Protocol,简单对象访问协议) commons-discovery-0.
npm install 很慢可能有多种原因,以下是一些常见的解决方法:
更换镜像源:使用淘宝镜像源或其他国内镜像源可以加速下载速度,可以通过以下命令进行设置:
npm config set registry https://registry.npm.taobao.org/ 使用cnpm:cnpm 是一个 npm 的镜像,使用 cnpm 安装依赖会比使用 npm 快很多,可以通过以下命令进行安装:但是 建议不要直接使用 cnpm 安装以来,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题:
npm install --registry=https://registry.npm.taobao.org //=========================================================== //如果安装了cnpm这是卸载命令: npm uninstall -g cnpm //如果在安装 cnpm 时指定了 --registry 选项 npm uninstall -g cnpm --registry=https://registry.npm.taobao.org 升级 npm:使用最新版本的 npm 可以提高下载速度,可以通过以下命令进行升级:
npm install -g npm 使用代理:如果你使用的是公司内部网络,可能需要设置代理才能正常下载,可以通过以下命令进行设置:
npm config set proxy http://proxy.example.com:8080 npm config set https-proxy http://proxy.example.com:8080 优化网络环境:如果你的网络环境比较差,可以尝试断开 VPN 或者使用其他网络环境下载。
升级电脑硬件:如果你的电脑配置比较低,可能会导致下载速度很慢,可以考虑升级硬件来提高性能。
以上是一些常见的解决方法,如果问题仍然存在,建议查看 npm 官方文档或寻求技术支持。
1.可以通过 jstack 命令来进行查看,jstack 命令中会显示发生了死锁的线程
2.或者两个线程去操作数据库时,数据库发生了死锁,这是可以查询数据库的死锁情况.
SQL:
1、查询是否锁表
show OPEN TABLES wtere In_use 》e;
2、查询进程
show processlist;
3、查看正在锁的事务
SELECT * EROM INFORMATION_SCHEMA.INNODB_LOCKS;
4、查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS.
一、vue3的新特性及新增api
1.响应式原理
vue2的响应式原理是利用Object.defineProperty而vue3则是利用Proxy。。
2.新增了组件 API(Composition API)
vue2使用的是options API而3新增了Composition API(注意是新增,也就是说这两个可以共用,甚至可以互相嵌套使用兼容性很好)
3.片段-碎片(Fragments)
这个类似于react Fragments组件(react Fragment官方文档)。其实就是vue2的时候每个组件必须要有根组件,而vue3就可以不必这样(减少不必要的dom元素)。
4.Suspense
将被用在 Vue 3 中的另一个从 React 学来的功能是 Suspense 组件。Suspense 能够暂停你的组件渲染,并渲染后备组件,直到条件满足为止。react Suspens官方文档(我的理解:当在加载异步组件的时候,等待所有组件加载完毕之前可以做一些事情类似于promise.all())。举个例子比如父组件请求接口需要3秒请求过来,而子组件是用来显示请求结果的这就是典型的异步组件。这个时候我们就可以用Suspense,实现在等待的时候展现一个组件(就比如移动端页面加载完毕之前都会有骨架,我们·就可以用这个实现)。
5.Portals
其实这个就类似于react的Portals(react Portals官方文档)。
Portals 提供了一种独特的方法来将子级渲染到父组件的 DOM 层次结构之外的 DOM 节点中。”
这种处理模式,是弹出式窗口以及通常显示在页面顶部的组件所使用的一种非常好的方法。通过使用 Portals,你可以确保没有任何主机组件 CSS 规则会影响你要显示的组件,并且可以避免用 z-index 进行的黑客攻击。
6.Custom Renderer API:暴露了自定义渲染API(teleport介绍)
7.Tree shaking support:可以将无用模块“剪枝”。
二、vue2和3的变化
1.响应式原理实现发生了变化。
2.新增了一些api
3.性能上发生了很大的变化:
1.diff算法上优化(让dom渲染时间缩小)
2.响应式原理的优化(减少源码量大小)
3.项目包大小的优化(vue3的cli打包后会比vue2小)
4.更好的支持typescript(这个是直接可以使用)
5.Tree shaking support:可以将无用模块“剪枝”。(模块按需加载减少包大小)
vue2 迁移 到 vue3
综上所述vue3会比vue2快上2到3倍(越大的项目越明显)。而且vue3(可以兼容ie11,应该是需要配置的)和vue2可以完美兼容(尤大大说不必,把项目立即升级vue3)。
一、Composition API
Composition API,即组合式API
高内聚
聚合业务逻辑,提高代码可读性
vue2 通过属性选项(options,如 data、computed、methods 等)书写代码逻辑,代码逻辑点是碎片化、跳跃式的,在大型项目和复杂组件中使得维护变得困难。
0x00: 说明 使用 Java 操作 HDFS 文件系统可以使用其对应的Java API,即对应三个 jar 依赖包:
hadoop-common.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的 \share\hadoop\common 目录下)hadoop-hdfs.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的 \share\hadoop\hdfs 目录下)hadoop-client.jar (该文件在 hadoop-2.10.1.tar.gz 压缩包中的 \share\hadoop\hdfs 目录下) 这三个 jar 包的具体名字可能根据你所安装的版本进行变化,在本文档中这三个文件名称具体如下:
此处我不推荐直接通过 jar 包引入依赖支持,本文中也将不在撰写 jar 的方式引入,因为这三个jar还依赖于其他的依赖库,例如 woodstox-core 等一系列jar包,过程较为繁琐,因此本文中使用 pom 表引入对应配置,使用pom表来管理依赖后,子依赖会自动导入,不在需要我们手动引入,较为方便,pom表依赖配置如下:
<dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>2.10.1</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.10.1</version> </dependency> 在本文中我将在宿主机使用 IDEA 创建对应工程调用虚拟机的 Java API 接口,创建基本 Java 工程在本文中将不在赘述,但请注意,在创建工程时请将系统编译方式选择为 Maven,如下图所示:
0x01: 依赖导入 注意,在第三步引入后你会发现他是处于红色的错误状态,此时点击第四步刷新依赖后即可
引入依赖完成后如下图所示,但因为版本问题存在相对较多的安全的漏洞提示,鼠标放在上方即可显示相关的CVE漏洞编号,但我们仅仅只是学习用途,该问题我们直接忽略
该步骤完成后 pom 表中无红色文本内容时则代表已完成依赖引入
1、打开VMware,点击创建新的虚拟机。 2、选择典型配置,并进行下一步。 3、选择稍后安装操作系统,并进行下一步。 4、客户机操作系统选择Microsoft Windows(W),版本选择Windows server 2016,并进行下一步。 5、虚拟机名称(自定义),位置(自定义,但不建议系统盘),点击下一步。 6、磁盘大小60G(这里并非直接占用而是在使用过程中逐渐占用存储空间,所以就算不够60G也没关系,可以先填60G,等以后扩充),之后选择将虚拟磁盘拆分成多个文件,并进行下一步。
7、点击完成。
8、点击编辑虚拟机设置。 9、按需求更改分配的内存和处理器,这里更改为:内存2GB、处理器2。
10、点击CD/DVD后,点击使用ISO镜像文件,点击浏览,选择对应ISO镜像文件。
11、点击打印机,点击移除,并点击确定。
12、点击开启此虚拟机。 13、进入安装界面,按如图选择(其实是默认的*-*),点击下一步。 14、点击我没有产品密钥。 15、 选择Windows server 2016 standard(桌面体验),并点击下一步。(桌面体验代表有ui界面) 16、 点击同意许可条款,并进行下一步。 17、点击 自定义:仅安装Windows并等待安装。 18、点击立即重启。 19、 设置Administrator用户密码,并点击完成。 20、 按Ctrl+Alt+Delete解锁。 21、输入密码登录。 22、 点击下方提示安装Tools。 23、这里一定有些人没有这个提示或者自己把提示点掉了。(*-*)没有此提示的请重启虚拟机, 并在重启的瞬间快速右键(Ctrl+Alt释放鼠标)上方虚拟机点击重新安装VMware-Tools(如果该选 项为灰色的无法选中,请重新重启并尝试) 24、 找到此电脑鼠标(双击垃圾站,点击此电脑),后双击DVD驱动器VMware-Tools进入,再双击setup文件进行安装。 25、 点击下一步。 26、 选择典型安装,并单击下一步。 27、点击安装。 28、点击完成。 29、点击是,重启电脑。 30、大功告成*-*。
目录 一、opencv源码下载二、编译三、配置环境 环境:Win10 + VS2019 + Opencv4.5 + Cmake 3.19.8
一、opencv源码下载 https://github.com/opencv
下载opencv和opencv_contrib
新建一个build文件夹,用于编译
下载CMAKE https://cmake.org/download/
二、编译 基本不需要修改什么,记得增加conrib模块的路径,勾选OPENCV_ENABLE_NONFREE,修改完点configure
可能会碰到一些报错,基本是下面文件里的一些文件下载失败,可从下面链接下载,放到对应文件夹里即可
https://download.csdn.net/download/qqlmdd/87734913
config完成后,generate
点击Open Project即可,点击生成中的批生成,勾选ALL_BUILD和INSTALL,点击生成
三、配置环境 添加环境变量
添加附加依赖项
lib文件太多,可用powershell
按住alt选择
在shader中,要对移动端的兼容,还不想实现两套分开兼容的话,
#pragma exclude_renderers gles gles3 glcore #pragma target 4.5 这两句话一定要改掉,第一行代码直接剔除了gles的渲染,而恰恰大部分移动端都是用的gles(安卓平台)所以,第一行要去掉。第二行是针对于ShaderMod,也就是一些shader新特性,可以调低,内置的lit里面是实现了两套一套高质感的用来配合pc,对gles平台专门书写了一套高性能的渲染。
如果我们需要多端兼容的话,推荐target的值 3 或者 3.5,放弃一些不兼容的特性。
目前unity URP对半透明对象的处理:不能参与Shadow Map,Depth,Depth Normal的渲染,可以在材质Debug模式下查看。
并且半透明无法产生阴影,屏幕空间阴影(这个需要深度),SSAO
半透明阴影:利用UnityDitherMask3D贴图解决
实现:
首先在ShadowPass的头部定义宏:
#if (SHADER_API_D3D11 || SHADER_API_GLCORE || SHADER_API_GLES3 || SHADER_API_METAL || SHADER_API_VULKAN) #define CAN_SKIP_VPOS #endif 用来确定当前是否可以支持这种方式。
声明一张贴图,这是一张3d贴图,unity内置提供的
TEXTURE3D(_DitherMaskLOD); SAMPLER(sampler_DitherMaskLOD); 然后在片元着色器上面增加参数:
half4 ShadowPassFragment(Varyings input #if !defined(CAN_SKIP_VPOS) , UNITY_VPOS_TYPE vpos : VPOS #endif ) : SV_TARGET { 这个是能够直接获取到屏幕空间的位置。
最后,在shader中增加噪波相关的运算:
half4 ShadowPassFragment(Varyings input #if !defined(CAN_SKIP_VPOS) , UNITY_VPOS_TYPE vpos : VPOS #endif ) : SV_TARGET { half4 BaseColorAlpha = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.
描述 我的点云数据发布在"map"坐标系下,我想把这个pointcloud2数据变化至"base_link"坐标系。
解决办法 方法一 找到tf关系,然后调用doTransform函数
#include "rclcpp/rclcpp.hpp" #include "sensor_msgs/msg/point_cloud2.hpp" #include "geometry_msgs/msg/transform_stamped.hpp" #include <tf2/transform_datatypes.h> #include <tf2/utils.h> #include "tf2_ros/buffer.h" #include <tf2_sensor_msgs/tf2_sensor_msgs.h> //for tf transform #include "tf2_ros/transform_listener.h" .... auto tf_buffer = std::make_unique<tf2_ros::Buffer>(this->get_clock()); auto in = std::make_shared<sensor_msgs::msg::PointCloud2>(); //输入点云 auto out = std::make_shared<sensor_msgs::msg::PointCloud2>(); //输出点云 geometry_msgs::msg::TransformStamped transformStamped; try { transformStamped = tf_buffer->lookupTransform( "base_link", in->header.frame_id, tf2::TimePointZero); } catch (tf2::TransformException &ex) { SPDLOG_ERROR("{}", ex.what()); return; } tf2::doTransform(*in, *out, transformStamped); CMAKE文件需要
find_package(catkin REQUIRED COMPONENTS rclcpp tf2 tf2_ros tf2_sensor_msgs geometry_msgs sensor_msgs ) target_link_libraries(your_node_name ${catkin_LIBRARIES} ) 方法二 更简单的方法时=是直接调用tf_bugger的transform函数
这篇文章主要介绍“mysql数据库索引原理及优化策略是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“MySQL数据库索引原理及优化策略是什么”文章能帮助大家解决问题。
1 索引 索引概念
索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的数据结构实现。
索引作用
数据库中的表、数据、索引之间的关系,类似于书架上的图书、书籍内容和书籍目录的关系,索引所起的作用类似书籍目录,可用于快速定位、检索数据。索引可以极大地提高数据库的性能。
索引的使用场景
要考虑对数据库表的某列或某几列创建索引,需要考虑以下几点:
数据量较大,且经常对这些列进行条件查询。
该数据库表的插入操作,及对这些列的修改操作频率较低。
索引会占用额外的磁盘空间。
2 索引分类 唯一索引的创建
-- 在表定义时,在某列后直接指定unique唯一属性。 create table user4(id int primary key, name varchar(30) unique); -- 创建表时,在表的后面指定某列或某几列为unique create table user5(id int primary key, name varchar(30), unique(name)); -- 创建表以后再添加unique create table user6(id int primary key, name varchar(30)); alter table user6 add unique(name); 唯一索引的特点:
普通索引的创建
--在表的定义最后,指定某列为索引 create table user8(id int primary key, name varchar(20), email varchar(30), index(name) ); --创建完表以后指定某列为普通索引 create table user9(id int primary key, name varchar(20), email varchar(30)); alter table user9 add index(name); -- 创建一个索引名为 idx_name 的索引 create table user10(id int primary key, name varchar(20), email varchar(30)); create index idx_name on user10(name); 普通索引的特点:
解题思路 在JavaScript中计算7/3*3,结果是7,而不是6。这是因为JavaScript中除法运算符(/)得到的结果是一个浮点数,而不是一个整数。
具体来说,7/3得到的结果是2.3333…,然后再乘以3得到7.0000…,由于JavaScript采用IEEE 754浮点数标准,所以会对小数进行四舍五入,最终结果为7。
建立sum函数,执行单一功能(求一个数的所有倍数)。
原sumOfMultiples函数,返回所有的计算结果。
时间复杂度为 O(1)
代码 /** * @param {number} n * @return {number} */ var sumOfMultiples = function(n) { return sum(n,3) + sum(n,5) + sum(n,7) - sum(n,21) - sum(n,35) - sum(n,15) + sum(n,105) }; var sum = function(n, m) { return ((m +(n-n%m)) * Math.floor(n/m)) / 2 } 容斥原理 什么是容斥原理?
所谓容斥原理就是数学中的,交集并集的观念,相同的部分会在不同的公式里面重复执行,需要对相同的部分做差剪掉,同理相同部分重叠两次剪掉的部分也要加回来。 形如:
疑问 为什么有些编译器出来的 7/3*3是 7 而不是 6 ?
首先,编译器出来的应该都是 6,因为计算机根据算数运算顺序,从左往右,优先级高的先执行, 7/3 = 2 (我们都知道 / 是一个向下取整的除法运算)2*3 = 6 (理应得6) 为什么会有 7?
如果该虚拟机未在使用,请按“获取所有权(T)”按钮获取它的所有权。
否则,请按“取消(C)”按钮以防损坏。
点击“获取所有权后还是无法打开”
找到你的安装目录,删除掉后缀为.vmx.lck的文件夹
就可以正常使用该虚拟机
单个属性排序:
<template> <div> <button type="button" @click="sx()">{{sxpl}}</button> <button type="button" @click="jx()">{{jxpl}}</button> <ul> <li v-for="item in sortedList" :key="item.name"> {{ item.name }} - {{ item.price }} </li> </ul> </div> </template> <script> export default { data() { return { list: [ { name: '物品1', price: 20 }, { name: '物品2', price: 50 }, { name: '物品3', price: 10 }, { name: '物品4', price: 30 } ], ascending: false ,// 标记当前是否为升序排序 sxpl:'价格从低到高', jxpl:'价格从高到低', descending: false// 标记当前是否为降序排序 }; }, computed: { sortedList() { const newList = this.
很久之前就就听说了元胞自动机(cellular automata,CA),但是一直没有尝试。得知2023年美赛春季赛只有两道赛题的时候,怕考到这个,所以出一篇元胞自动机的博客,权且当一篇学习笔记。
尝试过后才发现元胞自动机其实并没有那么难,非常好理解,算是万金油的模拟算法,可以作为保底的plan B。
文章目录 1 原理介绍1.1 概念1.2 原理 2 实例2.1 奇偶游戏2.2 生灭游戏2.3 森林火灾2.3.1 普通森林大火2.3.2 东风森林大火 3 小结 1 原理介绍 1.1 概念 元胞:模拟的时候就是一个有记忆存储状态功能的格子,是元胞自动机的最基本的组成部分。因此元胞具有以下3个特点:
元胞自动机最基本的单元。元胞有记忆贮存状态的功能。所有元胞状态都按照元胞规则不断更新。 状态:每个元胞都有自己的状态,随着时间的推移,状态也会改变。
元胞空间:元胞分布在空间中的格点,可以是1维、2维或n维。
邻居:能影响元胞下一时刻状态的周围元胞。一般来说有三种邻居模式(图是2维情况下的):
当然还有其他的邻居模式,不赘述,主要看题目要求。
边界:整个元胞空间不是无穷大的,是需要一个边界范围的。边界也有好几种类型:固定型、周期型、绝热型、映射型……,个人感觉最后还是得看需要解决的问题,具体问题具体分析。
规则:根据元胞自身及邻居元胞的状态,决定下一时刻元胞状态的决定,可以是动力学函数或状态转移方程。
1.2 原理 这个没啥原理,这部分简单讲讲步骤:
Step1:建立假设、简化条件。
Step2:设置初始状态和边界。
Step3:推导状态转方程和条件。
Step4:根据时间迭代。
基于大量的实验,人们发现元胞自动机根据动力学行为能分为 4 类(Wolfram. S.,1986):
平稳型:自任何初始状态开始,经过一定时间运行后,元胞空间趋于一个空间平稳的构形,这里空间平稳即指每一个元胞处于固定状态。不随时间变化而变化。周期型:经过一定时间运行后,元胞空间趋于一系列简单的固定结构(Stable Patterns)或周期结构(Perlodical Patterns)。由于这些结构可看作是一种滤波器(Filter),故可应用到图像处理的研究中。混沌型:自任何初始状态开始,经过一定时间运行后,元胞自动机表现出混沌的非周期行为,所生成的结构的统计特征不再变止,通常表现为分形分维特征。复杂型:出现复杂的局部结构,或者说是局部的混沌,其中有些会不断地传播。 我们不对每种类型的元胞做实验验证,只提供几种经典和常见的例子。
2 实例 2.1 奇偶游戏 条件:
邻居和为奇数时,中间的数字变成1;邻居和为偶数时,中间的数字变成2。 %%奇偶规则游戏 clear;clc; n = 1000;%指定边界长度 Se = zeros(n); z = zeros(n); Se(n/2-2:n/2+2,n/2-2:n/2+2)=1; %初始化中间的点 Ch = imagesc(Se); axis square; Sd = zeros(n+2); %边界 while(true) %死循环 % 保存现有状态的右2:边界1,右边1 Sd(2:n+1,2:n+1) = Se; % 上下左右加一次 sumValue = Sd(1:n,2:n+1)+Sd(3:n+2,2:n+1)+Sd(2:n+1,1:n)+Sd(2:n+1,3:n+2); % 摸一下 Se = mod(sumValue,2); set(Ch,'cdata',Se); pause(0.
设备协议的燃气价格是4字节,2字节整数,2字节小数,低位在前,它的16进制数据如何表示?
以数据2.06为例,说明下如何转16进制数据、如何解析16进制数据。
16进制表示 整数部分为2,小数部分为0.06
小数部分乘以10000,转成整数,0.06*10000 = 600
整数转为2字节的有符号整数,16进制表示为0x0002,小端模式为0x0200
小数转为2字节的有符号整数,16进制表示为0x0258,小端模式为0x5802
最终结果为0x58020200
为什么小数部分要乘以10000,而不是10、100、1000?
小数位占2字节,2字节表示的最大数是65535,假如小数位有5位,小数位最大位0.99999,乘以10000得到99999,很明显99999>65535;
假如小数位有4位,0.9999,乘以10000的到9999,很明显9999<65535,因此可得小数位最大为4位。
10进制表示 上面例子是低位在前,因此读取数据时要按照小端模式读取,代码如下:
{ ByteBuf payload = ByteBufAllocator.DEFAULT.buffer(); byte[] bytes = new byte[]{0x58, 0x02, 0x02, 0x00}; payload.writeBytes(bytes); // 调用ByteBuf#readIntLE方法,按小端读取 String data = DataUtil.hexToDecimalFor4Bytes(String.format("%08X", payload.readIntLE()), 2); System.out.println("16进制hex=2.06"); System.out.println("解析16进制decimal=" + data); } 工具方法:
/** * 4字节数据转换 * * @param hexData 4字节的16进制数据 * @param integerBytes 整数所占字节数 * @return */ public static String hexToDecimalFor4Bytes(String hexData, int integerBytes) { // hexData = 00020258,因为获取数据是ByteBuf#readIntLE方法,按小端读取 // 整数部分 String left = hexData.
#!/bin/bash # 发布的版本号 VERSION="$1" # 发布的模块名,为null时,deploy整个工程,不为null时,deploy指定的模块及模块依赖的模块 MODULE_NAME="$2" if [ -n "$VERSION" ]; then echo "开始修改pom.xml中版本号为:"${VERSION} mvn versions:set -DnewVersion=$VERSION -DprocessAllModules if [ $? -ne 0 ];then echo "[ERROR] 修改pom.xml版本号失败,详情请看上面日志" exit 1 fi mvn versions:commit echo "修改pom.xml中版本号完成" fi echo "开始编译打包上传......" if [ "$MODULE_NAME" = "src" ];then mvn -U clean deploy -T 1C -Dmaven.compile.fork=true -Dmaven.test.skip=true -Dmaven.install.skip=true -s ../../settings/settings_isv_pro.xml -DaltDeploymentRepository=isv::default::https://xxx/nexus/repository/maven-releases/ elif [ -n "$MODULE_NAME" ];then mvn -U clean deploy --also-make -pl ${MODULE_NAME} -T 1C -Dmaven.
/** * 16进制字符串转ascii字符串 * 如:30303030323032333636363637373737 == 0000202366667777 * * @param hex * @return */ public static String hexToAsciis(String hex) { StringBuilder output = new StringBuilder(""); for (int i = 0; i < hex.length(); i += 2) { String str = hex.substring(i, i + 2); output.append((char) Integer.parseInt(str, 16)); } return output.toString(); } /** * ascii字符串转16进制字符串 * * @param asciis * @return */ public static String asciisToHex(String asciis) { char[] chars = asciis.
文章目录 前言一、概述二、手写代码1. 简要说明2. 代码编写3. 完整代码4. 测试效果 三、项目源码 前言 最近看了一个开源的项目,jfinal-layui,然后这个项目里面有一个 代码生成器 的功能
之前虽然有用过代码生成器,但是从来没有看过相关的源码,所以就研究了一下,个人感觉这个项目的代码生成器还是蛮好的,能够根据指定的数据库和表生成前后端的代码,不过这个项目的框架是 jfinal ,直接把这个代码生成器相关的代码拷到自己的项目当中是运行不起来,而且每个项目的结构都存在一些特有的性质,很难找到一个拿来就能用的代码生成器,介于这一点,我就根据自己项目的架构,利用 jfinal 框架造的轮子,写了一个较为简单代码生成器,同时分享一下我是怎样实现的。
倘如各位想研究下 jfinal-layui 这个项目,可以点击 https://gitee.com/QinHaiSenLin/Jfinal-layui 这个链接去拉取这个项目的源码。
一、概述 代码生成器顾名思义就是一个生成代码的软件,在日常开发中我们可以使用代码生成器来减少一些重复的开发工作,提高开放效率,像我们经常使用的 mybatis 就有一个逆向工程,它能自动帮我们生产数据库对应的实体类,mapper 和 xml 文件等,其实就是一个代码生成器。
那代码生成器的原理是什么呢?
其实很简单,我们要生成的文件肯定是得有一定的规律,然后我们根据这个规律去编写一个统一的模板,按照这个模板去生成相应的代码。
二、手写代码 1. 简要说明 以下内容仅供参考,我提供的只是一种实现方案,可能并不是适用于你的项目,但是只要你理解了我是怎么实现的,你也可以编写一个适合你自己项目的代码生成器。
脱离实际场景的业务没什么意义,前面我也说过,任何项目都有它的独特性,我是根据自己的项目来编写一个符合我要求的代码生成器,所以我先说下我自己的这个项目简单的一个架构。
比如说我的这个项目,要实现一个完整的增删改查的一套的接口,需要有以下几个类的存在,其中红色框框选的部分(实体类 User.java、mapper 文件 UserMapper.java 和 xml 文件 UserMapper.xml)都可以通过 mybatis 的逆向工程生成,而绿色框框选的部分是需要我手动去编写的,所以我需要写的代码生成器是能够帮我去生成绿色框框选部分的文件,比如: Controller 、Service、ServiceImp 、请求体 dto、相应体 dto 以及 subclass 包下的转换器。
关于我这个项目具体的搭建可查看这篇博客:SpringBoot - 快速搭建
那我该如何去实现了,首先我建议你自己写一个标准的增删改查,然后对照你写的东西,去写一个模板,比如我写了一个岗位的 Controller ,代码如下:
package com.duojiala.mikeboot.controller; import com.duojiala.mikeboot.domain.req.QueryPostListReq; import com.duojiala.mikeboot.domain.req.SavePostReq; import com.duojiala.mikeboot.domain.dto.ResponseBean; import io.swagger.annotations.ApiOperation; import org.
在vue里面引入ts文件报错: An import path cannot end with a '.ts' extension. Consider importing xx.js' instead.
方法一(最快)
把引入的xx.ts后缀删除
方法二
# 在tsconfig.json中加入以下配置 "baseUrl": ".", "paths": { "@/*": [ "src/*" ] } 在webpack的配置文件中加入
"includes":"*.ts","*.tsx"
Pinia的坑 pinia不能在初始化之前调用,不然pinia实例化之后会有取不到值的问题,真的坑,也没有报错。需要在实例化后进行调用。
window.postMessage发送对象报错 Uncaught DOMException: Failed to execute 'postMessage' on 'Window': [object Object] could not be cloned.
应该是发送的数据有问题,网上查看对该参数的解释:
尝试用lodash的cloneDeep方法(或者JSON.stringfy)深拷贝该对象再上传,这次能成功了,坑
vue3项目build打包不通过 看了下报错信息,是node_modules里面文件问题。
检查下package.json的build指令是不是vue-tsc --noEmit && vite build
vue-tsc --noEmit:vue 3 的一个类型检测工具,还包括对模板内表达式和组件之间 props 的验证,常用来生成单文件组件的 d.ts 文件。
可以把指令改为: vue-tsc --noEmit --skipLibCheck && vite build;–skipLibCheck 表示在执行 vue-tsc 时忽略 node_moudles 问题
MySQL 部署PXC集群 PXC集群概述 PXC介绍 Percona XtraDB Cluster(简称PXC)
—— 是基于Galera的MySQL高可用集群解决方案
—— Galera Cluster是Codership公司开发的一套免费开源的高可用方案
—— PXC集群主要由两部分组成:Percona Server with XtraDB(数据存储插件)和 Write Set Replication patches(同步、多主复制插件)
—— 官网:http://galeracluster.com
PXC特点 具体如下
—— 数据强一致性,无同步延迟(写入主服务器的数据,所有从服务器必须马上也得有)
—— 没有主从切换操作,无需使用虚拟IP(无需一主多从的结构,无需vip地址)
—— 支持InnoDB存储引擎
—— 多线程复制(多线程同步工作)
—— 部署使用简单
—— 支持节点自动加入,无需手动拷贝数据(服务器会自动同步宕机期间的数据,无需手动配置)
————————————————
相应端口 服务端口
端口
说明
3306
数据库服务端口
4444
SST 端口
4567
集群通信端口
4568
IST 端口
SST
State Snapshot Transfer 全量同步
IST
Incremental State Transfer 增量同步
注:集群通信端口是指集群中各服务器之间通信的端口;数据库服务端口3306和集群通信端口4567是每时每刻都开放的;
SST 端口4444和IST 端口4568只有在做数据同步的时候才会开放
主机角色 三台服务器
主机名
设置el-table数据溢出出现滚动条:
方式1: 看了下element-ui官网,el-table有一个height属性:
直接给el-table设置height属性,height包括表头的高度;设置了height后,则行旁边就会出现一个滚动条了。 但会造成一个问题,如图:
解决方式:
方式2: el-table还有一个max-height的属性
前言:之前配置好Android Studio后,一直在参与课程的两个项目,未能及时更新,最近期末考试,可能又要断更一段时间。今天验收好,跟大家分享一下其中我负责的相机相册调用以及文字识别的部分,大家根据目录选择自己需要的内容。具体项目可能投入使用,所以不方便给项目中的源码,但如下我书写的测试项目运行正常,并能完美实现相关功能!
项目环境:
1、Android Studio 4.1.1
2、华为Nova 3e (安卓9)以及 华为 P20(安卓10)
3、百度智能云-文字识别OCR-通用文字识别(高精度版)
项目流程 一、调用手机相机/相册 注意有些部分是文字识别的方法(已注明),如果不需要文字识别功能,则不需要其代码。 1.activity_main.xml和MainActivity.java
1.1activity_main.xml(约束性布局)以及btnef4.xml(波纹按钮) **activity_main.xml** <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.myapplication.MainActivity" android:background="#13277a"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintWidth_percent="0.8" app:layout_constraintHeight_percent="0.4" android:id="@+id/reportcons1" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:background="@drawable/btnef4" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintVertical_bias="0.3"> <TextView android:id="@+id/albumtext1" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintHeight_percent="0.2" app:layout_constraintTop_toTopOf="parent" android:text="手写/拍照上传" android:background="#fff" android:textSize="24sp" android:textColor="#13277a" android:gravity="center"/> <Button android:id="@+id/rtake_photo" android:layout_width="0dp" app:layout_constraintWidth_percent="0.8" app:layout_constraintHeight_percent="0.3" android:background="@drawable/btnef4" android:layout_height="wrap_content" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintVertical_bias="0.3" android:text="拍照" android:textSize="20dp" android:textColor="#13277a"/> <Button android:id="@+id/choose_from_album" android:layout_width="
方法一:
如果 Ubuntu 系统无法正确识别汉字,可能是由于语言环境设置不正确导致的。您可以尝试以下方法来解决该问题:
检查系统语言环境 请确保您的系统语言环境是正确的。可以使用以下命令查看当前系统所支持的语言:
locale -a 如果输出中没有包含相应的中文语言环境,可以使用以下命令安装中文语言环境:
sudo apt-get install -y language-pack-zh-hans language-pack-zh-hans-base 安装完成后,请检查系统的语言设置是否正确,可以使用以下命令查看和修改系统语言设置:
locale sudo update-locale LANG=zh_CN.UTF-8 将上述命令中的 zh_CN.UTF-8 替换为适合您的语言环境。
修改终端字符集 如果您在终端中遇到了显示错误的情况,可能是由于终端字符集设置不正确导致的。此时可以尝试修改终端字符集。
打开终端窗口后,点击窗口左上角的“菜单”按钮,选择“首选项”->“配置文件”,找到您正在使用的终端配置文件,并进入“文本”选项卡。在“字符编码集”中选择“Unicode(UTF-8)”,保存后重启终端,看看问题是否已经解决。
安装中文输入法 如果您需要在系统中输入中文,可能需要安装一个中文输入法。Ubuntu 系统内置了几种中文输入法,可以在系统设置中查看和配置。打开“设置”->“区域和语言”->“输入源”,选择您需要的中文输入法,并进行相关设置。
如果您需要更多的中文输入法,还可以在 Ubuntu 软件库中搜索并安装其他输入法。
希望以上方法能够帮助您解决问题。
方法二:
如果您在虚拟机中运行 Ubuntu 操作系统时遇到了中文字符显示为文皓的问题,这可能是由于缺少相应的字体库或者字体设置不正确所导致的。以下是一些可能的解决方法:
安装中文语言支持和字体库 如果您的 Ubuntu 操作系统缺少中文语言支持和相应的字体库,中文字符可能会无法正确显示。您可以尝试安装中文语言支持和字体库,具体操作如下:
首先使用以下命令更新软件包列表:
sudo apt-get update 然后运行以下命令安装中文语言支持和字体库:
sudo apt-get install language-pack-zh-hans language-pack-zh-hans-base fonts-wqy-zenhei fonts-wqy-microhei 安装完成后,请重新启动系统,看看问题是否已经解决。
修改终端字体 如果您在终端中遇到了显示错误的情况,可能是由于终端字体设置不正确导致的。此时可以尝试修改终端字体。
打开终端窗口后,点击窗口左上角的“菜单”按钮,选择“首选项”,在“外观”选项卡中选择一个合适的中文字体,比如“文泉驿微米黑”。保存后重启终端,看看问题是否已经解决。
修改系统字体设置 如果以上方法都无法解决问题,还可以尝试修改系统字体设置。在 Ubuntu 系统中,可以通过 “设置”->“外观”->“字体” 来修改系统字体设置。请尝试选择合适的中文字体,并查看是否能够正确显示中文字符。
希望以上方法能够帮助您解决问题。
目的: python实现将数据写入excel文件中。
步骤: 1、导入依赖包xlwt
注意:这里的xlwt是python的第三方模块,需要下载安装才能使用(如果没安装可直接在终端输入pip install xlwt进行安装)。
2、创建excel表格类型文件
3、在excel表格类型文件中建立一张sheet表单
4、将指定值写入sheet
5、保存excel
实例: import numpy as np import xlwt # 随机生成一个3×4的数组(值不超过10) data = np.random.randint(10, size=(3, 4)) # 创建excel表格类型文件 book = xlwt.Workbook(encoding='utf-8', style_compression=0) # 在excel表格类型文件中建立一张sheet表单 sheet = book.add_sheet('sheet1', cell_overwrite_ok=True) for i in range(data.shape[0]): #逐行 for j in range(data.shape[1]): #逐列 sheet.write(i, j, data[i][j]) #将指定值写入第i行第j列 save_path = './data.xls' book.save(save_path) 其中,查看data:
print(data) [[2 1 9 3]
[7 6 7 3]
[9 4 8 4]]
前言:
在上期,我们简单的介绍了关于 模板和STL ,今天我就带领大家学习一下关于 【string】类。本期,我们主要讲解的是关于 【string】的基本介绍以及【string】类的常用接口说明。有了以上的基本认识之后,在下期,我们将模拟实现一个【string】类。
目录
(一)为什么学习string类?
1、 C语言中的字符串
(a)string类的引出🔥
2、两个面试题(暂不做讲解)
(二)标准库中的string类
1、 string类(了解)
2、编码
(a)ascll码
(b)万国码
(c)GBK字库
(三)string类对象的访问及遍历操作
1、遍历三剑客 🔥
(a)迭代器 begin()+end()
(b)迭代器 rbegin()+rend()
(c)for+[]
(d)范围for
2、单个字符
(四)string类对象的常见构造
(五)string类对象的容量操作
1、size() 和 length()
2、capacity()
3、empty()
4、clear()
5、resize()
6、reserve()
(六)string类对象的修改操作
1、push_back()
2、append()
3、operator+=
4、find() 和 npos()
5、rfind()
6、substr()
(七)string类非成员函数
(八)vs和g++下string结构的说明
(九)总结
前言:
string 是C++里面我们最常见的类之一,管理的是字符串。那什么是最常见的呢?
传统的类型,如内置类型只能表示一些基础的信息,当需要表示一些复杂的信息时就不适用了;假如我们要表示地址,表示身份证号码,此时再用日常的类型则无法较好的表示出来; (一)为什么学习string类? 1、 C语言中的字符串 基于上述情况,在C语言中引入了字符串来管理
C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数;但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 (a)string类的引出🔥 💨 假如此时我们的搬家了,这时需要修改家庭住址,地址信息变长了,这就会导致原先的字符串数组存放不下这么多的信息。
💨 因此在 C语言 中不能很好的进行管理,在C++ 中就提出了【string】类来管理字符串。
2、两个面试题(暂不做讲解) 把字符串转化为整数
控制台警告提示信息 控制台警告Runtime directive used on component with non-element root node. The directives will not function as intended. 原因和解决 原因 意思是自定义指令不能放到组件上,而是要放到自有的元素上,也就是这里用到的v-show不能放在自定义组件上,而是放在原来就有的标签上,所以这里套了一层div比如之前的是这样子,v-show指令用在了自定义组件ImageAddR身上,就警告了 <ImageAddR ref="ImageAddR" v-show="materialType === 'image'"></ImageAddR> 解决 外面套一层不是自定义组件的东东就可以,我这里套了一层div,你也可以嵌套一层template <div v-show="materialType === 'image'"> <ImageAddR ref="ImageAddR" ></ImageAddR> </div> 或者(新版本好像会报警告'v-show' directives cannot be put on <template> tags) <template v-show="materialType === 'image'"> <ImageAddR ref="ImageAddR" ></ImageAddR> </template>
现在很多用户都会将网址生成一个二维码,用户只需扫描二维码就可以访问,避免了手动输入网址的繁琐过程。这样既提高了品牌形象,也是一种营销方式。下面就给大家介绍具体的操作方法。
首先我们要将所有的链接整理到一个文本文件中,当然也可以选择其它文件,比如Excel文件,如下图所示就是我们整理好的链接。
然后打开条码标签打印软件,设置文件的尺寸。因为需要导入上面整理好的文本文件作为数据库,所以先点击软件上方的【设置数据源】,数据源类型选择“文本文件”。然后点击【选择文件】,将TXT文件导入到软件中。
从上图中可以看到汉字显示为乱码,勾选“文件内容为UTF8格式”即可。勾选“第一行为表头”即可将第一行内容设置为表头。
在软件左侧选择“二维码”工具,在画布上绘制出一个二维码,在弹出的编辑二维码数据的界面,将二维码类型设置为QR Code,插入数据源字段。
点击软件上方的【打印预览】,根据自己的需要选择纸张并设置排版。检查无误后就可以开始打印了。
综上所述就是将网址批量生成二维码的操作方法,制作方法简便,可以提高工作效率。
本文用举例的方式通俗地讲解了batchnormlization原理,是我觉得比较好理解的方式,比单纯公式好懂得多。
总体功能 将相同channel(特征)的数据进行归一化处理,也就是平移和缩放,让所有特征的量纲(特征值波动范围)差不多一致,可以让所有特征都能发挥作用,满足了glorot条件,有利于训练。
比如我一个特征A的值在0~255之间波动,另一个特征B的值0~1之间波动,那么我的模型去学习A特征带来loss减小的收益是远高于B特征的,因为A特征量纲比较大,对loss的影响也经常B大,模型会致力于去学习A特征,可以使loss降低地更快,带来地收益高,就导致B特征得不到充足的学习,导致最终结果变得不好。
光说可能太过抽象了,我们来举一个例子就好理解多了:实际上处理也就两步 比如我有一个batch(B)中有两张图像,每一张图像由RGB三个特征图组成(这一维度也叫channel即C),图像宽度为W高度为H,
那么一轮输入的size即为:
(B,C,W,H)也就是(2,3,W,H)
我们此时要归一化的话,按channel分为3组(传入batchnorm的数据的第二维默认为channel,所以RGB其实就是不同的特征,想让谁作为特征就放在第二维),每一组都是
(B,1,W,H) --》三张图像的R特征
(B,1,W,H) --》三张图像的G特征
(B,1,W,H) --》三张图像的B特征
处理第一步:进行z-score放缩 作用:将输入数据的均值平移至0点,并将输入数据的方差放缩至1
接着上面的例子:
比如对于R特征,我有(B,1,W,H)也就是B*W*H个点是属于R特征的(B个图每个图都有一个R特征图,每张图上有W*H个点,所以就是B*W*H个点是属于R特征的)
求这B*W*H个点的均值,对应上图的式子1
求这B*W*H个点的方差,对应上图的式子2
B*W*H个点同时减去均值,再除以方差的根号,对应上图的式子3,这步就是在归一化,z-score放缩。
对G和B特征也是同理
处理第二步:带参数的平移放缩 作用:第二阶段相当于在零均值的基础上再进行小规模的变换使其能适应模型,γ和β是属于模型的参数(也就是可以随着反向传播和梯度下降进行跟新的参数,require_grad=True),是可以跟着向前和向后的传播来进行修改的,能够达到生成一个适应模型的修正变换
公式:
new_x=γ*x+β
x是每一个元素
接着第一步:
我们经过第一步,的到了处理过后的RGB特征,总体数据还是(B,C,W,H)
为(B,1,W,H) --》三张图像的R特征 分配1个γ1和β1
(B,1,W,H) --》三张图像的G特征 分配1个γ2和β2
(B,1,W,H) --》三张图像的B特征 分配1个γ3和β3
以R为例子,B*W*H个点同时乘以相同的γ1,再加上相同的β1,即可得到放缩后的结果,γ1和β1都是数,不是数组,比如γ1为3,β1为2。
对G和B特征也是同理
至此bn的操作就完成了 我们可以得出一些结论 1.bn对属于相同的特征的值做加减乘除操作都是都是相同的,比如n1,n2都属于特征1,比如n1+100,n2也必须加上100,n1除以100,n2也必须除以100,这才能保证特征的一个整体分布不会被打乱,也就是各个特征间的相对位置不能有变化。
2.bn层并不会改变输入数据的size,因为只是对数据做了平移和放缩,也就是仿射变换
3.操作的两步本质都是平移和放缩,是一样的
4.第一步C组均值和方差,第二步有C组γ和β,官网也有提到
γ and β are learnable parameter vectors of size C (where C is the number of features or channels of the input).
在Java中,可以使用Redisson这个开源的Java
Redis客户端库来快速向Redis导入上百万key数据。Redisson是一个基于Redis的Java对象和服务框架,它提供了方便的方式来操作Redis数据。
以下是使用Redisson快速向Redis导入上百万key数据的步骤: 首先,需要在项目中添加Redisson依赖。可以在pom.xml文件中添加以下依赖: <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.16.1</version> </dependency> 创建Redisson客户端对象,连接到Redis服务器。可以使用以下代码创建客户端对象: Config config = new Config(); config.useSingleServer().setAddress("redis://localhost:6379"); RedissonClient redisson = Redisson.create(config); 向Redis中添加数据。可以使用以下代码将数据添加到Redis中: RScoredMap<String, String> scoreMap = redisson.getMap("scoreMap"); scoreMap.put("key1", "value1"); scoreMap.put("key2", "value2"); scoreMap.put("key3", "value3"); 这里使用了RScoredMap类型来保存分数对应的key,然后将数据添加到对应的键值对中。
导入数据。可以使用以下代码将数据导入到Redis中 RScoredMap<String, String> scoreMap = redisson.getMap("scoreMap"); ScoreMap<String, String> result = new ScoreMap<>(scoreMap.getBucketNum("", true), scoreMap.getKeyType(), scoreMap.getValueType()); 这里使用了ScoreMap类型来保存分数对应的key,然后根据分数类型和值类型创建对应的键值对结果。
查询数据。可以使用以下代码查询数据: RScoredMap<String, String> scoreMap = redisson.getMap("scoreMap"); ScoreMap<String, String> result = scoreMap.getBucket("", true); for (ScoreMap.Entry<String, String> entry : result.entrySet()) { String key = entry.
一、文件光标定位streampos
在读写文件时,有时希望直接跳到文件中的某处开始读写,这就需要先将文件的读写指针指向该处,然后再进行读写。
ifstream 类和 fstream 类有 seekg 成员函数,可以设置文件读指针的位置;ofstream 类和 fstream 类有 seekp 成员函数,可以设置文件写指针的位置;ostream & seekp (int offset, int mode);istream & seekg (int offset, int mode); mode 代表文件读写指针的设置模式,有以下三种选项:ios::beg:让文件读指针(或写指针)指向从文件开始向后的 offset 字节处。offset 等于 0 即代表文件开头。在此情况下,offset 只能是非负数。ios::cur:在此情况下,offset 为负数则表示将读指针(或写指针)从当前位置朝文件开头方向移动 offset 字节,为正数则表示将读指针(或写指针)从当前位置朝文件尾部移动 offset字节,为 0 则不移动。ios::end:让文件读指针(或写指针)指向从文件结尾往前的 |offset|(offset 的绝对值)字节处。在此情况下,offset 只能是 0 或者负数。 所谓“位置”,就是指距离文件开头有多少个字节。文件开头的位置是 0。
此外,我们还可以得到当前读写指针的具体位置:
ifstream 类和 fstream 类还有 tellg 成员函数,能够返回文件读指针的位置;ofstream 类和 fstream 类还有 tellp 成员函数,能够返回文件写指针的位置;int tellg();
int tellp(); 1、streampos是在stream中的 绝对位置,非负,看成int即可
2、streamoff是与stream中指定点的相对位置,可为负数
3、tellg/tellp 返回值是streampos,返回的是与stream起点的距离
4、seekg/seekp如果有两个 输入参数,那么第一个参数类型为streamoff
二、例子:如何获取文件长度
目录
一、试用期与加班工资
二、招聘
三、月度答辩和转正答辩
四、可信考试认证
五、接口人
六、问题缺陷单
七、代码检视
八、功能开发
九、出征海外
一、试用期与加班工资
试用期持续的时间一般3-6个月,工资、奖金都按正式员工的标准计算。唯一区别在于:试用期的员工,周末加班不能转调休,相当于白加班。因此,不到最忙的时候,组长PL(Program Leader)不会叫试用期员工周末加班,如果非得加班也会通过外出公干的方式让他们调休。
如果周末两天都加班,双倍工资就是4天,相当于基本工资涨80%,接近翻倍了。当然这种连续的周末加班也很消耗精力,无论你有多么强的体魄或是多么年轻,最终都不得不承认:命要紧。现在周末加班,依然按双倍工资计算,但不会下月发,而是给你累计,直到8年一次换工号或者离职的时候,才会统一给你结清。并且周末加班也需要主管审批,不再按打卡时间直接计算。
二、招聘
刚毕业那会,就听说过华为只要是985/211的学生就招,编程题通过就行,几乎不看你的个人经历。华为会以不信任员工为基础建立一套完善的制度和流程让员工把活干漂亮。承受不了压力的人被淘汰,承受住压力并遵从制度和流程的人能活下去,在这基础上智商、情商特别高的人会拿钱到手软。
在华为非HR也要参与招聘,这几乎成了他们在华为职业生涯中的必经之路。他们会根据现有的人才库,挨个打电话询问就职意愿,并引导他们做面试题、在线编程并参与面试官的1对1面试。
存储的招聘预算不太够,因此招聘一般倾向于招OD/WX的员工。OD的员工工号以300开头,WX的员工工号以WX开头,这两种员工都不算华为的正式员工,其中OD的员工相对更优秀些,主要从事开发工作。而WX开头的员工基本只能从事测试工作,他们按照测试文档一步步执行并查看是否符合预期,绝大多数WX员工并不知道自己为什么要这么执行,预期的结果代表着什么,因为他们没有资格参加方案的设计和串讲,也没有TDE(Test Design Engineer,负责设计测试用例的华为员工)愿意跟他们讲解。
由于外包的人员流失较大,因此招聘的任务就很重。同时又倾向于招聘OD/WX的员工,所以招聘难度会很大。总结一下就是:有能力的人看不上OD/WX,没有能力的人又过不了在线编程等考核。
三、月度答辩和转正答辩
在试用期,每个月都会有一次月度答辩,你要做PPT详细描述在这一个月内你做了啥,学到了啥,并现场回答评委的问题。在转正那一次,又需要准备转正答辩,把整个试用期的工作进行总结。
在答辩过程中,评委们都会认真听你讲,并经过思考询问你一些问题,这种气氛还是不错的。实际上,答辩对绩效的作用并不是特别大,因为你平时做的事情大家都能看到,也能估算出分量。
答辩最大的作用在于防止新员工偷懒。当一名员工进入公司后,在完全熟悉流程,成为一颗忙碌的螺丝钉之前,会有短暂的空窗期。在这个阶段,由于你啥也不懂,没人会找你,也没法给你分配任务。这时,如果你知道每个月都需要报告工作和学习进展,就会产生足够的动力,尽快融入团队。转正答辩完成后,基本上你已经是一颗标准的螺丝钉了,这时候不再需要答辩,通过绩效考核进行激励即可。
四、可信考试认证
对开发而言,每个人都需要通过可信考试。可信考试分专业级和工作级,一共四门课,四个考试,往往新来的员工更容易通过,因为他们有更充足的时间;而老员工没有时间学习,几乎都是裸考,除了科目一的在线编程,其他科都是理论知识,涵盖的范围包括编程语言语法和技巧、编程语言规范、需求分析、安全红线、设计模式、敏捷开发等等。这些经验被总结成精炼的语言,通过以考促训的思想灌输到每个员工的脑子
五、接口人
从入职到导师脱手,其实就差不多两个月时间。最重要的任务就是通过可信认证考试。两个月后,开始接手一些简单的任务,修改问题单或者承担一些简单的功能开发。但在一些部门,这时候往往会给你一个恐怖的任务----接口人。
一般而言,一个产品会被分为多个模块,每个小组维护多个模块。当测试发现属于某个组的模块出现问题,或者别的模块依赖该模块的部分工作不正常时,他们需要有人能帮忙查看原因,这个人就叫接口人。
一个组大概10个人,负责的模块代码量在数十~数百万行的级别。乍一看,会觉得应该选一个经验丰富的员工,对组内负责的模块、历史情况等掌握很清楚的人作为接口人。但实际上,帮他人看问题找原因,是一种吃力不讨好的工作,因为领导看不到,身边的同事也感知不到。
在有些公司,通常是主管当接口人,他会对问题进行简单的分析,再根据组内成员的擅长领域、负载情况 ,选择合适的人去分析该问题。在华为,类似的岗位是PL,为了绩效,他们不可能每天把时间浪费在这上面。同时,组内的每个人都忙得要命,最熟悉该领域的人可能正在完成紧急任务,根本没时间去分析。因此,PL通常会找组内资历浅一些的同事去充当接口人,并按固定期限轮换。
一个组维护的代码量不算小,让新员工去做接口人,美其名曰“锻炼”,实际上是让他去抗压。作为接口人,PL的要求就是尽可能不打扰到组内其他人,所有问题,除非真正是Bug,否则不能让测试提单。这样的要求看似简单,但对于新员工而言,很多时候测试咨询的问题你连他讲的啥意思都不明白,再加上设计又存在各种历史原因、特殊情况的考虑,新员工大多是懵逼的。想求助经验丰富的同事?如果项目不太紧张的时候还好说,项目紧张起来,每个人都戴着耳机在通话,你可能好几个小时都见不到他们空闲下来。而测试对你的响应时间是有要求的,一小时不给清楚解释?那就提单吧。
举个例子:你在分析A问题发生的原因,阅读完全陌生的代码,另外2个测试给你留言,找你咨询B、C问题。你简单扫了一下B、C问题,都不是你熟悉的领域,需要花时间去读代码,了解设计,才知道是不是问题,所以你暂时没回复。两分钟后,两个测试分别给你打电话,你很烦,不想接电话,但他们不停的打,并在留言中告诉你再不接电话就提单。你只能接起电话好言相劝,告诉他们现在真的很忙,只能请他们先登记,排队等你的消息。没多久,你读到A问题中一部分看不明白的代码逻辑,想找人问,一抬头组内所有人都在打电话。于是你咬咬牙一边跟A的测试确认测试用例的逻辑,一边忽略部分看不懂的代码去猜测后续的逻辑。这时候B、C的测试告诉你不能再等了,上面催着要提单,你只能暂时放下代码再次解释,给他们合理的截止期限并请求他们接受。突然电话又响了,是一个电话会议,问题很严重,线上四五个开发正在一起讨论,需要你做确认,TDE催促让你赶紧看,搞不定就往上捅。你赶紧放下A问题,一边读D问题的现象,一边凭你的理解去回答这几个开发的问题。D问题的难度不大,但涉及的条件特别多,变量也多,逻辑很绕,你得理一理,正在理的过程中,A测试的TDE气愤的给你留言:都看了两个小时了怎么还没结果?必须提单了。
如果实在搞不定了,测试等不及要提单,一般是要跟PL讲的。但作为新员工,你要做好心理准备,因为这时候免不了一顿臭骂。因为PL永远是忙得要死,他有方案要讨论,有设计要做,还有大量组内杂事,本来已经焦头烂额,你不仅不能帮他分担,还告诉他现有的某个问题搞不明白,他也是很崩溃的。但这顿骂往往又是值得的,因为PL会快速给你指明方向,因为如果是定位偏了,他会快速纠正你的方向。
六、问题缺陷单
刚才提到很多次“提单”,就是指的问题单。测试提的问题单,一般代表某个模块的功能有Bug。
问题单的跟踪,华为有一套系统叫DTS,测试提单,开发解决的流程大致如下:
测试外包员工在DTS系统中创建一个问题单,填写产品、版本、问题描述等信息。
问题单提给负责该模块的测试TDE(华为正式员工)审核。
测试TDE把问题单转发给负责该模块开发的组内PL。
组内PL再把问题转发给需要解决该问题的开发。
开发把问题解决,提交代码,填写根因分析并把问题单转给组内PL。
开发同时需要与测试TDE预约时间,与测试TDE串讲问题单发生的原因和修改后的影响。
组内PL等串讲完成并且最新的Build包含开发的Commit Id后,将问题单转给测试TDE。
测试TDE将问题单转交给测试外包员工进行验证。
这么一套流程走下来,感觉脱了层皮。对于上级领导来说,他不需要知道细节,只需要要求一个组的问题单的目标数量即可。比如今天整个组剩下40个问题单,明天的要求是35个,后天是30个…
于是,为了达成目标,PL非常反感问题单走到自己组头上。有的问题单涉及到模块间的协调处理,测试提单的时候发现的是A模块的问题,但A模块经研究后发现,实际问题出在A模块依赖的B模块身上,B模块由另一个组维护,于是跟B模块的接口人沟通。这种情况,即使已经基本确定是B模块的问题,B模块的PL、接口人也会想尽一切办法拖延问题单走给B模块的时间,定位问题根因和修改方案后,才会同意问题走到B模块。毕竟每天的问题单目标放在那里,多一个在自己头上,都是沉重的负担!这种时候,A模块的PL肯定也不希望问题单在自己组,所以这时候就看他们两个PL的PK了,作为PL,至少都在华为奋斗了好几年,大家像战友一样有感情,互相理解下,这次留给你,下次留给我,互相不撕破脸。
在这套流程中,开发最不喜欢的步骤就是测试串讲。这个设计的初衷是好的:担心你的改动造成的影响测试不清楚,从而无法对受影响的场景进行测试。但遗憾的就是这个规定太死板,绝大多数的串讲根本没有意义,只需要测试进行原场景复现,并检查问题是否解决即可。
问题单的设计如此复杂,依然是对员工的不信任。在其它公司,流程就简单多了:
测试创建问题单,填写产品、版本、问题描述等信息。
问题单提给需要解决该问题的开发者。
开发把问题解决,提交代码,填写根因分析和需要重点测试的场景,把单转回给测试验证。
步骤的简化,就对员工的素质要求高。就拿问题单与测试的串讲来说,一般开发人员觉得这个改动的影响比较大,可能需要重点测试一些场景的时候,就会在问题单上注明;同理,测试如果意识到开发人员的改动有风险,或者对开发人员的根因分析不太理解时,也会主动找开发人员沟通。
华为的流程复杂,它的基本逻辑是:信任DE/TDE这种在华为干了很长时间的老员工,新员工不值得信任。配套的激励也是倾向于PL/DE/TDE,这会让新员工做得很憋屈,但这没关系,因为总会过滤出一批忍得住憋屈,愿意遵从规则坚持努力下去的人。
复杂的流程导致了一个问题,就是测试TDE的繁忙程度超乎想象。因为一个测试TDE往往负责多个模块,也就是对应着多位开发,当问题单较多的时候,容易形成了单点瓶颈。举个例子,假设一名TDE手上有10个外包测试员工,分别测出了10个问题,这10个问题对应着8个开发,那这8个开发人员修复完问题后,跟外包测试员工串讲并不算数,必须排队给这名TDE串讲,从而形成了单点瓶颈。
测试TDE忙得找不着北,脾气自然也不会太好。开发更是一点也不敢得罪测试,如果TDE不爽你,别的不说,就单单在串讲里给你挑刺、或者把你的串讲排到最后,都会大大拖慢你的工作进度和工作热情。
七、代码检视
代码检视,也就是Code Review。每个开发写好代码后,都必须发代码检视才能合入主干分支。
在其它公司,开发一般会找对这个领域比较熟悉的两个开发进行检视,得到两个Approve以后,就顺手合入了。
在华为,代码合入理论上需要以下步骤:
选择两个开发检视
检视通过后选择一个Committer审核
审核通过后,选择具有合入权限的人合入。
一般Committer是在一个团队里的资深员工,技术比较强,并且做事仔细认真。
在其它公司,代码合入步骤简化为:
不同pcl版本的安装配置有微小差异,低版本要稍微复杂一点,建议选择跟博客一样的配置,防止奇奇怪怪的错误。本次配置是windows + vs2019 + pcl1.10.1
1.下载pcl1.10.1 Release pcl-1.10.1 · PointCloudLibrary/pcl · GitHub
这里没有选择源码编译,cmake稳定,但是复杂一点
2.解压安装 这里选择将pcl添加到环境路径(大概率会报错,没关系,后面如果报错可以手动添加)
然后安装位置是可以自己选的,但是你得自己找得到 ,后面一路点击下一步,安装就好。
3.添加环境路径 刚刚虽然选择了将pcl添加到环境路径,但是大概率会报一个错:path too long installer unable to modify path。问题不大,叉掉就好,接下来手动添加一下:
① 打开高级系统设置,点击环境变量 ② 下方系统变量中先添加一个名为Pcl_Root的变量,路径是你安装的pcl位置 ③ 然后点击Path,添加如下变量。这样子就把路径分为两部分,就不会too long了 4.vs2019配置pcl 到这里pcl基本上就安装好了,不过想要在vs里面使用,还需要配置一番。这里提供一种一劳永逸的配置方法,不用每次新建一个项目还要重复的配置。
① 首先打开vs,新建一个空项目,点击视图->其他窗口->属性管理器 ② 在右侧选中这个Microsoft.Cpp.x64.user,并且右键点击它进入属性 这里顺便说一下,我自己配置时,没有出现这个Microsoft.Cpp.x64.user。是因为缺失了一个文档,下载以下放到对应的位置即可。这里给出一篇参考博客(5条消息) 解决vs2019属性管理器里面没有Microsoft.Cpp.x64.user_vs2019属性窗口没东西_WangSaLe的博客-CSDN博客
③ 进入属性页后,首先在vc++中配置包含目录和库文件(不要完全照抄我的,因为我安装的pcl跟你的可能不一样,需要找到对应的文件位置) 包含目录其实就是你安装的pcl中一系列include文件位置,如下:
D:\3dparty\PCL 1.10.1\3rdParty\Boost\include\boost-1_72
D:\3dparty\PCL 1.10.1\3rdParty\OpenNI2\Include
D:\3dparty\PCL 1.10.1\3rdParty\VTK\include\vtk-8.2
D:\3dparty\PCL 1.10.1\3rdParty\FLANN\include
D:\3dparty\PCL 1.10.1\3rdParty\Eigen\eigen3
D:\3dparty\PCL 1.10.1\include\pcl-1.10
只包含到include也是没有问题的,Eigen特殊一点,没有include,但也要包含。
库目录其实就是一系列lib文件的位置,如下:
D:\3dparty\PCL 1.10.1\3rdParty\OpenNI2\Lib
D:\3dparty\PCL 1.10.1\3rdParty\VTK\lib
D:\3dparty\PCL 1.10.1\3rdParty\Qhull\lib
D:\3dparty\PCL 1.10.1\3rdParty\FLANN\lib
D:\3dparty\PCL 1.10.1\3rdParty\Boost\lib
D:\3dparty\PCL 1.
需求 需求:前端对接LED显示屏,且可以根据LED指令说明灵活性设置
了解 了解:设备LED指令是按照gb2312编码(16进制)来实现
思路 思路:需要将输入的内容转为16进制的gb2312编码格式发送给设备才可以,在这里笔者遇到一个坑,后面有详说
准备工作 准备工作:
下载encode-gb2312包,作用是将输入的字符串内容转为符合要的gb2312编码下载twitter-text包,作用是计算字符串输入的字节长度 npm install encode-gb2312 // 这里小编使用的是encode-gb2312 0.0.2版本 npm install twitter-text // 这里小编使用的是twitter-text 3.1.0版本 在使用的页面导入包
import twitter from ‘twitter-text’;
案例+效果图 下面笔者会将全部代码放入,先看下页面效果:
案例:
如果能够做到精准,一家一策、一人一策,当然是最好的,但需要通过专业人员评估社区环境、家庭通风下水条件等,确保周围是安全的。现实是没有可靠的评估的方法,很多社区也做不到这一点,采取集中隔离的策略是考虑到现实情况
、
转义:
AAA5F800FFFF0000B0A1100302000000000000008000040001000200F40100000000000000000000FFFFD000C8E7B9FBC4DCB9BBD7F6B5BDBEABD7BCA3ACD2BBBCD2D2BBB2DF3001D2BBC8CBD2BBB2DFA3ACB5B1C8BBCAC7D7EEBAC3B5C4A3ACB5ABD0E8D2AACDA8B9FDD7A8D2B5C8CBD4B1C6C0B9C0C9E7C7F8BBB7BEB33001BCD2CDA5CDA8B7E7CFC2CBAECCF5BCFEB5C8A3ACC8B7B1A3D6DCCEA7CAC7B0B2C8ABB5C43002CFD6CAB5CAC7C3BBD3D0BFC9BFBFB5C4C6C0B9C0B5C4B7BDB7A8A3ACBADCB6E0C9E7C7F8D2B2D7F6B2BBB5BDD5E2D2BBB5E3A3ACB2C9C8A1BCAFD6D0B8F4C0EBB5C4B2DFC2D4CAC7BFBCC2C7B5BDCFD6CAB5C7E9BFF600005A55
、
效果图:
遇到的坑(解决方法) 遇到的坑:要求格式是00 00,10进制的125转为16进制结果为7D,结果应该为7D 00,写入指令发送是没有反应的,是错误的,搞了半天发现这里格式须为00 7D,才可以指令发送成功,显示出来,所在代码中的位置function()函数详看就知道了
完整代码 <template> <!-- 设备推送 --> <div class="warn"> <van-nav-bar title="LED设备" left-text="返回" left-arrow @click-left="onClickLeft" > <template #right > <van-icon name="setting-o" size="20" v-show="active == '3'" @click="show = true"/> </template> </van-nav-bar> <van-popup v-model="show" title="
let a; if(a!=null&&typeof(a)!=undefined&&a!=''){ //a有内容才执行的代码 } 之前判断变量a为非空,未定义或者非空串才能执行以上方法体的内容,这样的代码看着很臃肿,代码也很冗余!
实际上我们只需要写一个判断表达以下:
if(!!a){ //a有内容才执行的代码 } 这样就可以和最上面达到同样的效果。a是有实际含义的变量才执行方法,否则变量null,undefined和空串都不会执行以下代码。
引申
! 是逻辑与运算,并且可以与任何变量进行逻辑与将其转化为布尔值;
!! 则是逻辑与的取反运算。
后者在判断类型时代码简洁高效,省去了多次判断null、undefined和空字符串的冗余代码,
所以后期使用用尽量使用 !!
最近一直没写博客,因为本人忙于申博而无暇顾及其他(最终终于上岸了)。笔者这几年也一直忙于让公司推动公司进行微服务方案整改。整改完成之后,决定还是再进行一次技术总结,于是,就又学习了一遍技术方案,然后在网络上翻到了周志明博士的《凤凰架构》(目录 | 凤凰架构)。学完之后,大为叹服。决定写几句有点心得体会。
1.架构是长出来的,而不是完全设计出来的。
2.微服务架构应该和组织的实际架构一致,即康威定律:
Any organization that designs a system will produce a design whose structure is a copy of the organization's communication structure.(系统的架构趋同于组织的沟通结构。)
3.不要为了技术而盲目推微服务方案,适合自己的才是最好的。
4.架构的历史是由原始分布式到单体,由单体到SOA,由SOA到微服务,再到后微服务和无服务。其中一条基本思路是:让架构变得不那么重要,让架构师只负责顶级架构设计,让工程师负责业务;而让工程师专注于业务,也是符合公司的理性的。
5.基于一系列不可靠装置上可以设计出一个可靠的系统。
6.JAVA之所以流行是因为这种语言的平台无关性(一次编译,到处运行);但Docker等虚拟容器在打破这个语言的优势,因为Docker也在搭建跨平台层。
7.博士的学习,不仅仅是熟悉具体的技术方案,而且是要理解整体行业和领域,对整体行业领域有个融会贯通,并可以突破。
我们在实际操作tree组件和后台交互的时候一般都是需要将父节点传过去,如图
需要把协同管理的ID一起传给后台,但是ant的tree组件的checkedvalue只会选择到请假管理的ID,所以我们需要在执行check的时候
const onCheck = (checked, e) => { //注意:halfCheckedKeys 是没有全部勾选状态下的父节点 allKeys.value = checked.concat(e.halfCheckedKeys); // console.info(allKeys.value); }; <Tree v-model:checkedKeys="checkedKeys" class="!p-4" defaultExpandAll checkable :tree-data="treeData" :fieldNames="{ children: 'children', title: 'name', key: 'id' }" @check="onCheck" /> 但是这样做的话,当我们在编辑的时候后台数据也会返回给我们一个父节点ID导致组件会默认全部勾选,所以我们要对返回的选中id组合进行筛选
//json 是指treedata idarr 是后台返回的id数组 temp 是return出来的一个筛选过的数组 开始的时候传空 const resolveAllEunuchNodeId = (json: any[], idArr: any[], temp: any[] = []) => { for (const item of json) { if (item.children && item.children.length !== 0) { resolveAllEunuchNodeId(item.children, idArr, temp); } else { temp.
文章目录 spring循环依赖?请谈一下你对 spring 的理解?说一下 Spring 的核心是什么?请谈 一下你对 Spring IOC 和 和 AOP 的理解?请说一下 Spring 的 的 Bean 作用域?请谈一下Spring中bean对象的生命周期?Spring中的事务是如何实现的 ?请谈一下Spring的两种事务形式?Spring容器启动流程是怎样的?Spring事务什么时候会失效?BeanFactory 和 ApplicationContext有什么区别?Spring 事务的传播行为了解吗?Spring 提供了几种事务的传播行为?Spring事务的隔离级别?请谈一下 Spring 事务回滚机制 ?说一下过滤器和 Spring 拦截器的区别 ?拦截器的实现原理是什么?简单说一下拦截器用场景 ?反射机制了解吗?知道 spring 中哪些用的反射吗 ?使用@Autowired注解自动装配的过程是怎样的 ? spring循环依赖? 当我们的类 A 中引用 B,B 引用 C,C 又引用 A 的时候,这个时候会产生循环依赖。Spring 所解决的循环依赖是有限
定条件的。首先 bean 必须是要单例模式。其次需要通过 get,set 的方式注入才行。使用构造器方式注入和多例模
式都不能解决循环依赖的问题。
根据 Spring 的初始化流程。Spring 先是用构造实例化 Bean 对象 ,此时 Spring 会将这个实例化结束的对象放到一
个 Map 中,并且 Spring 提供了获取这个未设置属性的实例化对象引用的方法。
首先理解为我们先实例化 A,A 此时并没有,于是从一级缓存区中取 A,取不到,然后取二级缓存区中取 A,也取不
文章目录 说一下 JVM 的主要组成部分及其作用?说一下 JVM 运行时数据区 ?JVM中哪些是线程共享区 ?说一下堆栈的区别?队列和栈是什么?有什么区别?说一下类装载的执行过程?什么是类加载器 ? Java中有哪些类加载器?描述一下JVM加载Class文件的原理机制 ?JVM 的双亲委派机制?怎么确定⼀个对象到底是不是垃圾?什么是STW ?JVM中的永久代中会发生垃圾回收吗 ?Java会存在内存泄漏吗?请简单描述 ?Finalize 遗言对程序的弊端 ?说一下 JVM 有哪些垃圾回收算法 ?说一下 JVM 有哪些垃圾回收器 ?详细介绍一下 CMS 垃圾回收器 ?新生代垃圾回收器和老年代垃圾回收器都有哪些?有什么区别 ?简述分代垃圾回收器是怎么工作的 ?⼀个对象从加载到JVM,再到被GC清除,都经历了什么过程 ?简述Java内存分配与回收策率以及Minor GC和Major GC ?JVM参数有哪些 ?常用的 JVM 调优的参数都有哪些 ?常用的 JVM 调优的参数都有哪些?你们项目如何排查 JVM 问题?说一下 JVM 调优的工具? 说一下 JVM 的主要组成部分及其作用? JVM包含两个子系统和两个组件,两个子系统为Class loader(类装载)、Execution engine(执行引擎);两个组件为Runtime data area(运行时数据区)、Native Interface(本地接口)。
Class loader(类装载):根据给定的全限定名类名(如:java.lang.Object)来装载class文件到
Runtime data area中的method area。
Execution engine(执行引擎):执行classes中的指令。
Native Interface(本地接口):与native libraries交互,是其它编程语言交互的接口。
Runtime data area(运行时数据区域):这就是我们常说的JVM的内存。
说一下 JVM 运行时数据区 ? 程序计数器:当前线程所执行的字节码的行号指示器,用于记录正在执行的虚拟机字节指令地址,线程私有。
文章目录 union 和 unionAll 的区别?drop、delete与truncate的区别 ?sql 语句如何优化 ?SQL语句的中关键字执行顺序 ?mysql的explain有哪些列数据库的三范式什么是事务 ?事务的四个特性(ACID) ?事务的隔离级别?索引主要有哪几种分类 ?Mysql聚集索引 ?Mysql的非聚集索引 ?Mysql的回表查询 ?什么时候适合添加索引,哪些列适合添加索引 ?什么情况会使索引失效 ?B 树和 B+树的区别?为什么 Mysql 使⽤B+树 ?MyISAM 和 InnoDB 的区别 ?从锁的分类来说,MySQL都有哪些锁?行级锁和表级锁对比 ?什么是死锁?如何解决?数据库的乐观锁和悲观锁是什么?怎么实现的?乐观锁和悲观锁的使用场景 ?什么是redo log日志 ?什么是binlog日志 ?什么是undo log日志 ?什么是 MVCC 以及实现 ?什么是主从复制 ?主从复制的作用 ? union 和 unionAll 的区别? union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序
unionAll: 对两个结果集进行并集操作,包括重复行,不进行排序
drop、delete与truncate的区别 ? 相同点:
truncate和不带where子句的delete,以及drop都会删除表内的数据
不同点:
truncate会清除表数据并重置id从1开始,delete就只删除记录,drop可以用来删除表或数据库并且将表所占用的空间全部释放
truncate和delete只删除数据不删除表的结构。drop语句将删除表的结构被依赖的约(constrain),触发器(trigger),依赖于该表的存储过程/函数将保留,但是变为 invalid 状态。
速度上一般来说: drop> truncate > delete
使用上,想删除部分数据行用 delete,想删除表用 drop,想保留表而将所有数据删除,如果和事务无关,用truncate即可。如果和事务有关,或者想触发trigger,还是用delete。
delete是DML语句,不会自动提交。drop/truncate都是DDL语句,执行后会自动提交。
sql 语句如何优化 ? 1.建议少用*代替所有列名
2.用 exists 代替 in
Java–LocalTime类获取时间信息 LocalTime nowTime = LocalTime.now(); System.out.println(nowTime);//获取时间 System.out.println(nowTime.getHour());//获取时 System.out.println(nowTime.getMinute());//获取分 System.out.println(nowTime.getSecond());//获取秒 System.out.println(nowTime.getNano());//获取纳秒 System.out.println(nowTime.withHour(19));//修改时 System.out.println(nowTime.withMinute(18));//修改分 System.out.println(nowTime.withSecond(17));//修改秒 System.out.println(nowTime.withNano(16));//修改纳秒 System.out.println(nowTime.minusHours(1));//一小时前 System.out.println(nowTime.minusMinutes(1));//一分钟前 System.out.println(nowTime.minusSeconds(1));//一秒钟前 System.out.println(nowTime.minusNanos(1));//一纳秒前 System.out.println(nowTime.plusHours(1));//一小时后 System.out.println(nowTime.plusMinutes(1));//一分钟后 System.out.println(nowTime.plusSeconds(1));//一秒钟后 System.out.println(nowTime.plusNanos(1));//一纳秒后 LocalTime other = LocalTime.now().minusHours(1);//一小时前 System.out.println(nowTime.isBefore(other));//比较当前时间是否在other对象时间之前 System.out.println(nowTime.isAfter(other));//比较当前对象时间是否在other对象时间之后 System.out.println(nowTime.compareTo(other));//比较当前对象时间与other对象时间在时间上的大小,为正,则nowTime晚 System.out.println(LocalTime.of(8, 20));//时分 System.out.println(LocalTime.of(8, 20, 30));//时分秒 System.out.println(LocalTime.of(8, 20, 30, 150));//时分秒纳秒 LocalTime mTime = LocalTime.of(8, 20, 30, 150); System.out.println(LocalTime.ofSecondOfDay(mTime.toSecondOfDay()));//参数为距离当天零时的秒数 System.out.println(LocalTime.ofNanoOfDay(mTime.toNanoOfDay()));//参数为距离当天零时的纳秒数 System.out.println(LocalTime.parse("08:20:30")); System.out.println(LocalTime.parse("082030", DateTimeFormatter.ofPattern("HHmmss")));
文章目录 前言restricted取消SIP保护最常用的 `csrutil disable`最安全的 前言 我尝试操作/bin目录下的文件,比如执行chmod 777 ./sh、mkdir test-dir,会发现报错Operation not permitted
这是由SIP(系统完整性保护)引起的
https://support.apple.com/en-us/HT204899
在受SIP保护的目录中,我们无法进行创建文件、修改文件等操作
restricted 如果你使用ls -lO查看/usr/local,你会发现下面的大部分文件都被打上了restricted标志
wushu@wushudeMacBook-Pro /bin % ls -lO total 9400 -rwxr-xr-x 1 root wheel restricted,compressed 121120 Jan 1 2020 [ -r-xr-xr-x 1 root wheel restricted,compressed 1296704 Jan 1 2020 bash -rwxr-xr-x 1 root wheel restricted,compressed 121984 Jan 1 2020 cat -rwxr-xr-x 1 root wheel restricted,compressed 107552 Jan 1 2020 chmod -rwxr-xr-x 1 root wheel restricted,compressed 123264 Jan 1 2020 cp -rwxr-xr-x 1 root wheel restricted,compressed 1106144 Jan 1 2020 csh -rwxr-xr-x 1 root wheel restricted,compressed 277440 Jan 1 2020 dash -rwxr-xr-x 1 root wheel restricted,compressed 139312 Jan 1 2020 date 这就是SIP的标识符,它的用途就是告诉macOS的SIP,这个文件受到系统保护,不能更改。
有时候站长不希望自己网页页面被其他站的FRAME嵌套进去, 这时候就需要的HTTP协议头里增加X-Frame-Options这一项。
X-Frame-Options的值有三个:
(1)DENY — 表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
(2)SAMEORIGIN — 表示该页面可以在相同域名页面的 frame 中展示。
(3)ALLOW-FROM https://example.com/ — 表示该页面可以在指定来源的 frame 中展示。
下面是重点:
NGINX配置X-Frame-Options响应头的方法
把下面这行添加到nginx的站点配置文件中,加到’http’, ‘server’ 或者 ‘location’ 的配置中均可。
add_header X-Frame-Options SAMEORIGIN;
卷积神经网络(LeNet) 文章目录 卷积神经网络(LeNet)一、前言二、LeNet结构三、LeNet原理1. 卷积层2. 池化层3. 全连接层 四、LeNet实现1. 数据准备2. 模型定义3. 模型训练4. 模型测试 五、总结 一、前言 卷积神经网络(Convolutional Neural Network,CNN)是一种深度神经网络,广泛应用于图像处理、自然语言处理等领域。LeNet是最早的卷积神经网络之一,由Yann LeCun等人在1998年提出,用于手写数字的识别。本文将介绍LeNet的结构、原理和实现。
二、LeNet结构 LeNet的结构如下图所示:
输入层 卷积层 池化层 卷积层 池化层 全连接层 全连接层 输出层 LeNet包含7层网络结构,其中第1、2层是卷积层,第3、4层是池化层,第5、6层是全连接层,第7层是输出层。
三、LeNet原理 1. 卷积层 卷积层是LeNet的核心部分,它通过卷积操作提取图像的特征。卷积操作可以看做是一个滤波器(Filter)在图像上滑动,对每个位置的像素值进行加权求和。卷积操作的公式如下:
y i , j = ∑ m ∑ n x i + m , j + n w m , n y_{i,j} = \sum_{m}\sum_{n}x_{i+m,j+n}w_{m,n} yi,j=m∑n∑xi+m,j+nwm,n
其中, x x x是输入图像, w w w是滤波器, y y y是输出特征图, i , j i,j i,j表示输出特征图的坐标, m , n m,n m,n表示滤波器的坐标。
文章目录 一、I2C驱动框架(1)I2C驱动框架介绍(2)I2C总线驱动介绍【1】i2c_adapter结构体【2】i2c_algorithm结构体【3】I2C总线驱动工作介绍 (3)I2C设备驱动介绍【1】i2c_client结构体【2】i2c_driver结构体 (4)I2C 核心介绍 二、sht20驱动开发流程(1)sht20相关命令(2)驱动程序结构 三、sht20驱动开发(1)硬件连接(2)修改编译设备树(3)编写驱动代码(4)执行结果 四、重难点分析(1)Linux下DEVICE_ATTR介绍【1】DEVICE_ATTR宏定义【2】代码实现【3】测试讲解 (2)container_of介绍【1】作用介绍【2】举个栗子 源码是学习上一届学长的,想要参考的可以去拜访一下gitee:源码链接
对于I2C不了解的可以参考这篇文章,里面有介绍I2C的相关知识以及时序:I2C协议介绍以及HAL库实现I2C对SHT30温湿度采样
sht20获取数据具体流程(软复位、数据处理公式)可以参考这篇文章:IGKBoard(imx6ull)-I2C接口编程之SHT20温湿度采样
具体tftp服务器搭建不懂的可以参考这篇文章:wpa_supplicant无线网络配置imx6ull以及搭建tftp服务器
uboot使用tftp从网络启动设备树和zImage的可以参考这篇文章:Linux嵌入式uboot使用tftp网络启动加载zImage、设备树
一、I2C驱动框架 (1)I2C驱动框架介绍 在 Linux 内核中 I2C 的体系结构分为 3 个部分:
I2C 总线驱动: I2C 总线驱动是对 I2C 硬件体系结构中适配器端的实现, 适配器可由CPU 控制, 甚至可以直接集成在 CPU 内部。I2C 总线驱动就是 SOC 的 I2C 控制器驱动,也叫做 I2C 适配器驱动。I2C 设备驱动: I2C 设备驱动是对 I2C 硬件体系结构中设备端的实现, 设备一般挂接在受 CPU 控制的 I2C 适配器上, 通过 I2C 适配器与 CPU 交换数据。I2C 核心: I2C 核心提供了 I2C 总线驱动和设备驱动的注册、 注销方法 在 Linux 系统中则采用了总线、设备驱动模型。我们之前讲解的平台设备也是采用了这种模型,只不过平台总线是一个虚拟的总线。
我们知道一个i2c(例如i2c1)上可以挂在多个i2c设备,例如sht20、i2c接口的OLED显示屏、摄像头(摄像头通过i2c接口发送控制信息)等等, 这些设备共用一个i2c,这个i2c的驱动我们称为i2c总线驱动。而对应具体的设备,例如sht20的驱动就是i2c设备驱动。 这样我们要使用sht20就需要拥有“两个驱动”一个是i2c总线驱动和sht20设备驱动。i
2c总线驱动由芯片厂商提供(驱动复杂,官方提供了经过测试的驱动,我们直接用)。sht20设备驱动可以从sht20芯片厂家那里获得,也可以我们手动编写。 i2c 总线包括 i2c 设备 (i2c_client) 和 i2c 驱动 (i2c_driver), 当我们向 linux 中注册设备或驱动的时候,按照 i2c 总线匹配规则进行配对,配对成功,则可以通过 i2c_driver 中.
VMware workstation 17 pro 配置虚拟机(Cent OS7)的保姆机教程 前言 对于Linux初学者来说,VMware这个虚拟机软件就是不错的选择。下面我们一起来看看VMware配置虚拟机的详细过程。
提示:以下是本篇文章正文内容,下面案例可供参考
一、工具 VMware版本:VMware workstation 17 pro 下载地址:[添加链接描述](https://www.vmware.com/cn/products/workstation-pro.html) Linux镜像文件:CentOS 7 下载地址:[添加链接描述](https://mirrors.tuna.tsinghua.edu.cn/centos/7.9.2009/isos/x86_64/) 此处省略VMware workstation 17 pro和CentOS 7的下载安装教程
二、VMware workstation 17 pro创建虚拟机步骤 1.新建虚拟机 2.选择自定义,以便于安装CentOS7。 3.直接下一步。 4.选择稍后安装操作系统。 5.选择Linux系统,版本选择centos7。 如果自己的电脑是32位就选centos7 32位;如果自己的电脑是64位就选centos7 64位。
6.设置虚拟机名称,以及安装位置,安装位置最好不选C盘。 7.每个处理器内核数量建议选2。 8.虚拟机内存建议选择2048MB。 9.网络类型选择NAT模式。 10.选择推荐 11.选择推荐 12.默认选择,直接下一步 13.最大磁盘大小建议20G。 14. 直接下一步 15.确定。 16.完成以上步骤后,双击CD/DVD,j进入设置 17.选择ISO映像文件,找到自己下载的centos7映像文件,然后确定。 18.开启刚刚配置的虚拟机,经过一段时间的等待,进入以下界面,选择中文。 19.点击软件选择。 20.选择最小安装。勾选开发工具,它会帮你下载一些常用开发工具。 21.进入安装位置。 22.选择自动分区。 23.进入网络和主机。 24.打开以太网。 25.设置root密码,完成安装。 26.安装完成后出现以下界面,输入用户名root和密码后,就是安装成功啦。 这一步完事儿之后,就要进入到我们的Linux 系统了
三、虚拟机配置固定IP 关于为什么要配置这样一个东西,这是因为当前我们虚拟机的Linux操作系统,其IP地址是通过DHCP服务获取的。 DHCP:动态获取IP地址,即每次重启设备后都会获取一次,可能导致IP地址频繁变更 这样每次都变的话,会不舒服,所以,我们需要把IP地址固定下来。 其实配置固定IP 的步骤很固定:
在VMware Workstation(或Fusion)中配置IP地址网关和网段(IP地址的范围)在Linux系统中手动修改配置文件,固定IP 1.编辑——虚拟网路编辑器 2.选择VMent8,更改设置 3.
WebFlux 服务编排是指使用 WebFlux 框架来编排多个异步服务的执行顺序和数据流动,从而构建出一个完整的、基于事件驱动的响应式应用程序。
WebFlux服务编排的优势如下:
高性能:WebFlux基于响应式编程模型,可以使用少量的线程处理大量的请求,从而提高系统的并发能力和吞吐量。
异步处理:WebFlux可以异步处理请求和响应,避免线程的阻塞和等待,提高系统的并发能力和性能。
高可靠性:WebFlux基于事件驱动的编程模型,可以更好地处理错误和异常,从而提高系统的可靠性和稳定性。
简洁清晰:WebFlux的代码简洁清晰,可以使用函数式编程风格来编写业务逻辑,提高代码的可读性和可维护性。
可扩展性:WebFlux可以轻松地集成其他的响应式组件和服务,例如Reactive Streams、Spring Cloud、RSocket等,从而提高系统的可扩展性和灵活性。
综上所述,WebFlux服务编排可以帮助我们构建高性能、高可靠性、可扩展性强的响应式应用程序,提高系统的并发能力和性能,从而更好地满足现代应用程序的需求。
一个示例
public Mono> getOrderDetails(String orderId) { return Mono.fromCallable(() -> { // 查询订单基本信息 return "order info"; }) .flatMap(orderInfo -> { // 查询订单商品信息 return Mono.fromCallable(() -> { return "order item info"; }); }) .flatMap(orderItemInfo -> { // 查询订单配送信息 return Mono.fromCallable(() -> { return "order delivery info"; }); }) .flatMap(orderDeliveryInfo -> { // 查询订单支付信息 return Mono.fromCallable(() -> { return "
HTTP协议中的PUT方法是将指定资源的内容替换为请求中所包含的新内容。PUT方法可以用于上传或更新文件,也可以用于创建新的资源。当PUT方法可用时,客户端可以将文件上传到Web服务器并将其存储为已命名的文件或文件夹。但在某些情况下,PUT方法可能会导致服务器安全漏洞,例如,PUT请求可能会导致服务器存储敏感信息或恶意代码。因此,在一些安全标准中,PUT方法被视为不安全的,很多Web服务器默认情况下是禁用PUT方法的。
[GDOUCTF 2023]EZ WEB 访问页面没事东西,源码提示就在眼前,看到了/src,访问是个py文件
import flask app = flask.Flask(__name__) @app.route('/', methods=['GET']) def index(): return flask.send_file('index.html') @app.route('/src', methods=['GET']) def source(): return flask.send_file('app.py') @app.route('/super-secret-route-nobody-will-guess', methods=['PUT']) def flag(): return open('flag').read() 这里我访问chat,我太菜了
这是一个使用 Flask 框架编写的 Python 代码,它创建了一个 Web 应用程序,并定义了三个路由:
"/" 路由:使用 GET 方法返回 "index.html" 文件。"/src" 路由:使用 GET 方法返回 "app.py" 文件。"/super-secret-route-nobody-will-guess" 路由:使用 PUT 方法打开名为 "flag" 的文件并将其中的内容返回给客户端。 可以看出,第三个路由是一个秘密路由,只有当请求方法为 PUT 并且路径为 "/super-secret-route-nobody-will-guess" 时才能访问。它会打开名为 "flag" 的文件并将其中的内容返回给客户端。这可能是一个漏洞,因为未对该路由进行身份验证或授权检查,攻击者可以通过篡改 HTTP 请求来绕过安全控制,获取敏感信息或执行恶意操作。
PUT请求?用bp抓包,改一下请求方式,然后改文件路径在发包,就返回falg了
[NSSRound#1 Basic]basic_check Dir没扫出来有用的东西
Nikto扫描扫描出PUT提交
这和上一题也是put提交,那么用bp抓一下,上传个shell?
上传成功
找到NSSCTF{0f3453aa-6199-442e-bb08-04d3cd2a2515}