阿里云服务器8080端口开放在安全组中放行,Tomcat默认使用8080端口,8080端口也用于www代理服务,阿腾云atengyun.com以8080端口为例来详细说下阿里云服务器8080端口开启教程教程:
阿里云服务器8080端口开启教程 阿里云服务器8080端口默认是不开启的,默认只开放22和3389远程端口。如果云服务器上搭建Tomcat需要使用8080端口,需要用户手动去安全组中开通。端口号来详细说下在阿里云服务器安全组开启8080端口教程:
哦对了,安全组是一种虚拟防火墙,阿里云服务器端口开放或禁用需要在安全组中设置,如果安全组中没有开启8080端口,无论iptables防火墙中如何设置都无法开启8080端口。
1、登录到阿里云服务器ECS管理控制台
在左侧“实例与镜像”中选择“实例”,找到需要开放80端口的云服务器,如果没有找到,记得在顶部切换云服务器地域。在阿里云CLUB中心领券 aliyun.club 专用满减优惠券。
2、点击“更多”–“网络和安全组”–“安全组配置”,如下图:
阿里云服务器安全组配置规则
在打开窗口点击“配置规则”
3、在“入方向”,点击“手动添加”,规则如下:
授权策略:允许优先级:1协议类型:自定义TCP端口范围 目的:8080/8080授权对象 源:0.0.0.0/0描述:可填,可不填,自己知道就行 如下图:
阿里云服务器安全组开启8080端口
然后点“保存”即可。不需要重启,配置安全组规则开放端口是即时生效的,不需要重启云服务器。举一反三,如果开启80端口就在端口范围中填80/80,以上为端口号分享的阿里云服务器安全组开启8080端口教程。
在上一篇博文中介绍了一种轻量级的跨进程通讯方案-Messenger,Messenger实现起来非常简单,其底层原理也是AIDL,更像是一个简易版的AIDL,但简单的东西往往也有其局限性,Messenger的主要作用是传递消息,它无法实现RPC功能也就是无法让我们在客户端本地就能调用远程的方法,而且Messenger是以串行的方式处理,无法同时处理多个请求,只能一个一个的处理。而AIDL就可以很好弥补Messenger的不足,虽然实现起来相对复杂一些,但它功能强大,无疑是跨进程通讯的首选方案。接下来我们先看看AIDL是什么,都可以传递哪些数据,并且本文会用一个小例子来直观的体会AIDL的实现过程。
读完本文你将深入掌握以下几个知识点:
AIDL是什么?AIDL传递的类型。怎么创建AIDL。AIDL文件中的定向tag:in、out、inout的区别。如何在AIDL中添加权限校验。 一、AIDL是什么? AIDL全称Android Interface Definition Language,即Android接口定义语言。AIDL是Android中可以实现跨进程通讯的一种方案,通过AIDL可以实现RPC方式,所谓RPC是指远程过程调用(Remote Procedure Call),可以简单的理解为就像在本地一样方便的调动远程的方法。在Android的跨进程通讯的方案中,只有AIDL可以实现RPC方式。
二、AIDL文件支持哪些数据类型: 基本数据类型:int、long、char、boolean、double等StringCharSequenceArrayList:里面每个元素也需要被AIDL支持HashMap:里面的每个Key和Value也都需要被AIDL支持Parcelable:所有实现了此接口的对象AIDL:所有的AIDL接口本身也可以在AIDL文件中使用 三、创建AIDL 接下类用一个小例子来说明AIDL的创建过程及用法,尽管在同一个APP内依然可以指定两个进程,但为了更能凸显“跨进程”这一点,还是决定将此示例借助于两个APP来实现,毕竟在开发中真实的需求也是发生在两个APP中。
在实现AIDL的过程中服务端APP和客户端APP中要包含结构完全相同的AIDL接口文件,包括AIDL接口所在的包名及包路径要完全一样,否则就会报错,这是因为客户端需要反序列化服务端中所有和AIDL相关的类,如果类的完整路径不一致就无法反序列化成功。
小技巧:为了更加方便的创建AIDL文件,我们可以新建一个lib工程,让客户端APP和服务端APP同时依赖这个lib,这样只需要在这个lib工程中添加AIDL文件就可以了!
简要说明一下将要实现的小例子的需求:是一个通讯录,在服务端维护一个List用来存放联系人信息,客户端可以通过RPC方式来添加联系人、获取联系列表等功能。
1、新建一个承载AIDL文件的lib(在本示例中姑且叫做libaidl) 创建一个Android Library类型的Module,为了与普通的java代码作区分,在main文件夹下为AIDL文件新建一个专门的文件夹,新建工程的结构如下: 然后添加AIDL接口文件: 首先新建一个Contact类,通过上面的介绍我们知道,普通的java类是不能在AIDL中使用的,必须要实现Parcelable接口,并在AIDL文件中声明:
Contact.java
/** * Created by liuwei on 18/2/8. */ public class Contact implements Parcelable { private int phoneNumber; private String name; private String address; public Contact(int phoneNumber, String name, String address) { this.phoneNumber = phoneNumber; this.name = name; this.address = address; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.
在Android中进程间通信是比较难的一部分,同时又非常重要,针对进程间通信,博主会用四篇文章来介绍,本篇文章为IPC系列的开篇,主要介绍一些IPC中用到的一些概念、基础等,目的是让读者朋友们在学习IPC之前对一些必要的知识有一个大体的把握。在Android中进程间通讯的方式有很多种,在后续的三篇中会分别介绍每一种方式的实现过程已经各自的优缺点。
IPC是什么? IPC(全称:Inter-Process Communication)为进程间通讯,指至少两个进程间传递数据或信号的一些技术活方法。
注:进程间通讯是至少两个进程之间发生的事情,我们通常习惯性的会把一方称为客户端,一方称为服务端,在后续的文章也会多次出现客户端和服务端,没接触过进程间通信的童鞋可能一开始会不太习惯,这里要注意一下。
为什么要使用IPC? 无论是在计算机系统还是Android系统中每个进程都有自己一部分独立的系统资源,彼此是隔离的,为了能是不同的进程互相访问资源并协同工作,就需要用到进程间通讯。
RPC是什么? RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。(-来自百度百科)
在后面介绍AIDL时会用到RPC的概念,在这里简要说明一下RPC在Android的进程间通讯所扮演的角色,以博主本人的理解,简单来说RPC机制就是指在本地即可调用远程进程中的方法,而不需要关心其底层实现。
在Android中IPC有哪几种实现方式? Bundle文件共享ContentProviderMessagerAIDLSocket 如何开启一个进程 在四大组件的AndroidManifest配置中配置process属性
比如这个:
<service android:name=".messager.MessengerService" android:exported="true" android:process=":remote" /> “:”开头和不带“:”的有什么区别:
“:”开头的进程属于当前应用的私有进程,其他应用的组件不能和它跑在同一进程下。 不带“:”的进程属于全局进程,其他应用可以通过ShareUID和它跑在同一进程下。
Android系统会为每一个应用分配一个UID,具有相同的UID才能共享数据。 通过ShareUID跑在同一进程中需要两个应用有相同的ShareUID并且有相同的签名才可以。
Android系统为每一个进程分配一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致不同的虚拟机访问同一个类的对象会产生多个副本。
使用多进程会导致如下问题:
静态变量和单例失效线程同步机制失效SharePreference可靠性下降Application多次创建 IPC中涉及到的基础概念 SerializableParcelableBinder Serializable 使用Serializable进行序列化很简单,只需要实现Serializable接口,然后为类指定一个serialVersionUID即可。
Serializable中的serialVersionUID工作机制:
序列化时系统会把当前类的serialVersionUID写入序列化的文件中(或其他中介)反序列化时系统去检测文件中的serialVersionUID,对比是否和当前类的seralVersionUID一致。一致就说明序列化的类的版本和当前类的版本是相同的,可以成功反序列化,否则就说明当前类和序列化的类相比发生了某些转换,就会报错(java.io.InvalidClassException) 静态变量属于类不属于对象,不参与序列化过程用transient关键字标记的成员变量不参与序列化过程 Parcelable 使用Parcelable进行序列化比Serializable要麻烦一些,需要实现Parcelable接口,并实现一些必要方法,其通常形式如下:
public class Contact implements Parcelable { public int phoneNumber; public String name; public String address; public Contact(int phoneNumber, String name, String address) { this.phoneNumber = phoneNumber; this.name = name; this.address = address; } public Contact() { } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.
简介 在我们常用的手机应用中,经常会见到一些数据列表,如设置页面、通讯录、商品列表等。下图中两个页面都包含列表,“首页”页面中包含两个网格布局,“商城”页面中包含一个商品列表。
上图中的列表中都包含一系列相同宽度的列表项,连续、多行呈现同类数据,例如图片和文本。常见的列表有线性列表(List列表)和网格布局(Grid列表):
为了帮助开发者构建包含列表的应用,ArkUI提供了List组件和Grid组件,开发者使用List和Grid组件能够很轻松的完成一些列表页面。
List组件的使用 List组件简介 List是很常用的滚动类容器组件,一般和子组件ListItem一起使用,List列表中的每一个列表项对应一个ListItem组件。
使用ForEeach渲染列表 列表往往由多个列表项组成,所以我们需要在List组件中使用多个ListItem组件来构建列表,这就会导致代码的冗余。使用循环渲染(ForEach)遍历数组的方式构建列表,可以减少重复代码,示例代码如下:
@Entry @Component struct ListDemo { private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] build() { Column() { List({ space: 10 }) { ForEach(this.arr, (item: number) => { ListItem() { Text(`${item}`) .width('100%') .height(100) .fontSize(20) .fontColor(Color.White) .textAlign(TextAlign.Center) .borderRadius(10) .backgroundColor(0x007DFF) } }, item => item) } } .padding(12) .height('100%') .backgroundColor(0xF1F3F5) } } 效果图如下:
设置列表分割线 List组件子组件ListItem之间默认是没有分割线的,部分场景子组件ListItem间需要设置分割线,这时候您可以使用List组件的divider属性。divider属性包含四个参数:
strokeWidth: 分割线的线宽。
目录
pyenv-win简介
pyenv-win安装
配置环境变量
pyenv的基本命令
pyenv安装py环境
pyenv安装遇到问题
pycharm测试
pyenv-win简介 什么是pyenv-win: 是一个在windows系统上管理python版本的工具。它是pyenv的windows版本,旨在提供类似于unix/linux系统上的pyenv功能。允许用户在同一台计算机上安装多个python版本,并轻松切换它们之间的环境。使用pyenv-win,可以方便地安装、管理和切换各种python版本,而无需手动更改系统环境变量。
pyenv-win应用场景:pyenv-win可以应用于各种领域,但在机器学习方面尤其有用。在机器学习领域,通常需要使用多个python库和工具来进行数据处理、模型训练和预测等任务。不同的库和工具可能对不同版本的python有不同的要求,因此使用pyenv-win可以轻松地管理这些不同版本的python,并切换到特定的环境,以满足不同的需求。
pyenv-win的特点:轻量级的python版本管理工具,相比于同样为python管理工具Anaconda,体积更为小巧,并且还提供了虚拟环境的支持,可以为不同的项目创建独立的python环境,从而避免不同项目之间的依赖冲突。这对于机器学习项目来说尤其重要,因为不同的项目可能需要不同版本的python和不同的库。
总之,pyenv-win是一个非常有用的工具,可以帮助机器学习开发者轻松管理多个python版本和虚拟环境,从而提高开发效率和项目可维护性。对于有多个python环境需求的开发者来说,pyenv-win是个不错的选择!
pyenv-win安装 打开 pyenv-win下载地址 ,点击Code,然后再点击Download ZIP进行下载压缩包:
将pyenv-win压缩包解压到不带中文的目录下,并将文件夹名称重命名为pyenv:
打开文件夹找到bin目录,并将文件夹路径进行复制:
配置环境变量 电脑搜索框输入 “高级系统设置”,打开后点击环境变量:
在系统变量中点击新建,然后将 PYENV 添加到系统变量中,并配置上面复制的目录,点击确认:
在系统变量中找到Path这个变量,双击打开,将下面这两行路径加进去,然后点击确定,点击完里面的确定再点击环境变量的确定
%PYENV%\bin %PYENV%\shims 至此环境变量配置完成,为了验证我们是否配置成功,cmd终端执行pyenv,出现如下界面说明我们已经安装成功:
pyenv的基本命令 以下pyenv的常用命令,掌握这些基本的命令之后,就可以在项目中轻松切换python版本:
查看pyenv-win支持的python版本列表:
pyenv install --list 查看当前python对应版本:
pyenv version 查看电脑安装的所有python版本:
pyenv versions 安装指定版本 || 也可以在一个命令中安装多个版本:
pyenv install <version> || pyenv install <version> <version> 卸载指定版本:
pyenv uninstall <version> 将python版本设置为全局版本(默认使用的python版本) 注意:必须先安装该版本。
pyenv global <version> 设置本地版本(当在此文件夹中调用python时,都会使用给定的版本。) 注意:必须先安装该版本。
pyenv local <version> 查看python版本来核对:
六、 实现细节
都有哪些开源的卷积神经网络实现
caffe中卷积神经网络各个层(卷积层、全连接层、池化层、激活函数层、内基层、损失层等)
Caffe2 与caffe 对比
caffe2 开源吗
使用caffe的c++ 版本和python版本,分别适用于哪些场景
6.1 卷积层
在进行预测时,训练时 正向传播区别
采用矩阵乘法的优势
6.2 激活函数
在神经网络中,激活函数通常是将向量中的每个元素独立地映射到一个新的值。这种映射是逐元素(element-wise)的,也就是说,每个元素的新值只取决于该元素的原值。
例如,ReLU(Rectified Linear Unit)激活函数就是一个常见的逐元素映射。它将输入向量中的每个元素x映射到max(0, x),即如果x大于0,就保留x,否则就将x置为0。同样,Sigmoid激活函数也是一个逐元素映射。它将输入向量中的每个元素x映射到1 / (1 + exp(-x)),这样可以将x的值压缩到0和1之间。
6.3 内积层
反向传播是同时对多个样本进行计算的。
6.4 损失层
Multinomial Logistic Loss
Infogain Loss - a generalization of MultinomialLogisticLossLayer.
Softmax with Loss - computes the multinomial logistic loss of the softmax of its inputs. It's conceptually identical to a softmax layer followed by a multinomial logistic loss layer, but provides a more numerically stable gradient.
目录
注意
3. 模板
topic.html
4. 将显示所有主题的页面中的每个主题都设置为链接
topics.html
18.5 小结
第 19 章
用户账户
19.1 让用户能够输入数据
19.1.1 添加新主题
1. 用于添加主题的表单
forms.py
2. URL模式new_topic
urls.py
3. 视图函数new_topic()
views.py
4. GET请求和POST请求
5. 模板new_topic
new_topic.html
往期快速传送门👆(在文章最后):
感谢大家的支持!欢迎订阅收藏!专栏将持续更新!
--snip-- 1 def topic(request, topic_id): """显示单个主题及其所有的条目""" 2 topic = Topic.objects.get(id=topic_id) 3 entries = topic.entry_set.order_by('-date_added') 4 context = {'topic': topic, 'entries': entries} 5 return render(request, 'learning_logs/topic.html', context) 这是第一个除request对象外还包含另一个形参的视图函数。这个函数接受正则表达式 (?P\d+)捕获的值,并将其存储到topic_id中(见1)。在2处,我们使用get()来获取 指定的主题,就像前面在Django shell中所做的那样。在3处,我们获取与该主题相关联的条目, 并将它们按date_added排序:date_added前面的减号指定按降序排列,即先显示最近的条目。我们将主题和条目都存储在字典context中(见4),再将这个字典发送给模板topic.html(见5)。
注意 2处和3处的代码被称为查询,因为它们向数据库查询特定的信息。在自己的项目中编 写这样的查询时,先在Django shell中进行尝试大有裨益。相比于编写视图和模板,再在 浏览器中检查结果,在shell中执行代码可更快地获得反馈。
1、资源管理 (1)陈述式资源管理(常用——查、增)
使用kubectl工具进行命令行管理
①特点:对资源的增删查比较方便,对改不友好
②优点:90%以上的场景都可以满足
③缺点:命令冗长、复杂
(2)声明式资源管理(常用——部署资源)
使用yml文件进行声明式资源管理
(3)GUI图形化资源管理
2、kubectl命令详解 (1)查看 kubectl命令大全网站http://docs.kubernetes.org.cn/683.html
查看版本信息
kubectl version
查看所有api的资源对象
kubectl api-resources
查看k8s的集群信息
kubectl cluster-info
自动补齐命令
基本信息查看
查看master节点的状态
kubectl get cs
查看默认命名空间内的pod信息
kubectl get pod
查看当前集群所有命名空间
kubectl get namespaces
查看指定命名空间里的pod
kubectl get pod -n 命名空间名称
查看默认命名空间内pod的详细信息
kubectl get pod -o wide
查看指定命名空间内的pod详细信息
kubectl get pod -o wide -n 命名空间名称
查看node节点信息和状态
kubectl get node
查看node节点的详细信息
kubectl get node -o wide
查看已经部署好的pod的详细信息
kubectl describe pod pod名称
将学习自动化测试时的医药管理信息系统项目用idea运行 背景 学习自动化测试的时候老师的运行方式是把医药管理信息系统项目打包成war包后再放到tomcat的webapp中去运行,于是我想着用idea运行会方便点,现在记录下步骤方便以后查找最开始没有查阅资料,启动项目后输入网址显示404,直接命令行运行tomcat时可以正常访问,想必是配置的问题,懒得翻之前的笔记了,还是直接百度,看到的是这篇IDEA 导入web项目ok下面就是步骤了 步骤 一、用idea打开项目 如果你的项目是个war包,记得先解压打开 IDEA 后点击 open 选择要导入的项目
二、导入 jar 包 找到 jar 包后在该文件夹下右键,选择 Add as Library,把它加进仓库里面去
一般保持默认就可以,你也可以随便取名,点击 OK 就可以了。
三、配置 Project(项目) 点击 File -> Project Structure 首先设置项目的 SDK
设置输出目录,也就是 out 目录,一般放在项目目录下,我是先在项目目录下创建了一个名out的文件夹,然后在Project Structure中选择这个文件夹
四、配置 Modules (模块) 标识 Sources:点击 Modules,选择 sources, 然后右键 WEB-INF 下的mms ,将它标识为 sources 目录:
配置 Dependencies:选择 dependencies, 点击加号,选择 Library, 然后选择你的 Tomcat 服务器,点击 Add Selected:
然后在复选框里打钩,并 Apply:
添加 Web 配置:点击加号,选择 Web
需要更改部署描述文件的位置,也就是我们常说的 web.xml文件,点击右侧的铅笔更改:
下面的 Web Resource Directory 也要改, 这里改的是 Web 资源仓库,就是制定哪一个文件夹是你的 web 资源目录,我这里选的是项目mms的位置
通配符的基本概念 Java中的通配符?用于泛型编程。它表示未知的类型,通常用于声明泛型类型、方法参数或返回类型,使得代码可以更加通用和灵活。
通配符的分类 无界通配符(Unbounded Wildcard) ? 表示任何类型都是合法的。例如,List<?> 表示“具有任何类型元素的列表”。 有界通配符(Bounded Wildcard) ? extends Type 表示类型的上界,意味着接受Type或者它的任何子类。用例详细解? super Type 表示类型的下界,意味着接受Type或者它的任何父类。用例详细解例如,List<? extends Number> 表示“具有Number或其子类类型元素的列表”。 通配符的使用场景 作为参数类型 当你想要编写一个能够接受泛型类型而又不关心具体类型参数的方法时,可以使用通配符。例如,编写一个打印列表中所有元素的方法:void printList(List<?> list) { /* ... */ } 泛型类和接口 在声明泛型类或接口时使用通配符,以提供更大的灵活性。例如,声明一个可以与任何类型的Comparator一起工作的方法:void sort(List<?> list, Comparator<?> c) { /* ... */ } 通配符的限制 不能实例化通配符类型的对象。无界通配符类型的对象不能添加除了null之外的任何元素。有界通配符可能会限制某些方法的使用,因为编译器只知道类型的上界或下界。 通配符和类型擦除 在运行时,泛型信息会被擦除,但通配符有助于在编译时期提供类型安全。 通配符的好处 提高API的灵活性。使得代码更加通用,能够处理更广泛的数据类型。有助于减少代码中的强制类型转换。 通配符?是Java泛型中的一个关键概念,通过其灵活的使用,可以编写出更加通用和类型安全的代码。
前言 12月份参加了开放原第四季线下活动,觉得很有意义。通过这篇博文,记录一下这次活动进行的移植TobudOS内核的过程,下面就让我们开始吧。
开发板介绍 本次使用的开发板型号为STM32H750,当然了,其他型号的开发版也是可以的,只要是支持 ARM Cortex M 核芯片的都是可以的,移植方法都是类似的。
环境准备 2.1 STM32CubeMX STM32CubeMX是ST公司推出的一种自动创建单片机工程及初始化代码的工具,适用于旗下所有STM32系列产品。此软件可以作为eclipse插件形式安装,也可以单独运行,需要安装JAVA运行环境。软件可以在ST官网上找到,下载地址为:https://www.st.com/content/st_com/zh/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html,安装过程非常简单,在此不详述。
建议采用管理员方式运行,因为ST对软件版本及其集成的库更新频繁,无管理员权限容易安装失败。
2.2 Keil编译器 本移植指南针对的是 Keil 编译器,所以我们移植内核前需要先安装 Keil 编译器,能编译 ARM Cortex M 核的 Keil 编译器,现在也叫 MDK,下载地址为:https://www.keil.com/demo/eval/arm.htm 填写注册信息即可下载,下载完成在 windows 环境下按照提示安装即可,安装完成后需要自行购买软件 License,避免 32K Flash 下载限制。 由于新版本的 MDK 编译器和芯片支持包是分离的,所以 MDK(Keil)安装完成后,还需要安装对应芯片的器件支持包(PACK 包)。
准备芯片的裸机工程 3.1 启动 STM32CubeMX,新建工程 3.2 选择MCU型号 双击后弹出工程配置界面,如图:
3.3 配置时钟源 3.4 配置串口 3.5 配置GPIO 3.6 配置总线时钟 3.7 工程配置 3.8 代码生成配置 3.9 点击Generate Code生成工程 生成代码后,在Keil 中打开该工程,编译运行,无报错,就说明裸机工程代码已经生成完毕啦!
接下来就是进行TobudOS内核移植的过程啦,让我们继续。
TobudOS简介 TobudOS是面向物联网领域开发的实时操作系统,早期版本基于腾讯自研的物联网操作系统TencentOS Tiny,2020年由腾讯捐赠到开放原子开源基金会进行孵化,2023年正式更名为TobudOS,TobudOS具有低功耗,低资源占用,模块化,安全可靠等特点,可有效提升物联网终端产品开发效率,提供精简的 RTOS 内核,内核组件可裁剪可配置,可快速移植到多种主流 MCU (如 STM32 全系列) 及模组芯片上。而且,基于 RTOS 内核提供了丰富的物联网组件,内部集成主流物联网协议栈(如 CoAP/MQTT/TLS/DTLS/LoRaWAN/NB-IoT 等),可助力物联网终端设备及业务快速接入物联网云平台。
在Java中,? extends Type是一个上界通配符,表示参数化类型的上限是Type。这意味着容器可以持有Type类型的任何对象或者Type的子类型对象。
使用场景 这种类型的通配符常用于泛型方法中,允许方法接受Type的实例或其子类型的集合。这同样基于PECS原则,即如果你需要一个提供(生产)指定类型元素的集合,使用? extends。
例子
假设我们有以下类的层次结构:
class Animal {} class Dog extends Animal {} class Cat extends Animal {} 现在,我们有一个方法,它的目的是从一个集合里读取Animal对象:
public void processAnimals(List<? extends Animal> animals) { for(Animal animal : animals) { // 这里可以安全地调用Animal类的方法 } } 这个方法接受的参数是一个列表,这个列表的类型是Animal或Animal的任何子类型。因此,以下的调用是有效的:
List<Animal> animalList = new ArrayList<>(); List<Dog> dogList = new ArrayList<>(); List<Cat> catList = new ArrayList<>(); processAnimals(animalList); // 正确:列表的类型正好是Animal processAnimals(dogList); // 正确:Dog是Animal的子类型 processAnimals(catList); // 正确:Cat是Animal的子类型 在这个例子中,无论是Animal列表、Dog列表还是Cat列表,都可以传递给processAnimals方法,因为它们都满足? extends Animal的条件。这样做的好处是你可以将方法的使用范围扩展到更多的子类型,同时能够在提取元素时保持类型安全。
遍历 使用? extends Type时,遍历集合是安全的,因为你确切知道集合中的每个元素至少是Type类型。因此,你可以调用Type中定义的方法,而不需要进行任何类型转换。
在Java中,? super Type是一个下界通配符,表示参数化类型的下限是Type。这意味着容器可以持有Type类型的任何对象或者Type的父类型对象。
使用场景 这种类型的通配符通常用于泛型方法中,允许方法接受Type的实例或其父类型的集合。这是基于PECS原则(Producer Extends, Consumer Super),即如果你需要一个提供(生产)指定类型元素的集合,使用? extends;如果你需要一个消费(接受)指定类型元素的集合,使用? super。
例子
假设有一个基类Animal和两个子类Dog和Cat
class Animal {} class Dog extends Animal {} class Cat extends Animal {} 现在,我们有一个方法,它的目的是往一个集合里添加Dog对象:
public void addDogsToList(List<? super Dog> dogs) { dogs.add(new Dog()); // 这是允许的,因为List可以是Dog或其父类型 } 这个方法接受的参数是一个列表,这个列表的类型是Dog或Dog的任何父类型。因此,以下的调用都是有效的:
List<Animal> animalList = new ArrayList<>(); List<Dog> dogList = new ArrayList<>(); List<Object> objectList = new ArrayList<>(); addDogsToList(animalList); // 正确:Animal是Dog的父类型 addDogsToList(dogList); // 正确:列表的类型正好是Dog addDogsToList(objectList); // 正确:Object是所有类的父类型 在这个例子中,无论是Animal列表、Dog列表还是Object列表,都可以传递给addDogsToList方法,因为它们都满足? super Dog的条件。这样做的好处是,你可以将方法的使用范围扩展到更通用的类型,同时仍然能够向集合中添加特定类型的元素(在本例中是Dog)。
遍历 使用? super Type时,遍历集合可能会受到一些限制,因为你不知道集合中元素的确切类型。你只能确保它们是Type或其父类的实例。在遍历时,通常需要将元素视为Type的父类类型,这样会丢失与Type相关的特定信息。
A. DS二叉排序树之创建和插入 题目描述 给出一个数据序列,建立二叉排序树,并实现插入功能。
在建立和插入操作后,都输出二叉树的先序遍历结果i
输入 第1行输入n,表示序列包含n个数据
第2行输入n个数据,都是自然数且互不相同,数据之间用空格隔开
第3行输入m,表示要插入m个数据
输入m行,每行一个要插入的数据,都是自然数且和前面的数据不等
输出 第一行输出一开始构建的二叉排序树的先序遍历结果
从第二行起,输出m行,每行输出插入一个数据到二叉排序树后的先序遍历结果
每行输出的遍历结果中,每个数据后面都带一个空格,最后一个数据也带。
样例查看模式 正常显示查看格式
输入样例1 6\n
22 33 55 66 11 44\n
3\n
77\n
50\n
10\n
输出样例1 22 11 33 55 44 66 \n
22 11 33 55 44 66 77 \n
22 11 33 55 44 50 66 77 \n
22 11 10 33 55 44 50 66 77 \n
输入样例2 6\n
33 55 22 66 11 44\n
nmcli con show
NAME UUID TYPE DEVICE Wired connection 1 ********-****-****-****-************ ethernet eth0 tailscale0 ********-****-****-****-************ tun tailscale0 docker0 ********-****-****-****-************ bridge docker0 nmtui
manual
address 192.168.1.*/24
gateway 192.168.1.1
nmcli con up 'Wired connection 1'
ip r
KMP算法(Knuth-Morris-Pratt algorithm)是一种用于字符串匹配的高效算法,它的时间复杂度为O(m+n),其中m为模式串的长度,n为文本串的长度。KMP算法通过利用模式串中的重复信息,避免了朴素算法中不必要的比较,提高了匹配的效率。
KMP算法的核心思想是使用一个辅助数组next[],用于存储模式串中每个位置的最长公共前后缀长度。通过利用这些信息,可以在匹配过程中跳过一些不必要的比较,从而提高匹配的效率。
下面是KMP算法的实现代码:
#include <stdio.h> #include <string.h> // 构建next数组 void getNext(char* pattern, int* next) { int patternLength = strlen(pattern); next[0] = -1; int i = 0, j = -1; while (i < patternLength - 1) { if (j == -1 || pattern[i] == pattern[j]) { i++; j++; next[i] = j; } else { j = next[j]; } } } // 使用KMP算法进行字符串匹配 void kmpMatch(char* text, char* pattern) { int textLength = strlen(text); int patternLength = strlen(pattern); int next[patternLength]; getNext(pattern, next); int i = 0, j = 0; while (i < textLength) { if (j == -1 || text[i] == pattern[j]) { i++; j++; if (j == patternLength) { printf("
1.分层索引 分层索引就是在一个轴上拥有多个(两个及以上)索引级别,能以低维度形式处理高维度数据。
行索引有两层 1.1 分层索引的创建 1.1.1 方式一:直接设置
1)在创建series、dataframe或读取文件时时,行名或列名输入一个二维的列表;2)使用语句:data.set_index( ) 括号中输入一个含多个列名的列表 set_index会生成一个新的dataframe,使用一个或多个列作为索引
reset_index是它的反函数,分层索引中的索引层级会被移动到列中
import pandas as pd data = {"城市":["北京","上海","深圳","广州"], "同比":[120.7,127.3,119.4,140.9], "环比":[101.5,101.2,101.3,120.0], "定基":[121.4,127.8,120.0,145.5]} # 法一 data1 = pd.DataFrame(data, index = [["A","A","B","B"],[1,2,1,4]], #第一层中相同的要放在一起 columns =["城市","同比","环比","定基"]) # 法二 data2 = pd.DataFrame(data,columns =["城市","同比","环比","定基"]) data2 = data2.set_index(['城市','同比']) 输出结果如下:
我们得到的就是一个以 MutiIndex 对象 作为索引的 美化视图
print(data.index) #打印dataframe的索引 返回结果如下: 1.1.2 利用方法属性创建 以下方法只是创建出多维索引 Mutiindex 对象,还需要在定义时将其赋给Dataframe 创建语法:pd. MutiIndex.下述方法()
方法描述from_arrays接收一个多维数组,高维指定高层索引,低维指定底层索引from_tuples 接收一个元组的列表,每个元组指定每个对应索引
(高维索引,低维索引) 如上图
from_product接收一个可迭代对象的列表,使用笛卡尔积的方式创建 补充:笛卡尔积 两个集合X和Y的笛卡尔积(X × Y)是指 第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员
例如:A={a, b},B={0, 1, 2},则笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
写给自己 工作之后,已经好久没有学习编程、码代码了,因为最开始是从python开始接触的编程,所以对于一些底层的逻辑了解不够清晰,所以打算从0开始学习一下C语言程序。
C语言 关于其相关历史优劣等,在这里不再一 一赘述,主要说明一下C语言参考手册,这是最权威及官方的也是最权威的C语言参考文献,应该熟练并掌握运用和查询解决遇到的问题。
可以直接搜索creference,打开后是英文界面,但是不要慌,下方语言选择中文,就可以切换到中文模式了。我们可以看到上面的内容很全面,有语言,头文件,各种库的相关文件,我们以内存管理为例,点击进入后,可以看到,C语言与之相关的全部内容就展示出来了,使用时需要引入什么头文件,具体每一个函数的作用是什么。
参考手册更好的一点就是,我们查看某一项具体内容时候,里面不仅对于该函数有具体的解释,另外还有代码运行的完整实例更有助于我们的理解。而且该页面上的代码可进行编辑,可以及时试验突然的灵感。而且对于没有C语言环境的朋友也更友好。
输入输出函数 学习编程语言时,每个人的第一个程序应该都是打印一个“Hello World!”吧!C语言中的输入输出依赖的头文件是标准输入输出头文件<stdio.h>,点击后会看到有很多的内置函数,我们只需要找到这个就ok了,可以看到关于printf()函数,就有很多种,这里就不一一举例了,各位感兴趣的话可以自行查询了解。
printf()函数 #include<stdio.h> int printf( const char *restrict format, ... );------------------------------------(C99) restric format: 格式控制字符串 ...:可变参数列表 int:返回值-输出字符数量 格式控制字符串:式控制字符串,包含了两种类型的对象:普通字符和转换说明 。在输出时,普通字符将原样不动地复制到标准输出,转换说明并不直接输出而是用于控制 printf 中参数的转换和打印。每个转换说明都由一个百分号字符(%)开始,以转换说明结束,从而说明输出数据的类型、宽度、精度等
可变参数列表等到函数的那个部分再去研究
printf()函数的返回值,很少会有人关注到printf会有返回值,printf返回的是打印的字符数量。有了这个概念我们可以尝试一下下面的小练习来进一步理解它的返回内容。
使用printf()函数表示,求解一个数字n的十进制表示的数字位数
scanf()函数 #include<stdio.h> int scanf( const char *restrict format, ... );------------------------------------(C99) restric format: 格式控制字符串 ...:可变参数列表 int:返回值-成功读入的参数个数 scanf()的返回值是成功读入的参数个数,通俗的解释就是,你赋值变量的个数。那么正常情况下,返回值是大于0的,如果出现返回0的情况,就是输入变量格式错误。看下面的示例,我们定义的变量n是整型的,输入数字时,会被正常接收,然后scanf则返回1。但当输入字符的时候,与变量定义类型不符,所以未被接收,则返回0.
scanf循环读入
在C语言中的<stdio.h>中定义了一个宏常量EOF(end of file)文件结束符。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。
那么从逻辑上来讲,如果scanf的返回值不等于EOF,那么就意味着后面依旧有可读入的内容,那么我们可以基于这个逻辑来写一个循环读入
在上述测试案例中可以看到,已经成功实现了循环读入的功能,但是还可以进一步思考和优化一个小问题,尽管上面输入的是整型,如果是输入字符串的话,可不可以输入带空格的字符串?
在这里呢可以使用正则表达式来解决,在scanf中是默认将空格、换行符、制表符等作为终止符的,所以在读入时遇见以上符号,会默认结束读入,那么我们可以通过字符匹配集来解决,只让换行符作为终止符。
可以看下面案例,已经成功把空格读入并输出了,但是出现了一个问题,就是程序陷入死循环了。
从运行结果上可以看到,在后面的过程中,scanf并没有读到任何参数。
scanf读入数据的形式是以字符流的形式读入的,当我们输入之后按下回车,实际上在缓冲区的字符是这样子的
sadasd asdas asdas \n 在换行符之前的内容被读入,然后遇到换行符停止读入,然后进行输入,当我们的循环第二次循行到这里的时候,会发现换行符留在了缓冲区里,会第一个读入,从而导致直接停止读入,使得程序陷入死循环。这时候我们需要在循环中加入一个getchar()来吸收缓冲区里的换行符。
一、Tensor概念 什么是张量? 张量是一个多维数组,它是标量、向量、矩阵的高维拓展
Tensor与Variable Variable是torch.autograd中的数据类型,主要用于封装Tensor,进行自动求导。
data: 被包装的Tensorgrad: data的梯度(梦回数一)grad_fn: 创建Tensor的Function,是自动求导的关键requires_grad: 指示是否需要梯度is_leaf: 指示是否是叶子节点(张量) Tensor PyTorch 0.4.0版本开始,Variable已并入Tensor。
dtype: 张量的数据类型,例如torch.FloatTensor, torch.cuda.FloatTensorshape: 张量的形状,例如 (64, 3, 224, 224)device: 张量所在设备,GPU/CPU,是加速的关键
二、 Create Tensor 1、直接创建 torch.tensor( data, dtype=None, device=None, requires_grad=False, pin_memory=False ) 功能:从data创建tensor
• data: 数据, 可以是list, numpy
• dtype : 数据类型,默认与data的一致
• device : 所在设备, cuda/cpu
• requires_grad:是否需要梯度
• pin_memory:是否存于锁页内存
torch.from_numpy(ndarray) 功能:从numpy创建tensor。 注意事项:从torch.from_numpy创建的 tensor 与原始 ndarray 共享内存。 当修改其中一个的数据时,另一个也会被改动。 2、依据数值创建 torch.zeros( *size, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False ) 功能:依照size创建全0张量
一、教程描述
本套驾驶教程,大小3.15G,共有274个文件。
二、教程目录
01-汽车驾驶的理论知识(共95课时)
02-汽车驾驶的场地练习(共87课时)
03-汽车驾驶的道路练习(共55课时)
04-驾考通关秘籍的动画(共10课时)
05-汽车驾驶的学车视频(24个视频)
06-汽车驾驶的相关文件(3个文件)
三、教程下载
A. DS静态查找之顺序查找 题目描述 给出一个队列和要查找的数值,找出数值在队列中的位置,队列位置从1开始
要求使用带哨兵的顺序查找算法
输入 第一行输入n,表示队列有n个数据
第二行输入n个数据,都是正整数,用空格隔开
第三行输入t,表示有t个要查找的数值
第四行起,输入t个数值,输入t行
输出 每行输出一个要查找的数值在队列的位置,如果查找不成功,输出字符串error
样例查看模式 正常显示查看格式
输入样例1 8\n
33 66 22 88 11 27 44 55\n
3\n
22\n
11\n
99\n
输出样例1 3\n
5\n
error\n
AC代码 #include<bits/stdc++.h> using namespace std; int main() { int n; cin>>n; vector<int>v(n+1); for(int i=1;i<=n;i++) { cin>>v[i]; } int m; cin>>m; while(m--) { int x; cin>>x; int k=n; while(k) { if(v[k]==x) { break; } k--; } if(k) { cout<<k<<endl; } else { cout<<"
有基础,进阶用,个人查漏补缺
第十五章的内容之前学过,跳过
预处理之前,编译器必须对该程序进行一些翻译处理
首先把源代码中出现的字符映射到原字符集
其次编译器定位每个反斜杠后面跟着换行符的实例,并删除它们(把由于写代码时,一行太长,会用反斜杠\把一行逻辑行变成两个物理行)
然后编译器把文本划分为预处理记号序列、空白序列和注释序列。此处需要注意的是,编译器将用一个空格字符替换每一条注释,如
int/* 注释*/fox; //将变成 int fox;//中间的注释变成了一个空格 C预处理器在程序执行之前查看程序,故称之为预处理器。根据程序中的预处理器指令,预处理器把符号缩写替换成其表达的内容。
明示常量:#define
指令从#开始运行,到第1个换行符结束,针对的是一个逻辑行(可以用\进行物理换行)
类对象宏定义的组成:宏的名称中不允许有空格,需要遵循C变量的命名规则
#define PX printf("x is %d\n", x) //预处理指令 宏 替换体 预处理器不做计算,不对表达式求值,只进行替换
记号:可以把宏的替换体看作是记号(token)型字符串
#define FOUR 2*2 //有一个记号2*2,但对于C编译器来说是3个记号 #define six 2 * 3 //有三个记号2、*、3,额外的空格也是替换体的一部分 重定义常量:假设先把LIMIT定义为20,稍后在该文件中又把它定义为25。
//ANSI标准在新定义和旧定义完全相同时才允许重定义 #define six 2 * 3 #define six 2 * 3 在#define中使用参数,即类函数宏:
为保证运算顺序,要多使用圆括号
#define SQUARE(X) X*X #define SQUARE1(X) (X*X) #define SQUARE2(X) (X)*(X) int x = 5; z = SQUARE(x);//z=25 z = SQUARE(x+2);//z= x+2*x+2 = 5+2*5+2 = 17 z = 100 / SQUARE(2);//z = 100/2*2 = 100/2*2 = 100 z = SQUARE1(2);//z = 100 / (2*2) = 25 z = SQUARE2(x+2);//z = (x+2)*(x+2) 避免使用++x等这种递增或者递减
引言 在项目开发中,从媒体库中选择图片或使用相机拍摄图片是一个极为普遍的需求。通常,我们使用UIImagePickerController来实现单张图片选择或启动相机拍照。整个拍照过程由UIImagePickerController内部实现,无需我们关心细节,只需实现相应的回调以获取所需的图片。
然而,你或许好奇拍照的底层实现是什么样的,是否能够自己调用手机摄像头完成拍照功能?这正是AVFoundation发挥作用的地方。AVFoundation是一个强大的框架,提供了访问音视频的底层功能,包括相机和麦克风。通过AVFoundation,我们能够直接与设备的摄像头进行交互,实现自定义的拍照功能,为我们提供更大的灵活性和控制权。
在接下来的内容中,我们将深入探讨AVFoundation的拍照功能,了解如何通过这一框架自定义拍照过程,从而更好地满足项目的需求。
介绍 媒体捕捉主要类 首先介绍一下主要类:
AVCaptureDevice:捕捉设备。相对手机而言,它是摄像头,麦克风等物理设备定义了一个接口。
AVCaptureDeviceInput:捕捉设备的输入。捕捉设备不能直接添加到会话中,需要封装在AVCaptureDeviceInput中再进行添加。
AVCaptureSession:捕捉会话。捕获会话是整个功能的核心,有用链接输入和输出,配置捕捉环境。
AVCaptureOutput:捕捉的输出。AVCaptureOutput是一个抽象类,用于捕捉到的数据进行输出,不能直接使用,通常我们是使用它的子类比如AVCapturePhotoOutput,AVCaptureMovieFileOutput等等。
另外还有一个比较重要的类AVCaptureVideoPreviewLayer它提供了画面的预览功能。
基本使用 这里面演示一下我们使用的最小单元,也就是一个拍照功能的最核心代码:
创建会话 AVCaptureSession * session = [[AVCaptureSession alloc] init]; 创建捕捉及输入并添加到会话 AVCaptureDevice * cameraDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; NSError * error; AVCaptureDeviceInput * cameraInput = [AVCaptureDeviceInput deviceInputWithDevice:cameraDevice error:&error]; if ([session canAddInput:cameraInput]) { [session addInput:cameraInput]; } 创建输出并添加到会话 AVCapturePhotoOutput * photoOutput = [[AVCapturePhotoOutput alloc] init]; if ([session canAddOutput:photoOutput]) { [session addOutput:photoOutput]; } 上面的代码创建了一个拍摄图片最基础的框架。创建会话,将设备捕捉到的数据添加到会话,再将数据进行输出静态图片。启动会话,视频数据流就可以开始传输了。真正使用起来会比上面的示例代码复杂一点,但核心内容仍然是这几个步骤。
完整示例 这一部分内容比较多,为了更容易理解,我们将对应的功能分散到不同的类中。
PHCameraController:捕捉核心类。负责启动会话处理输入和输出。
PHPreviewView:预览图层。负责渲染预览画面。
而我们首先把注意力集中在PHCameraController上面。
捕捉核心类 配置会话 我们先来定义一个最小的功能,只声明一些拍照所需要的属性及方法。.
7-1 学生成绩录入及查询
分数 26
全屏浏览题目
切换布局
作者 zym
单位 广东外语外贸大学
学生成绩表中,一名学生的信息包含如下信息:
学号(11位)、姓名、数学成绩、英语成绩、程序设计成绩、物理成绩。
本题要求编写程序,录入N条学生的信息,并且按查询要求显示学生成绩等信息。
输入格式:
输入在第一行给出正整数N(N<=10);随后N行,每行按格式:
学号 姓名 数学成绩 英语成绩 程序设计成绩 物理成绩 给出一名学生的信息。
其中学号是11位数字;姓名是不超过10个字符、不包含空格的非空字符串;成绩是<=100的非负整数;
在学生信息输入完成后,给出要查询的姓名。
输出格式:
对查询的姓名的每一名学生,在一行中按照如下格式输出:
学号 姓名 数学成绩 英语成绩 程序设计成绩 物理成绩 如果有相同姓名的同学,输出全部同学的信息,每名同学一行;
如果要查询的学生不存在,则输出:
Not Found! 输入样例:
在这里给出一组输入。例如:
4 20201003012 LiWen 68 90 78 86 20201003012 HeHua 91 88 80 82 20201002121 WangFang 78 78 82 90 20201002112 ZhengYi 56 83 77 80 ZhengYi 输出样例:
在这里给出相应的输出。例如:
20201002112 ZhengYi 56 83 77 80 代码长度限制
AirServer 7 .27 for Mac中文免费激活版是一款Mac专用投屏工具,能够通过本地网络将音频、照片、视频以及支持AirPlay功能的第三方App,从 iOS 设备无线传送到 Mac 电脑的屏幕上,把Mac变成一个AirPlay终端的实用工具。
目前最新的AirServer 7.2.7版本,支持 macOS High Sierra 和 iOS 11,通过AirServer,可以解决iPhone或iPad的屏幕录像问题,将iPhone变为游戏手柄等,支持视频和声音的同步显示、HDTV高清、密码保护等功能,功能十分强大!AIrServer是一款Mac应用程序,可将AIrPlay / AIrTunes的音频,视频,照片,幻灯片和镜像接收功能添加到Mac。AIrserver 7 mac版可以实现将手机上的媒体文件以及其他操作投射到电脑上进行操作。使用AIrServer,您现在可以从Mac,iOS,PC,Chromebook或Android设备上运行的任何AIrPlay兼容应用程序接收音频,视频,照片或幻灯片。而且使用非常的方便,只要您通过同一网络连接便可,相信很多用户都能用上!
什么是 AirServer? AirServer 是适用于 Mac 和 PC 的先进的屏幕镜像接收器。 它允许您接收 AirPlay 和 Google Cast 流,类似于 Apple TV 或 Chromecast 设备。AirServer 可以将一个简单的大屏幕或投影仪变成一个通用的屏幕镜像接收器 ,是一款十分强大的投屏软件
AirServer 7 .27 for Mac中文免费激活版软件特色 1、支持 Windows、 Mac (部分苹果用户)、 Android和 iOS。
其中, Windows平台提供了更加便捷的网络使用体验,非常适合家庭和办公室场景。当然!它同样还能为 iPad、 Mac电脑上的多媒体视频提供无缝体验:支持多台设备同时连接电脑进行同步处理!比如一个苹果电脑连接到电脑,另一个苹果电脑连接到电脑上!这样你就可以随时随地把一台 iPhone、 iPad上的音乐视频、文档图片等文件通过网络轻松同步到另一个 iPhone、 iPad上了!
2、可以通过多个设备连接同一个局域网,快速查看同一局域网内的视频内容。
AirServer-AirServer下载页:https://souurl.cn/vXBtOh AirServer 激活码: 22SOYGT-FRDESW-DEFRGT-SLSiJUK
AirServer 7是一个开源的 macOS,而它就是这么一个让你可以通过多个设备进行投屏,并且可以快速获得你想要的视频内容。你只需要在你的电脑上连接一个 WiFi就可以轻松进行投屏,而且你还可以通过各种方法将这些数据进行备份,保证不会出现网络拥塞或者突然中断。第一步:选择网络上的你喜欢的一个设备连接到电脑上,然后开始自动搜索连接上电脑上的每个视频设备。第二步:搜索出来你想要发送给多个视频媒体,并将它们进行连接后直接播放。第三步:播放到你需要的视频内容后你可以选择是否停止或者切换到下一台设备继续观看。第四步:播放到你想要视频媒体后你就可以点击鼠标右键单击它让它播放视频媒体功能会自动打开,这时候就会显示视频内容了。第五步:播放视频后点击播放按钮就可以看到你想要视频的播放路径了。
目录
往期精彩内容:
前言
1 快速傅里叶变换FFT原理介绍
2 轴承故障数据的预处理
2.1 导入数据
2.2 制作数据集和对应标签
3 基于FFT+CNN-Transformer的轴承故障识别模型
3.1 网络定义模型
3.2 设置参数,训练模型
3.3 模型评估
往期精彩内容: Python-凯斯西储大学(CWRU)轴承数据解读与分类处理_cwru数据集时域图-CSDN博客
Python轴承故障诊断 (一)短时傅里叶变换STFT
Python轴承故障诊断 (二)连续小波变换CWT
Python轴承故障诊断 (三)经验模态分解EMD_轴承诊断 pytorch-CSDN博客
Pytorch-LSTM轴承故障一维信号分类(一)_cwru数据集pytorch训练-CSDN博客
Pytorch-CNN轴承故障一维信号分类(二)-CSDN博客
Pytorch-Transformer轴承故障一维信号分类(三)-CSDN博客
Python轴承故障诊断 (四)基于EMD-CNN的故障分类-CSDN博客
Python轴承故障诊断 (五)基于EMD-LSTM的故障分类-CSDN博客
Python轴承故障诊断 (六)基于EMD-Transformer的故障分类-CSDN博客
Python轴承故障诊断 (七)基于EMD-CNN-LSTM的故障分类-CSDN博客
Python轴承故障诊断 (八)基于EMD-CNN-GRU并行模型的故障分类-CSDN博客
基于FFT + CNN - BiGRU-Attention 时域、频域特征注意力融合的轴承故障识别模型-CSDN博客
前言 本文基于凯斯西储大学(CWRU)轴承数据,进行快速傅里叶变换(FFT)的介绍与数据预处理,最后通过Python实现基于FFT的CNN-Transformer模型对故障数据的分类。凯斯西储大学轴承数据的详细介绍可以参考下文: Python-凯斯西储大学(CWRU)轴承数据解读与分类处理_cwru数据集时域图-CSDN博客
模型整体结构
模型整体结构如下所示,一维故障信号经过FFT变换的频域特征以及信号本身的时域特征分别经过CNN卷积池化操作,提取全局特征,然后再经过Transformer提取时序特征,再进行特征增强融合,最后经过全连接层和softmax输出分类结果。
1 快速傅里叶变换FFT原理介绍 傅里叶变换是一种信号处理和频谱分析的工具,用于将一个信号从时间域转换到频率域。而快速傅里叶变换(FFT)是一种高效实现傅里叶变换的算法,特别适用于离散信号的处理。
第一步,导入部分数据
fromscipy.ioimportloadmat import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rc("font", family='Microsoft YaHei') # 读取MAT文件 data1 = loadmat('0_0.
LDA:LDA最大化类间距离,最小化类内距离,使得投影后的不同类别的样本分的更开,属于监督学习。
PCA:PCA最小重构误差,使得投影后的值和原来的值尽量接近,属于非监督学习。
SVM:最大间隔的优化模型
CART算法
ID3算法
GINI算法
C4.5算法
Novikoff定理:
模糊C均值算法:
J ( U , V ) = ∑ i = 1 n ∑ j = 1 k u i j m d i j 2 ∑ j = 1 k u i j = 1 , u i j ∈ [ 0 , 1 ] J(U,V) = \sum_{i=1} ^{n}\sum_{j=1} ^{k} u_{ij} ^ m d _{ij} ^2\\ \sum_{j=1}^{k}u_{ij} = 1,u_{ij} \in [0,1] J(U,V)=i=1∑nj=1∑kuijmdij2j=1∑kuij=1,uij∈[0,1]
勤学如春起之苗,不见其增,日有所长 。辍学如磨刀之石,不见其损,日有所亏。
在写上一篇 2023年前端学习路线 的时候,时间还在2023年初停留,而如今不知不觉时间已经悄然来到了2024年,回顾往昔岁月,常顾于迷失在琐碎的事物中,虚度光阴,令人深感悔恨和羞愧。
羞愧,正是因为对自己的浪费与失误感到惋惜和后悔。虚度岁月,正是因为我们没有珍惜时间的来之不易。然而,我们不能只是沉浸在悔恨和羞愧之中。时间虽然不可逆转,但我们可以通过珍惜现在和未来,来弥补过去的不足。只要我们能够把握当下的每一个瞬间,让每一秒都有意义,那么未来必然会更加美好。
“青山不改,绿水长流”,岁月不停地流逝,但我们仍需保持学习的虔诚的和坚定。让我们共同珍惜时间,奋斗向前,创造出更加辉煌的明天!
目录
巩固与拓展
掌握与应用 趋势与方向
挑战与发展
总结与展望
巩固与拓展 回顾过去的一年,前端技术在不断演进和发展的同时,也带来了许多挑战和机遇。作为前端开发者,我们有责任与时俱进,不断巩固基础知识的同时拓展新的技能和领域。因此,今天我将为您呈现一篇关于2024年前端学习路线的文章,开篇就在巩固与拓展这个方面:
首先介绍一下什么是前端开发,前端开发就是设计网站或应用程序的外观,关注的是你所看到的事物并与你产生互动,确保它是易于使用并且能够在任何设备上产生良好的兼容,简单来讲就是前端开发人员将设计变成人们可以使用的实时网站和应用程序。
将幻想变为显示的就是通过 HTML+CSS 来进行实现,以下是学习路线的重要规划,再结合去年总结的学习路线以及博主专栏:HTML+CSS ,巩固前端基础知识并将其应用于实际项目中:
在掌握基本的web前端的HTML+CSS基础知识之后,想要进一部拓展可以进行在移动端上深耕:
HTML+CSS可以多在网上找找实战项目巩固自己的基础,实战经验可以让自己更加游刃有余的处理今后遇到的各种问题。在掌握HTML+CSS的前提下,接下来最重点学习JavaScript语言了, 以下是学习路线的重要规划,再结合去年总结的学习路线以及博主专栏:JavaScript ,巩固前端基础知识并将其应用于实际项目中:
在掌握JavaScript的前提下如果想继续深耕JS语言的话,也可以继续学习Node.js这门轻量级后端语言,以下是学习路线的重要规划,再结合去年总结的学习路线以及博主专栏:node ,巩固前端基础知识并将其应用于实际项目中:
掌握与应用 在当今快速发展的前端领域,掌握和应用前端框架已经成为了提高开发效率和代码质量的关键。前端框架不仅能够简化我们的开发流程,还能帮助我们构建出更加灵活、可维护和可扩展的应用程序。因此,今天我将为您带来一篇关于2024年前端学习路线的文章,重点放在掌握与应用这个方面:
前端框架如React、Vue等,已经成为现代化前端开发的重要工具。通过学习和应用这些框架,我们可以极大地简化开发流程,提高代码的可读性和可维护性,减少重复劳动并增加开发效率。同时,框架也为我们提供了丰富的组件和功能库,使得我们能够更加轻松地构建出强大而灵活的应用程序,以下是学习路线的重要规划,再结合去年总结的学习路线以及博主专栏:Vue ,React 当然如果想在seo方面下功夫的话,也可以参考我之前的专栏:Nuxt.js 巩固前端基础知识并将其应用于实际项目中:
如果想在前端框架这一方面下功夫,在掌握web端的前提之下,也可以学习以下移动端方面的内容, 以下是学习路线的重要规划,再结合去年总结的学习路线以及博主专栏:小程序 巩固前端基础知识并将其应用于实际项目中:
趋势与方向 在物联网时代,是人与物、物与物连接、随着物联网的发展,这时候越来越多的Web应用有了3D可视化的需求,所以学习WebGL、three.js等对前端开发者今后的发展也是不错的方向,下面的对three.js的简单介绍,详细了解可以参考我的专栏:three
学前基础:在学习WebGL和Three.js之前,首先确保你有web前端基础,最差也要掌握HTML、CSS和JavaScript、对node.js也要有一定的了解,主要是搭建开放环境也离不开nodejs,如果你没有相关基础请提前进行学习。
如何学习three.js:有没有原生WebGL基础,你都可以直接学习Three.js,刚刚入门three.js时候,可以先不用学习WebGL,当你需要进阶深入学习three.js的时候,最好先去学学原生WebGL,了解了解图形学相关理论知识,即便只是稍微入门WebGL,那么对于three.js深入学习帮助都是很大的
3D建模学习:有些WebGL可视化项目,可能需要通过3D建模软件绘制模型,一般可以通过3dmax、c4d、Blender等软件实现。对于3D建模,一般工作都是由美术负责,然后美术把绘制好的模型,导出给程序员使用。对于程序员而言,3D建模并不是必须要掌握的,不过稍微了解一点建模知识,对于学习和开发还是很有帮助的。关于3D建模,我的建议是:只要了解一些导入导出的知识即可,具体的建模过程可学可不学,当然如果你时间很充足的话,也可以选择一款3D建模软件进行学习。
了解Cesium:Cesium也是一款WebGL的3D引擎,相比three.js封装更进一步,主要是给GIS行业使用,并不像three.js那么通用,如果你不是GIS专业方向,可以不用学习,如果你是GIS方向,可以同时学习WebGL、Three.js和Cesium。
以下是WebGL前端工程师相关待遇案例:
在2023年华为秋季发布会上,HarmonyOS Next开发预览版正式亮相,未来鸿蒙将彻底摆脱安卓,开启鸿蒙原生应用开发的新时代,这也意味着无论是硬件还是软件上,华为都已经摆脱了其他国家的技术风格,走出自己的道路。可以预见鸿蒙系统在未来将会成为最主流的全终端操作系统。 详细了解可以参考我的专栏:HarmonyOS(鸿蒙开发)
学习鸿蒙开发是跟随技术潮流的必然选择。随着智能终端的普及和技术的不断进步,鸿蒙操作系统将成为未来智能时代的重要趋势。学习鸿蒙开发将使我们站在技术的前沿,紧跟时代的步伐,为自己的职业发展打下坚实的基础。
以下是HarmonyOS(鸿蒙开发)工程师相关待遇案例:
挑战与发展 相信大家也发现了,近几年大环境不是太好,对开发来讲相比于以前的压力是越来越大了,随着大模型的发展,许多AI工具横空出世,好多人都说前端已凉!劝退了不是人,对于还在坚持的人我想说,罗马不是一天建成的,只有沉下心来一点点扎实的学习,才可能到达自己想去的地方,有些人收藏夹里的学习文章以及视频,甚至是购买的书籍都快堆成山了,也没有见他空余时间多看一眼。
优秀的前端工程师之所以优秀,不是因为工作的年限有多长,而是具备快速学习的能力,前端开发涵盖的知识面非常广,技术迭代速度非常快,盲目的学习而没有一个完整的学习路线是不行的。
在学有余力的情况下涉及一下后端,提高自己的核心竞争力才能在大洪流中屹立不倒,我也希望在2024年这一年的时间力,能够多涉及 Java开发 期待和大家一起互相监督相互学习。
总结与展望 最后让我们来总结一下去年前端学习方面的经验和不足。在去年,我通过阅读书籍、参加课程、完成项目等方式不断深入学习前端技术,掌握了HTML、CSS、JavaScript等基础技能,并且学习了Vue、React等流行的前端框架。我意识到,持续不断地学习是非常重要的,只有不断学习才能跟上技术的发展。同时,我还参与了一些实际项目的开发工作,这让我更好地理解了前端技术在实际应用中的价值和意义。当然去年取得了一个实习的机会,得到了不少的锻炼,大家学习的最终目的也是为了得到一份工作,早早去实习是一个明智的选择!
在去年虽然我取得了一些进步,但我也发现了自己的不足之处。比如,在项目开发中,我发现自己的代码可读性不够好,注释不够充分,这给团队合作带来了一些困难。另外,我也发现自己在一些细节问题上需要更加注重,比如在一些浏览器兼容性方面的处理,以及代码的优化和性能调整等。 接下来,让我们来谈一谈今年的前端学习目标和展望。在新的一年里,我计划继续深入学习前端技术,包括掌握更多的前端框架和工具,提升自己的代码质量和开发效率,并且在实际项目中应用所学知识。我也计划参与一些开源项目,积累更多的经验和技能。
此外,我还计划深入学习前端与后端的交互与合作,学习一些后端开发的基础知识,提高自己的全栈开发能力。同时,我还计划学习一些设计相关的知识,提高自己的UI设计和用户体验能力,为用户提供更好的产品体验。
总而言之,去年的前端学习让我获得了一些经验和技能,但也发现了自己的不足之处。在新的一年里,我将继续努力,学习更多的技术知识,改善自己的不足,提高自己的专业能力和素质水平。让我们一起迎接新的挑战和机遇,为更好的明天而努力奋斗吧! 相约2025年再见!
“我干了件从来没有人干过的事情。”在写完《计算》后,吴翰清如是说。
《计算》终于出版了
计算,为了可计算的价值
撰文 | 吴翰清
三年前在新冠疫情大爆发期间,当我决心动笔写下第一行文字时,从来没想到过写作《计算》的工程会如此之大。
它横跨了人类文明三千年的数学史和计算机科学史,从数字的起源一直讲到了今天的ChatGPT。
写到一半时我突然发现,市面上能找到的书,如果不是枯燥的工具书和理论书,就是讲数学史的,一般从古希腊讲到了20世纪初的现代数学,要么就是讲计算机历史的,往往从图灵开始讲到今天的互联网和人工智能。
但是几乎找不到一本书涵盖了两个领域,跨越了完整的时间线,用讲人话的方式深入浅出地从数学的本源开始一直讲到今天最前沿的计算机技术。
而《计算》做到了。
也因此,《计算》有了一个史诗般气势恢弘的开头:
“1936年5月28日,在阿兰·麦席森·图灵决定发表论文《论可计算数及其在判定性问题中的应用》的那个下午,他正焦虑于普林斯顿的丘奇已抢先发表了对这个著名希尔伯特问题的证明。此刻距离毕达哥拉斯学派的希帕索斯被投入大海已过去2500多年,而AlphaGo还要等到80年后才能击败李世石,真正把人类的傲慢踩在脚下。”
爱好文学的读者们应该有一种熟悉的感觉,没错,这里模仿了加西亚·马尔克斯的《百年孤独》的开头,在一段话中,嵌入了过去、现在、未来三个时间片段,蕴含了极其丰富的信息。
自然,《计算》的结尾也是不平凡的,留待读者们自己探索。
这本书不仅仅是写给理工科生或者程序员看的,也是写给所有人看的。原因在于我认为“计算技术”是人类文明三千年来的智慧结晶,它深刻地影响着我们这个时代,与每个人的生活息息相关,因此对计算这一概念的正确解释、澄清和发展就成为一种必要。
在我写作到一半时,我再次发现,这件事情依然没有人好好做过。所以就由《计算》来做吧。
于是就有了封底的三句话:
这就是我写作《计算》的初心。
相应地,为了保持版面和内容整洁,我没有请任何人写推荐语、写序言。
因为我清楚读者们在市面上看到的大多数书,在封底为其写推荐语的人多半自己都没有读过该书。
我认为这对读者是不负责任的,因此我不希望《计算》遭此狗皮膏药的厄运。
难得的是,我的编辑,博文视点的张春雨先生也愿意陪着我胡闹一把,冒着损失销量的风险,没有在书的封面和封底贴任何的狗皮膏药。
同理,我也没有请人写序,因此本文就权当代序吧。
如果本书再版时需要有人写推荐语,我认为也应当留给真正读完了此书的普通读者们,而不是找一些有帽子的专家。世人服从权威多过服从真理,我辈读书人当拨乱反正之。
至于任性到连内容简介都没有附在封底,则纯属我的骄傲了。因此如果当你在书店里拿起此书,却丈二和尚摸不着头脑时,你一定就已经深深地感受到作者我的骄傲了吧!
《计算》洋洋洒洒四百多页,却只是我想表达的三分之一。我决定通过回答三个问题,来阐述我的计算主义世界观:
1. 计算的原理是什么?
2. 计算的技术该如何实现?
3. 计算会对世界产生什么影响?
《计算》写完,只回答了第一个问题。
因此本书也可以看作是《计算》三部曲的奠基之作。
有生之年,我会回答清楚这三个问题。
但反过来说,我狡猾的地方在于,若有任何人想在计算的问题上与我进行辩论,则请先通读这四百页的著作,我们才有辩论的必要,否则这个人要么是傲慢的,要么是无知的。
我的思想都已经公开摆在这里了,不藏私,请君自取!
在写作《计算》的过程中,我买遍了几乎我能找到的所有计算机书,其中不乏国内外顶尖专家、学者的作品。
一方面我从中受益良多,另一方面,居然让我看清楚了这些大神们的思想脉络和水位。
就像我在攀登一座山峰,我清晰地看到他们都处于山峰上的什么位置,不再遥不可及,他们有的高,有的低,有的也不过如此。这是一种很神奇的感受。写完《计算》后,我认为,《计算》这座山峰应该也足够后人们攀登好一阵子了。
至少写完《计算》后,我终于明白了什么是数学,计算机将发展去何方。
说来惭愧,学了这么多年数学,到年近不惑才入了数学的大门。要是能穿越回去,让还在读中学的我读读《计算》,可能我会少走二十年的弯路。
但普通读者们大可不必对本书望而生畏,虽然本书中有不少数学思想,但几乎没有公式和枯燥的证明过程,所引入的有限公式,也只是因为我觉得它们特别地“美”。
正如前所说,这是一本写给每个人看的书。
本书的正确打开方式为随时随地,随手翻开一页,沉浸享受。
当然,本书也值得你通读十遍,相信每一遍会有不同的收获。作为读者的我,在阅读身为作者的我写出来的《计算》时,也同样如是。
而我自己最大的收获,则在于过往模糊的概念变得清晰,过往未知的问题有了答案,即对计算边界的终极探索。
从数学、物理学、计算机科学和哲学出发,在写作到第三年时,我终于找到了自己的答案,这种求知欲的满足让我欣喜若狂,忍不住分享出来。
我本人也因此成为了一个彻彻底底的计算主义者,进而以计算的世界观解释万事万物,洞若观火。
说起对计算的启蒙,我要感谢阿里云的创始人王坚博士,是他每天把计算挂在嘴边,以及工作中对我的不断鞭策,让我理解了什么是计算,什么是计算机,最终才有今天我把计算变成了自己的信仰。
如果没有我在阿里云的工作经历,《计算》一书是无法写作出来的,而我独特的工程师视角则为我解读“计算”提供了诸多帮助,这应当也是本书特殊的地方。
《计算》写作于阿里云,待到《计算》出版之际,却已不在阿里云,《计算》与阿里云从此只有渊源,再无瓜葛,想来这是阿里云的遗憾了。
计算,为了可计算的价值!
——道哥(吴翰清)
向上滑动阅览
↑限时五折优惠↑
限时五折优惠,快快抢购吧!
PaperWeekly携手博文视点送书啦! 在本文评论区留言+点赞 我们将随机抽取10位读者 包邮送出这本计算理论重磅新书 活动截止时间为1月8日 12:00届时请留意后台消息 🔍 现在,在「知乎」也能找到我们了进入知乎首页搜索「PaperWeekly」点击「关注」订阅我们的专栏吧 ······
开放路径最短优先协议OSPF基础 对比RIP 对比距离矢量路由协议(RIP),OSPF协议交换的不是路由条目,而是链路信息,并通过SPF算法计算出最佳路由,链路状态信息内含有路由接口、IP地址、掩码、cost值等,进而形成了链路状态通告(LSA)。
基本术语 邻居表:也成为邻接数据库,通过Hello包建立邻居关系,包含自己所承认的邻居名单。链路状态数据库(LSDB):OSPF学来的LSA存放处,同一个区域的LSDB一样路由表:使用SPF算法,算出以自己为根,到达目的地最短、最佳无环路径,形成路由表。通常称为转发数据库,达到目的的最佳路径列表。区域边界路由器(ABR):位于不同区域边界上的路由器自治系统边界路由器(ASBR):它连接一个OSPF域与其他路由协议域(比如BGP),简单来说就是沟通OSPF与其他协议的桥梁 OSPF区域 OSPF虽然不受路由器数量限制,但是网络中路由器太多,相互交换的LSA也会增加,随之而来的网络负担也会变大,因此需要给OSPF路由器划分区域。
区域主要分为两种:
骨干区域,又叫传输区域常规区域 常规区域主要限制了这一个区域之间的通信,多个常规区域之间一般是相互隔绝的,如果它们之间进行通信需要经过骨干区域转发。因此常规区域一定与骨干区域相连。
OSPF寻路 OSPF寻找最佳路径采用Dijkstra算法,也叫**最短路径优先(SPF)**算法:
在同一个区域每个路由器都有一个相同额链路状态数据库每台路由器建立由本身为根到目的的树(即然是树,则无环)到特定目的总成本最低的链接放入路由表 一段链路的成本或者说度量的计算如下(默认情况):
C o s t = 1 0 8 b p s B a n d w i t h Cost = \frac{10^8 bps}{Bandwith} Cost=Bandwith108bps
到达目的的链路总成本为每段链路成本之和:
T o t a l C o s t = ∑ i = 1 n C o s t i TotalCost = \sum_{i=1}^{n} Cost_i TotalCost=i=1∑nCosti
此处带宽的单位为bps(比特每秒),其中参考带宽在默认情况下为1E8 bps
这里需要注意,在使用默认值的情况下,我们无法比较百兆带宽和千兆带宽哪个好(本文对于带宽的单位都以比特每秒为基础,例如百兆为100Mbps)。
当带宽为100Mbps的时候,代入公式成本为1;当带宽为1000Mbps的时候成本为0.1,按1算。
可以通过修改参考带宽来区分百兆和前兆网络,在思科路由器上可以采用一下命令:
HIVE 查询语句 1 查询语句语法: SELECT [ALL | DISTINCT] select_expr, select_expr, ... FROM table_reference [WHERE where_condition] [GROUP BY col_list] [ORDER BY col_list] [CLUSTER BY col_list | [DISTRIBUTE BY col_list] [SORT BY col_list] ] [LIMIT number] 1.1 基本查询(Select…From) 1 全表和特定列查询 数据准备
dept:
10 ACCOUNTING 1700 20 RESEARCH 1800 30 SALES 1900 40 OPERATIONS 1700 emp:
7369 SMITH CLERK 7902 1980-12-17 800.00 20 7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300.00 30 7521 WARD SALESMAN 7698 1981-2-22 1250.
1.Linux连接文件 linux有两种文件:符号连接(软连接)与硬连接,符号连接类似Windows下的快捷方式,硬连接通过文件系统的inode连接来产生新文件名,而不是产生新文件。
inode:记录文件属性,一个文件一个inode。inode相当于文件ID,查找文件的时候要先找到inode,然后才能读出文件的内容。
2.ln命令 ln命令用于创建连接文件:
ln[选项] 源文件 目标文件
选项:-s创建符号连接(软连接)
-f强制创建连接文件,如果目标存在,那么先删除掉目标文件,然后再建立连接文件。
3.硬连接 硬连接是多个文件都指向同一个inode,硬连接知识点:
1.具有相同inode的多个文件互为硬连接文件,创建硬连接相当于文件实体多了个入口。
2.对于硬连接文件,只有删除了源文件以及对应的所有硬连接文件,文件实体才会被删除。
3.根据硬连接文件的特点,我们可以通过给文件创建硬连接的方式来防止文件误删除。
4.不论修改源文件还是连接文件,另一个文件的数据都会被改变。
5.硬连接不能跨文件系统。
6.硬连接不能连接到目录。
因为以上这些限制,硬连接其实不常用!靠!
4.符号连接(软连接) 符号连接相当于创建一个独立的文件,这个文件会让数据读取指向它连接的哪个文件的文件名。软连接的特点:
1.可以连接到目录
2.可以跨文件系统
3.删除源文件后,软连接文件也就打不开了
4.符号连接通过->来指示具体的连接文件
LVS(Linux Virtual Server)和F5是两种常见的负载均衡解决方案。 1. LVS(Linux Virtual Server): LVS是基于Linux操作系统的负载均衡软件,它通过网络地址转换(NAT)或直接路由(DR)的方式将请求分发到后端服务器群集。LVS使用IP负载均衡技术,可以根据不同的负载均衡算法(如轮询、加权轮询、源IP哈希等)将请求分发给后端服务器,并支持实现高可用性和故障恢复。
2. F5: F5 Networks是一家专注于负载均衡和应用交付控制的公司,其产品包括硬件负载均衡器和软件定义的应用交付控制器(ADC)。F5提供了一套全面的负载均衡解决方案,支持流量管理、会话保持、应用优化和安全等功能。F5的硬件设备和软件解决方案可根据需要提供高性能、可伸缩性和高可用性的负载均衡服务。
选择LVS或F5负载均衡解决方案应根据具体需求和场景来决定。以下是一些比较方面的考虑:
功能和性能要求:根据您的应用需求和预算,评估所需的负载均衡功能和性能。F5通常提供更多高级功能和性能选项,而LVS是一个开源解决方案,功能相对较为基本。
系统环境和集成:考虑您的系统环境,包括操作系统、网络架构和其他基础设施。LVS是基于Linux系统的软件,而F5提供硬件和软件解决方案,需要考虑与现有环境的集成性和兼容性。
成本:评估预算和成本因素。LVS是开源软件,免费使用,而F5的解决方案通常需要购买相关的硬件和许可证,成本较高。
技术支持和维护:考虑可用的技术支持和维护资源。F5作为商业厂商提供技术支持和维护服务,而LVS依赖于社区支持和开发者社群。
综上所述,根据具体需求和情况,选择适合的负载均衡解决方案。如果您有特定的需求或更详细的场景信息,可以进一步提供,以便提供更具体的建议。
SLB 负载均衡
ELB、SLB
SLB购买
功能清单 游客功能 用户注册、登录登录权限拦截按名称搜索房间支付流程查看订单信息和状态评论预定过的房间,并自动修改订单状态查看统计剩余房间数量,数量为0时不可预定 管理员功能 房间分类管理
类型的删除、修改、查询(准备添加增添功能,即图片上传功能)类型所含属性的增删改查房间分类图片上传 房间管理
房间增删改导印统查询已上传房间的所有照片房间的配套设施属性设置房间价格(原价、活动价)、名称、描述等属性设置房间存量统计 订单管理
订单信息修改、删除订单组合条件查询筛选出超时未评论的订单 高级功能 各种列表清单的导出和打印功能订单组合条件查询
这里使用Springboot 2.7.12版本,Elasticsearch为7.15.0。
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> yaml文件配置:
elasticsearch: uris: http://localhost:9200 构建实体类,这里为商品的SKU属性表
@Data @Document(indexName = "skusearch") public class SkuEs { @Id private String id; @Field(type = FieldType.Text,analyzer = "ik_smart",searchAnalyzer = "ik_smart") private String name; private Integer price; private Integer num; private String image; private String images; private Date createTime; private Date updateTime; private String spuId; private Integer categoryId; //Keyword:不分词 @Field(type= FieldType.Keyword) private String categoryName; private Integer brandId; @Field(type=FieldType.Keyword) private String brandName; @Field(type=FieldType.
方式一,Uvicorn部署 Run a Server Manually - Uvicorn - FastAPI
1,linux服务器安装 python>3.8 2,安装 uvicorn : pip install "uvicorn[standard]" 3,上传项目到服务器 main.py
from typing import Union from fastapi import FastAPI import uvicorn app = FastAPI() ''' 启动命令 uvicorn main:app --reload --port 8000 #导出依赖 pip freeze >requirements.txt api文档地址 http://localhost:8080/docs 参数类型: 请求正文(body)+路径参数({})+查询参数(?&) ''' @app.get("/") async def root(): return {"message": "Hello World"} @app.get("/items/{item_id}") def read_item(item_id: int, q: Union[str, None] = None): return {"item_id": item_id, "q": q} # 第二种启动方式: if __name__ == '__main__': uvicorn.
File: rust/library/alloc/src/vec/mod.rs 在Rust源代码中,rust/library/alloc/src/vec/mod.rs这个文件是Rust标准库中的Vec类型的实现文件。Vec是一个动态大小的数组类型,在内存中以连续的方式存储其元素。
具体来说,mod.rs文件中定义了以下内容:
struct Vec<T>:表示动态数组的类型。它包含了指向存储元素的内存缓冲区的指针、当前有效的元素数目以及分配给缓冲区的容量等信息。 impl<T> Vec<T>: Vec<T>类型的实现方法,包括创建、操作和管理动态数组的函数。例如, push用于在尾部添加元素, pop用于移除尾部的元素, insert用于在指定位置插入元素等。 struct BackshiftOnDrop<'a, T>:表示回溯释放的迭代器。它在 Vec缩减容量时,用于将被释放的元素的生命周期延长至指定的生命周期。 impl<'a, T> BackshiftOnDrop<'a, T>: BackshiftOnDrop<'a, T>类型的实现方法,用于迭代地回溯释放元素,并将其存储在给定的生命周期之后。 struct FillGapOnDrop<'a, T>:表示填充释放的元素的迭代器。它在 Vec缩减容量时,用于将被释放的元素的生命周期填充为指定的生命周期,并在需要时放入默认值。 impl<'a, T> FillGapOnDrop<'a, T>: FillGapOnDrop<'a, T>类型的实现方法,用于迭代地填充释放的元素,并将其存储在给定的生命周期之后。 trait ExtendFromWithinSpec:表示可从内部扩展的特性。这个特性允许扩展一个具有方法的类型,以允许自定义的内存扩展策略。 trait UnpinSlice<T>:表示未固定切片的特性。它用于标记 Vec类型中的切片,使其不会阻止其包含的 Vec实例从 Pin回到其初始位置。 trait DrainFilterIntoIterTrait<T>:表示经过过滤的迭代器的特性。它通过自定义的过滤方法在迭代时处理元素。 以上是 rust/library/alloc/src/vec/mod.rs 文件的主要内容和作用。它是实现Rust标准库中动态数组类型Vec的文件,并提供了相关的结构体和特性来支持Vec的功能和特性。
File: rust/library/alloc/src/ffi/c_str.rs 文件c_str.rs位于Rust源代码的rust/library/alloc/src/ffi/目录下。该文件的作用是实现C字符串(null-terminated string)相关的功能。
在该文件中,有以下几个重要的结构体:
CString: 这个结构体表示一个C字符串。它是一个包含了零字节(null byte)结尾的字节数组。CString提供了一些方法来与C字符串进行相互转换,比如从一个UTF-8字符串创建一个CString,或者将CString转换为一个Rust字符串。它也提供了一些方法来处理C字符串中的内存安全问题,如检查C字符串是否包含有效的null字节结尾。
NulError(usize): 这个结构体表示在将一个字节数组转换为CString时出现的错误。它包含了一个usize类型的字段,表示在字节数组中第一个null字节(\0)之前的字节数。这个结构体用于捕获转换错误,并提供了一些方法来获取错误的信息。
FromVecWithNulError: 这个结构体表示从一个包含null字节结尾的Vec 类型转换为CString时出现的错误。它包含了一个Vec 类型的字段,表示转换失败的字节数组。该结构体提供了一些方法来获取错误的信息。 IntoStringError: 这个结构体表示将一个CString转换为Rust字符串时出现的错误。它包含了一个CString类型的字段,表示转换失败的CString。该结构体提供了一些方法来获取错误的信息。
此外,还有一些trait和enum的定义:
SpecNewImpl: 这是一个trait,提供了一个用于创建C字符串的接口。它的实现类型为CString。
FromBytesWithNulErrorKind: 这是一个enum,表示将一个字节数组转换为CString时可能的错误类型。它包含了以下几个成员:
InteriorNul: 表示字节数组中间存在null字节。 NotNulTerminated: 表示字节数组在末尾缺少null字节。 ContainsNul: 表示字节数组中包含了多个null字节。 这些enum成员用于更详细地描述转换错误的类型。
File: rust/library/alloc/benches/slice.rs 在Rust源代码中,rust/library/alloc/benches/slice.rs文件的作用是对&[T]类型(切片类型)进行性能基准测试。该文件包含了对切片类型的一系列操作的基准测试,例如切片迭代、切片排序、切片的iter和into_iter方法等。
该文件中的基准测试函数使用了Rust的基准测试框架criterion,通过多次运行基准测试并测量时间来评估不同实现方式的性能。这些性能测试对于评估和改进对切片类型的操作的效率至关重要。
在slice.rs文件中,还定义了一些自定义的结构体类型,例如F64x4和f64。这些结构体类型用于在切片类型的基准测试中模拟具体的数据类型,从而更好地反映实际使用中的性能情况。
F64x4是一个结构体类型,代表了由4个f64类型的值组成的向量。这个结构体类型可以用于测试切片类型在处理这种向量数据时的性能表现。
f64是Rust中的浮点数类型,用于表示双精度浮点数。在切片基准测试中,f64类型可以用于作为切片的元素类型,用于模拟对浮点数类型进行操作时的性能情况。
综上所述,rust/library/alloc/benches/slice.rs文件的主要作用是对切片类型进行性能基准测试,并在其中定义了一些自定义的结构体类型用于模拟不同的数据类型。这些基准测试对于评估和改进切片类型的性能非常重要,以确保Rust语言在处理切片类型时能够达到高效的性能水平。
File: rust/library/alloc/benches/string.rs 文件 rust/library/alloc/benches/string.rs 是 Rust 标准库中的一个基准测试文件,用于对字符串(String)类型的性能进行基准测试和性能优化。
首先要了解基准测试是什么。基准测试旨在评估代码的性能和效率,并与其他实现进行比较。在开发过程中,基准测试可以帮助开发人员发现性能瓶颈和潜在的性能优化机会。
这个文件主要有以下作用和功能:
给 String 类型的不同函数进行性能测试:push_str、push、len 等等。这些函数是 String 类型的常用操作,基准测试可以比较它们之间的性能差异。
提供了一些基准测试的标准库函数和宏。这些函数和宏用于执行和验证基准测试的结果,例如 black_box、criterion_group 和 criterion_main 等。
执行基准测试并生成性能报告。基准测试运行时,会记录每个测试的运行时间、内存占用等数据。基准测试框架可以将这些数据整理成性能报告,用于分析和优化测试对象的性能。
基准测试是 Rust 标准库中对性能优化非常重要的一环,并且在每个发布的版本中都会运行以确保性能得到良好的保证。通过基准测试可以找到性能瓶颈,以便进行相应的优化来提高代码的性能和效率。同时,它还可以让开发者对不同的实现进行比较,以选择最佳的方案。
该文件的代码会被cargo bench命令调用,并利用 Rust 内置的基准测试框架 criterion 来执行基准测试。基准测试框架会自动运行和记录多次测试运行的结果,并提供性能报告,其中包括测试运行时间、内存占用、统计数据和图表等。开发者可以根据性能报告来判断和优化代码。
总之,rust/library/alloc/benches/string.rs 文件是 Rust 标准库中用于对字符串类型 String 的性能进行基准测试和优化的文件,通过实际运行测试代码并生成性能报告,帮助开发者发现性能问题并进行相应的优化。
File: rust/library/alloc/benches/vec.rs 在Rust源代码中,rust/library/alloc/benches/vec.rs文件是用于性能基准测试(benchmark)向量(Vector)相关功能的文件。
该文件包含一些由criterion宏定义的基准测试函数。这些基准测试函数在不同场景下评估向量的性能,并提供有关向量操作的性能指标。这是为了确保向量的实现在各种情况下都能够获得良好的性能。
Droppable(usize)是一个自定义的结构体,其目的是在基准测试期间模拟需要释放的资源。它包含一个整数字段以及实现了Drop特性的析构函数。这个结构体主要用于测试在向量中插入或删除元素时,对应元素的资源(如内存)释放情况。
在基准测试的过程中,这个结构体可以被构造、插入到向量中并移除,以模拟真实的资源管理场景,进而评估向量在这种情况下的性能表现。它的目的是验证向量是否正确地管理和释放元素所需的资源。
总结起来,rust/library/alloc/benches/vec.rs文件提供了一套基准测试函数,用于评估Rust标准库中向量的性能。其中Droppable结构体用于模拟需释放资源的元素,并对向量在释放资源方面的表现进行测试。
File: rust/library/alloc/benches/linked_list.rs rust/library/alloc/benches/linked_list.rs是Rust标准库中包含的一个基准测试文件,用于对标准库中的LinkedList数据结构进行性能测试和优化。
LinkedList是一个双向链表数据结构,用于在运行时管理动态分配的内存。由于其灵活性和高效的插入/删除操作,LinkedList在某些情况下可以比其他数据结构(例如数组或向量)更加高效。
linked_list.rs文件中定义了一个包含多个基准测试函数的模块。基准测试的目的是通过模拟实际场景中的工作负载,来度量和比较不同代码实现(尤其是数据结构实现)的性能。这些基准测试函数在输入数据上执行各种操作,并测量它们的执行时间、CPU周期和内存占用等性能指标。
在linked_list.rs中,首先引入了一些必要的模块和依赖项。然后,定义了一系列基准测试函数,每个函数都对LinkedList进行不同类型的操作,并测量其性能。这些基准测试函数可以使用标准库提供的宏(如benchmark_group!和benchmark_main!)来定义和运行基准测试。
基准测试函数的实现通常包括以下步骤:
准备测试数据:创建一个LinkedList实例,并根据测试需求插入合适的元素。 执行测试操作:对LinkedList执行一系列的操作,如插入元素、删除元素、遍历列表等。 测量性能指标:使用标准库提供的计时函数,测量操作的执行时间、CPU周期等性能指标。 输出测试结果:将性能指标打印到控制台,以便进一步分析和比较。 这些基准测试函数的目的是让开发者可以比较不同版本的LinkedList实现之间的性能差异,并帮助Rust开发团队进行性能优化和改进。通过基准测试,开发者可以更好地理解LinkedList的性能特点,以及使用该数据结构时的注意事项和最佳实践。
总之,rust/library/alloc/benches/linked_list.rs文件是Rust标准库中用于基准测试LinkedList性能的文件,它包含了一系列基准测试函数,用于度量不同操作在LinkedList上的执行时间和性能指标,以帮助开发者分析和优化LinkedList的性能。
File: rust/library/alloc/benches/binary_heap.rs 在Rust源代码中,rust/library/alloc/benches/binary_heap.rs文件的作用是实现对二叉堆数据结构(BinaryHeap)的性能基准测试。
二叉堆是一种基于完全二叉树的数据结构,常用于实现优先队列。在binary_heap.rs文件中,通过使用Rust语言的性能测试框架bencher,对BinaryHeap的各种操作进行性能测试。
首先,文件开头包含了对所需库和模块的导入语句。其中,alloc::binary_heap模块是定义BinaryHeap结构的实现代码。
一、什么是Fixture 在测试开展的过程中,会需要考虑到测试前的准备工作,以及测试后的释放操作行为。这些在Pytest中,会通过Fixture的方式来实现。如果说在运行pytest的测试用例的时候,需要调用一些数据来实现测试行为,这些数据可以通过Fixture来生成。Fixture也叫夹具。
二、Fixture的基本应用 2.1单个Fixture的使用 1. Fixture在pytest之中都是基于装饰器的形态来实现的。@pytest.fixture
2. fixture是对函数进行定义的操作。使用fixture非常简单,只需要将fixture当做参数传入函数即可
3. 在pytest中,调用Fixture直接通过函数的名称即可。
4. 一个pytest中可以定义非常多个fixture,来满足到不同的用例的需要。
首先定义一个构造函数,定义一个fixture,返回human对象。调用fixture生成数据内容,可以生成一个man. class Human: #定义一个构造函数 def __init__(self,name): self.name = name #定义一个fixture,返回一个human对象,名字叫做man @pytest.fixture def man(): return Human('man') #调用fixture生成的数据内容 def test_function(man): print(man.name) if __name__ == '__main__': pytest.main(['-s']) 查看结果:
2.2多个Fixture的使用 在unitTest中,一般只有一个前置条件,但是在pytest可以有多个夹具,也就是fixture
class Human: #定义一个构造函数 def __init__(self,name): self.name = name #定义一个fixture,返回一个human对象,名字叫做man @pytest.fixture def man(): return Human('man') @pytest.fixture def woman(): return Human('woman') # 定义一个调用fixture的fixture @pytest.fixture def people(man, woman): return [man, woman] #调用fixture生成的数据内容 def test_function_01(man): print(man.
00. 目录 文章目录 00. 目录01. 输入捕获简介02. 频率测量03. 输入捕获通道04. 主从触发模式05. 输入捕获基本结构06. PWMI基本结构07. 其它08. 附录 01. 输入捕获简介 IC(Input Capture)输入捕获
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
每个高级定时器和通用定时器都拥有4个输入捕获通道
可配置为PWMI模式,同时测量频率和占空比
可配合主从触发模式,实现硬件全自动测量
02. 频率测量 03. 输入捕获通道 04. 主从触发模式 05. 输入捕获基本结构 06. PWMI基本结构 07. 其它 08. 附录 参考: 【STM32】江科大STM32学习笔记汇总
个人主页:Lei宝啊 愿所有美好如期而遇
目录
本题链接
输入描述
输出描述
算法分析
算法一:暴力求解
算法二:前缀和
预处理前缀和dp表
使用前缀和dp表
解题源码
我们以一道题目为例详解一维前缀和原理。 本题链接 【模板】前缀和_牛客题霸_牛客网 输入描述 首先第一行输入两个整数,n和q,n是要输入的数组的元素个数,q是要查询的次数,查询时输入l和r,代表着要查询的数组区间
比如:我们的示例:
n = 3,我们输入的数组元素就有三个:1 2 4q = 2,我们就需要查找两次,l和r也就会更新两次,要查询的数组区间也就是[1,2] [2,3] 值得注意的是n和q都大于等于1,至于为什么要这么给,我们后面讲算法会说到。 输出描述 返回要查询的数组区间内所有元素值的和。
算法分析 算法一:暴力求解 直接遍历数组,从给定区间开始遍历q次,我们分析一下时间复杂度:首先有q次的遍历,并且我们考虑最坏的情况,就是每次数组都是从头遍历到尾,时间复杂度就为O(q*N),按我们本题最大的q和n来看,这么干绝对是超时的。
算法二:前缀和 预处理前缀和dp表 类似于动态规划的dp表,这里的dp表每个元素都表示一个状态,由于我们的n是从1开始的,那我们的dp[1]就用来表示区间[1,1]的和,dp[1]表示区间[1,2]的和,看图更直观些:
我们可以用一个变量sum来表示和,然后通过遍历数组给dp表赋值。 使用前缀和dp表 那么我们如何使用dp表来求取数组区间的元素和呢?
我们dp表第i个位置就表示从下标0到下标i所有元素的和,比如我们要算[2,3]区间,也就是求这个区间的元素和,就是dp[3]-dp[1],我们也就能推知一个公式:
区间和 = dp[r] - dp[l-1];
解题源码 #include <iostream> #include <vector> using namespace std; int main() { int n = 0, q = 0; cin >> n >> q; vector<int> v(n+1,0); for(int i=1; i<v.
使用PageView开发一个带指示器的轮播图组件,当轮播图切换的时候,指示器也会跟着切换,切换到当前轮播图所在的索引时,指示器的背景色会变成蓝色,否则是灰色。使用了一个curIndex变量来记录当前激活的轮播图索引。并使用Stack组件来实现定位布局。
组件代码:
import 'package:flutter/material.dart'; // 轮播图 class Lunbo extends StatefulWidget { const Lunbo({super.key}); @override State<Lunbo> createState() => _LunboState(); } class _LunboState extends State<Lunbo> { // 定义轮播图列表 List<Widget> imgList = []; // 记录一下当前图片的索引,激活指示器背景色 var curIndex = 0; void handle = (int cur) { print("handle函数"); }; @override void initState() { // TODO: implement initState var imgUrls = [ "https://img-blog.csdnimg.cn/img_convert/b723ea01d277dac4926a936f9b40862c.jpeg", "https://img-blog.csdnimg.cn/img_convert/d794e0b76460ea037fc707b01bb1d703.jpeg", "https://img-blog.csdnimg.cn/img_convert/f90cd009d24e58857a135cfcd44fe993.jpeg" ]; // 图片列表初始化 for (int i = 0; i < imgUrls.
文章目录 Spring Boot 中自动装配机制的原理 Spring Boot 中自动装配机制的原理 自动装配,简单来说就是自动把第三方组件的 Bean 装载到 Spring IOC 器里面, 不需要开发人员再去写 Bean 的装配配置。
在 Spring Boot 应用里面,只需要在启动类加上@SpringBootApplication 注解就可以实现自动装配。
@SpringBootApplication 是一个复合注解, 真正实现自动装配的注解是
@EnableAutoConfiguration。
自动装配的实现主要依靠三个核心关键技术。
引入 Starter 启动依赖组件的时候,这个组件里面必须要包含 @Configuration 配置类,在这个配置类里面通过@Bean 注解声明需要装配到 IOC 容器的 Bean 对象。
这个配置类是放在第三方的 jar 包里面,然后通过 SpringBoot 中的约定优于配置思想,把这个配置类的全路径放在 classpath:/META-INF/spring.factories 文件中。这样 SpringBoot 就可以知道第三方 jar 包里面的配置类的位置,这个步骤主要是用到了 Spring 里面的 SpringFactoriesLoader 来完成的。
SpringBoot 拿到所第三方 jar 包里面声明的配置类以后,再通过 Spring 提供的ImportSelector 接口,实现对这些配置类的动态加载。
在我看来,SpringBoot 是约定优于配置这一理念下的产物,所以在很多的地方, 都会看到这类的思想。它的出现,让开发人员更加聚焦在了业务代码的编写上, 而不需要去关心和业务无关的配置。
其实,自动装配的思想,在 SpringFramework3.x 版本里面的@Enable 注解,就有了实现的雏形。@Enable 注解是模块驱动的意思,我们只需要增加某个@Enable 注解,就自动打开某个功能,而不需要针对这个功能去做 Bean 的配置,@Enable 底层也是帮我们去自动完成这个模块相关 Bean 的注入。
09 字节对齐_结构体数组 一、sizeof关键字1.1 基本类型的sizeof1.2 数组类型的sizeof1.3 结构体类型的sizeof 二、字节对齐--结构体对齐2.1 结构体对齐2.2 对齐规则2.2.1对其参数规则2.2.2 数据成员对齐规则2.2.2.3 结构体的总大小2.2.2.4 结构体嵌套 三、typedef关键字3.1 对已有类型定义别名3.2 一维数组类型的定义格式3.3 二维数组类型的定义格式3.4 结构体的定义格式 四、作业 一、sizeof关键字 1.1 基本类型的sizeof 可以适用类型,也可以适用变量
1.2 数组类型的sizeof 1.3 结构体类型的sizeof 二、字节对齐–结构体对齐 2.1 结构体对齐 例1 struct Test { char a; int b ; }; int main(int argc, char* argv[]){ Test t; printf("%d\n",sizeof(t)); printf("%d\n",sizeof(Test)); return 0; } 例2 struct Test { int a ; __int64 b ; char c ; }; int main(int argc, char* argv[]){ Test t; printf("
前言:
接下来我将带大家探索 进程间通信 的方式。本期,要讲的就是管道其中之一“匿名管道”!! 目录
(一)进程间通信介绍
1、进程间通信目的
2、进程间通信发展
3、进程间通信分类
(二)管道
1、什么是管道
2、站在文件描述符角度-深度理解管道
(三)管道分类
1、匿名管道 2、场景分类
3、管道读写规则
4、管道特点
(四)总结
(一)进程间通信介绍 进程间通信(Inter-process communication,IPC)是指操作系统中不同进程之间进行数据交换和通信的机制。
1、进程间通信目的 数据传输:一个进程需要将它的数据发送给另一个进程;资源共享:多个进程之间共享同样的资源;通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程);进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变 在一个计算机系统中,多个进程可能需要在运行时进行相互协作、共享数据或进行消息传递。为实现这些目的,操作系统提供了多种形式的进程间通信机制。 2、进程间通信发展 进程间通信(IPC)的发展一直与计算机领域的进步和需求密切相关。随着计算机技术的不断发展,IPC也经历了许多演进和改进,以满足不断增长的通信需求。以下是进程间通信发展的一些关键方面:
管道 System V进程间通信 POSIX进程间通信 3、进程间通信分类 下面是几种常见的进程间通信机制:
管道 匿名管道pipe 命名管道 System V IPC System V 消息队列 System V 共享内存 System V 信号量 POSIX IPC 消息队列 共享内存 信号量 互斥量 条件变量 读写锁 这些进程间通信机制各有优缺点,选择合适的机制取决于应用程序的需求和特点。开发者需要考虑数据传输的速度、数据大小、并发性、可靠性等因素来选择适当的通信机制。
(二)管道 1、什么是管道 管道通信是消息传递的一种特殊方式(见下图):
所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间的通信的一个共享文件,又名pipe文件;向管道(共享文件)提供输入的发送进程(即写进程),以字符流形式将大量的数据送入(写)管道;而接收管道输出的接收进程(即读进程)则从管道中接收(读)数据;为了协调双方的通信,管道机制必须提供以下三方面的协调能力:互斥、同步和确定对方的存在。 2、站在文件描述符角度-深度理解管道 【解释说明】
上述描述了一个进程的默认文件符打开表,其中0、1、2是默认打开的,而3、4是分别使用读和写分别打开管道文件(当然反过来也是一样的)。 【解释说明】
此时。父进程通过 fork 创建了子进程,只需把进程相关的数据结构调入,大家可以看成共享一片地址空间。 【解释说明】
此时,我们关闭管道文件的读写端。就会形成一个单向通信的信道,至此双方就可以使用文件描述符对管道进行一个读一个写的操作,即实现了通信。 (三)管道分类 在Linux中,管道是一种用于进程间通信的特殊机制。根据使用方式和功能,Linux中的管道可以分为不同类型:
基于矢量风格的一组画面:
矢量风格是海报设计中常见的一种风格,它主要使用矢量图形进行设计。矢量图形是由数学公式定义的图形,其特点是可以在不失去清晰度的情况下进行任意缩放,无论图形尺寸如何变化,都不会失真或模糊。
在矢量风格的设计中,通常使用矢量软件如Adobe Illustrator来创建图形元素。设计师会使用简单的几何形状和线条,并利用颜色、渐变、阴影等方式增加图形的视觉效果和层次感。这种风格通常具有简洁、干净、现代的视觉特点,适用于各种场景和主题,如商业、艺术、音乐等。矢量风格的好处在于可以保持图形的清晰度和可扩展性,使得设计在各种尺寸和媒介上都能保持一致的视觉效果。
此外,矢量图形是一种特殊的图片格式,常见的有AI或EPS格式。这些格式的文件通常具有较小的文件大小,适合于需要频繁缩放和修改的设计项目。矢量图形在平面设计、印刷、广告等领域有着广泛的应用,尤其在需要高品质、高清晰度图像的场合中,矢量风格的设计可以发挥其独特的优势。
prompt: A[矢量风格] --> B[购物袋]–>C[山水雾蒙蒙的纹理]–>D[白色背景],c4d渲染,细腻笔触,12k
目录
前言
1、什么是clickhouse
2、OLAP场景的关键特征
3、列式存储更适合于OLAP场景的原因
4、clickhouse的独特功能
5、clickhouse的缺点
6、性能
6.1、单个大查询的吞吐量
6.2、处理短查询的延迟时间
6.3、处理大量短查询的吞吐量
6.4、数据的写入性能
前言 11月份的时候,有幸收到OceanBase官方的邀请,代表部门去参加了OceanBase2023年度发布大会(对OceanBase不了解的兄弟盟,后面有空我会发表一些关于Ob的文章哈),之前公司国产化信创适配改造过程中,对于OB有了一定的实践以及了解。整个大会让我印象最深刻的就是OceanBase列存实验室版本同业内一流的大宽表数据库ClickHouse现场进行了跑分PK。结果显示,在同等硬件条件下,OceanBase的性能达到了ClickHouse的同一水平,甚至比ClickHouse还高一点点。之前对ClickHouse基本不了解,会后对这兄弟产生了好奇。利用业余时间了解了一下,做了下总结。
1、什么是clickhouse clickhouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS),由俄罗斯最大的搜索公司Yandex开发,于2016年开源,采用c++开发
2、OLAP场景的关键特征 大多数是读请求数据总是以相当大批的写入(>1000rows)不修改已添加的数据每次查询都从数据中读取大量的行,但同时仅需要少量的列宽表,即每个表包含大量的列较少的查询(通常每台服务器每秒数百个查询或更少)对于简单查询,允许延迟大约50ms列中的数据相对较小,如数字和短字符串处理单个查询时需要高吞吐量(每个服务器每秒高达数十亿行)事务不是必须的对于数据一致性要求低每个查询除了一个大表外,其余都很小查询结果明显小于源数据,或者说,数据被过滤或聚合后能够被盛放在内存中 3、列式存储更适合于OLAP场景的原因 列式数据对于大多数查询而言,处理速度至少提高了100倍
行式:
列式:
为何会有以上情况的发生?
针对分析类查询,通常只需要读取表中一小部分列。在列式数据库中你可以只读取你需要的数据。如果只需要读取100列中的5列数据,这将帮助你减少20倍的io消耗。由于数据总是打包成批量读取的,所以压缩是非常容易的。同时数据按列分别存储也容易压缩。由于io的降低,这将帮助更多的数据被系统缓存。 4、clickhouse的独特功能 真正的列式数据库管理系统,即除了数据本身外不应该存在其它额外的数据。这意味着为了避免在值旁边存在它们的长度,必须支持固定长度数值类型数据压缩,数据压缩在性能提升上有很关键的作用数据存储,clickhouse专门设计在机械盘工作,因此存储成本更低。如果有ssd和额外ram也将充分利用多核并行处理多服务器分布式查询处理,在clickhouse中,数据可以保存在不同的shard上,每个shard都由一组用于容错的replica组成,查询可以并行的在所有shard上进行处理,这对用户是透明的大部分情况兼容标准sql向量引擎,数据不仅以列存储,还以向量块来处理。因此可以提高cpu效率实时数据更新,click house支持具有主键的表,为了能够快速在主键范围内快速执行扫描,使用合并树对数据增量排序,因此支持数据不断添加到表中,添加时没有锁表索引,通过主键对数据进行物理排序这使得你以较低延迟(数毫秒)接收特定值或范围的数据适用于在线查询,低延迟意味着可以立即执行查询支持近似计算,click house提供各种允许牺牲数据精度情况下对查询数据进行加速的方法支持数据复制和数据完整性,clickhouse使用异步复制技术。当数据被写入任何一个可用副本后,系统会在后台将数据分发给其它副本,以保证系统在不同副本上保持相同的数据。大多数情况下,clickhouse能在故障后自动恢复,在一些少数情况下需要手动恢复 5、clickhouse的缺点 没有完整的事务支持缺乏高速率低延迟修改或删除已存在数据的能力,有可用于批量更新和删除数据的能力稀疏索引使得clickhouse不适合通过其键检索单行的定点查询 6、性能 根据Yandex的内部测试结果,clickhouse表现出了同类可比较产品更优的性能(长查询的吞吐量最高,短查询的延迟最低)
6.1、单个大查询的吞吐量 吞吐量可以以每秒处理的行数或每秒处理的字节数来衡量。如果数据被放置在page cache缓存的情况下,则不太复杂的查询在现代硬件上大约2-10G/s的速度在单个服务器上处理未压缩数据(对于简单查询,速度可以达到30G/s)
对于分布式处理,处理速度几乎是线性扩展的,但这受限于聚合或排序的结果不是那么大的情况下
6.2、处理短查询的延迟时间 如果一个查询使用主键且没有太多行(几十万行)进行处理,并且查询没有太多列,那么在数据被page cache的情况下,它的延迟应该小于50ms(最佳情况应该小于10ms)。否则,延迟取决于数据的查找次数。如果使用HDD,在数据没有加载的情况下,查询所需要的延迟可以通过一下公式计算得知:查找时间(10ms)*查询的列的数量*查询的数据库的数量
6.3、处理大量短查询的吞吐量 在相同情况下,clickhouse可以在单个服务器每秒处理数百个查询(在最佳的情况下最多可以处理数千个)。但是由于这不适用于分析型场景,因此我们建议每秒最多100次查询
6.4、数据的写入性能 建议每次写入不少于1000行的批量写入,或每秒不超过一个写入请求。可以使用多个insert并行插入,这将使性能线性提升
服务器的关键参数指标
5.1 操作系统
5.1.1 Windows Server
重要版本
Windows NT Server 4.0、Windows 2000 Server、Windows Server 2003、Windows Serve2003 R2、Windows Server 2008、Windows Server 2008 R2 、Windows Server 2012......
Windows服务器操作系统派应用,结合.NET开发环境,为微软企业用户提供了良好的应用框架。
5.1.2 Netware
在一些特定行业和事业单位中,NetWare优秀的批处理功能和安全、稳定的系统性能也有很大的生存空间。
NetWare常用的版本有Novell的3.11、3.12、4.10、5.0等中英文版。
5.1.3 Unix
Unix服务器操作系统由AT&T公司和SCO公司共同推出,主要支持大型的文件系统服务、数据服务等应用。
市面上流传的主要有SCO SVR、BSD Unix、SUN Solaris、IBM-AIX、HP-U、FreeBSDX。
5.1.4 Linux
Linux操作系统虽然与UNIX操作系统类似,但是它不是UNIX操作系统的变种。 Torvald从开始编写内核代码时就仿效UNIX,几乎所有UNIX的工具与外壳都可以运行在LINUX上。
Linux系统相比Windows更安全,运行效率更高
源码获取:俺的博客首页 "资源" 里下载! 项目介绍
Springboot户政电子档案管理平台系统为前后端分离的项目,
主要分为管理员、用户两种角色。
管理员角色主要功能如下:
首页
系统用户管理:管理员用户查询、添加、修改、删除;
单位管理:单位查询、添加、修改、删除;
部门管理:部门查询、添加、修改、删除;
岗位管理:岗位查询、添加、修改、删除;
用户管理:用户查询、添加、修改、删除;
案卷类别管理:案卷类别查询、添加、修改、删除;
案卷管理:案卷查询、添加、修改、删除;
案卷目录管理:案卷目录查询、添加、修改、删除;
人口基本管理:人口基本查询、添加、修改、删除;
案卷统计:按案卷类别统计;
人口基本统计:按户口类型统计;
用户主要功能如下:
首页;
个人资料管理:修改个人资料;
案卷类别管理:案卷类别查询;
案卷管理:案卷查询;
案卷目录管理:案卷目录查询;
人口基本管理:人口基本查询;
环境需要
1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;
4.数据库:MySql 5.7/8.0版本均可;
5.是否Maven项目:是;
技术栈
后端:SpringBoot+Mybaits
前端:Vue+axios
后端项目运行 - houduan:
1. 使用Navicat或者其它工具,在mysql中创建对应sql文件名称的数据库,并导入项目的sql文件;
2. 使用IDEA/Eclipse/MyEclipse导入项目houduan,导入成功后请执行maven clean;maven install命令,然后运行;
3. 将项目中application.yml配置文件中的数据库配置改为自己的配置;
4. 控制台提示运行成功后再运行前端项目;
前端项目运行 - houtai:
1.命令行cd进入 前端目录 houtai; 2.执行命令 npm install 下载依赖; 3.执行命令 npm run dev 启动; 4.
系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装
Pytorch深度学习-----数据模块Dataset类
Pytorch深度学习------TensorBoard的使用
Pytorch深度学习------Torchvision中Transforms的使用(ToTensor,Normalize,Resize ,Compose,RandomCrop)
Pytorch深度学习------torchvision中dataset数据集的使用(CIFAR10)
Pytorch深度学习-----DataLoader的用法
Pytorch深度学习-----神经网络的基本骨架-nn.Module的使用
Pytorch深度学习-----神经网络的卷积操作
Pytorch深度学习-----神经网络之卷积层用法详解
Pytorch深度学习-----神经网络之池化层用法详解及其最大池化的使用
Pytorch深度学习-----神经网络之非线性激活的使用(ReLu、Sigmoid)
Pytorch深度学习-----神经网络之线性层用法
Pytorch深度学习-----神经网络之Sequential的详细使用及实战详解
Pytorch深度学习-----损失函数(L1Loss、MSELoss、CrossEntropyLoss)
Pytorch深度学习-----优化器详解(SGD、Adam、RMSprop)
Pytorch深度学习-----现有网络模型的使用及修改(VGG16模型)
Pytorch深度学习-----神经网络模型的保存与加载(VGG16模型)
Pytorch深度学习-----完整神经网络模型训练套路
Pytorch深度学习-----实现神经网络模型在GPU上进行训练的方法
文章目录 系列文章目录一、完整的模型验证套路步骤1.步骤1:导入必要的库2.步骤2:加载和预处理图像3.步骤3:定义神经网络模型4.步骤4:加载预训练模型5.步骤5:为模型推理准备图像6.步骤6:模型评估和预测 二、代码演示 一、完整的模型验证套路步骤 1.步骤1:导入必要的库 import torch import torchvision from PIL import Image from torch import nn 这里,导入了用于深度学习任务的torch和torchvision,用于图像处理的PIL中的Image,以及torch中的nn模块用于神经网络层。
2.步骤2:加载和预处理图像 image_path = "../imgs/airplane.png" image = Image.open(image_path) print(image) image = image.convert('RGB') 从给定路径加载一张图像,并将其转换为RGB格式,确保与大多数预训练模型的兼容性,这些模型期望有三个颜色通道。
transform = torchvision.transforms.Compose([ torchvision.transforms.Resize((32, 32)), torchvision.transforms.ToTensor() ]) image = transform(image) print(image.shape) 图像被调整为32x32像素的尺寸,并转换为张量。使其符合要求。
3.步骤3:定义神经网络模型 class Lgl(nn.Module): def __init__(self): super(Lgl, self).