Linux基础及Linux环境搭建(保姆级别)

详细:!!!!!!!!!!!!!! ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 第一章 Linux基础及Linux环境搭建(保姆级别)_Kali-BugChen的博客-CSDN博客 第一章 Linux基础及Linux环境的搭建(保姆级别) 一、Linux简介 1、什么是Linux? ​ 一款免费开源流行的操作系统。 2、Linux为什么流行? 1)Windows以用户的体验很好而流行 2)Linux流行主要是因为稳定而流行 Linux一般用于企业中中的服务器 Linux用来做服务器操作系统使用 3、Linux与Windows操作系统的区别 1)Windows是一款单用户、多线程、多任务的操作系统。 2)Linux是一款多用户、多线程、多任务的操作系统。 4、类Unix操作系统 5、Linux操作系统特点 1)开源:开放源代码 ​ (1)底层是用C语言和C++语言来实现的。 ​ (2)多用户。 ​ (3)稳定:一些公司会规定公司7*24小时不关机,为了防止出现死机、蓝屏,一般都是采用Linux操作系统。 6、Liunx发展史 ​ 1991年,AT&T实验室开发了unix操作系统——》Unix7版本发布以后,AT&T将其代码私有化——》Andrew S。Tanenbaum开发了类似于Unix的微内核的Unix操作系统minix操作系统,并将其开源——》Linus trovald 随后对minix操作系统(类Unix)进行了优化,并于1994年将Linux1.0发布出来。 7、Linux版本 1)CentOs 2)RedHat 3)Ubuntu 4)红旗 5)蓝点 6)中标麒麟 ​ (1)中标麒麟(民用) ​ (2)银河麒麟(军用) ​ (3)2013年合并 7)kali Linux:一般用于系统漏洞进行操作系统的渗透测试(很猛) 8)magic box 二、Linux安装 1、虚拟机 ​ 简单来说,将本机剩余的空间分配给其他的操作系统进行使用。 2、常用的三款软件 1)vitual box:软件级别的 2)Vmware:软件级别的 3)VMware vSphere:操作系统级别的 3、VM和Linux的安装 ​ 前提条件:Linux需要在电脑上安装使用,我们总不能把我们自己的电脑的Windows操作系统给卸载了,然后安装Linux来使用吧,因此需要使用虚拟机来安装Liunx。 1)Windows、VM和Linux的关系 ​ 关系:Windows本身就是一款流行的操作系统,一般情况下一台计算机设备装一个操作系统,在内存充足的情况下,我们可以通过VM虚拟机软件将计算机的内存划分一块出来,这一块内存用来给Linux使用(可以把这一块内存看作做了Linux的虚拟电脑),而VM的作用则是划分空间做到虚拟电脑与Windows的相对隔离。 备注: 虚拟空间可以放到其他的Windows上使用,用VM软件打开即可。 2)安装CentOs过程

React 封装全局事件监听 GlobalEvent(发布订阅者)

类似于vue的$root和$on,可以全局触发和监听事件,采用发布订阅者模式实现,支持单事件多响应,简单易懂。 globalEvent.ts // globalEvent.ts class GlobalEvent { private static instance: GlobalEvent; public eventObject: any; constructor() { this.eventObject = {}; } public subscribe(eventKey: string, callBack: Function) { if (this.eventObject[eventKey]) { this.eventObject[eventKey] = [...this.eventObject[eventKey], callBack]; } else { this.eventObject[eventKey] = [callBack]; } } public submit(eventKey: string, ...params: any) { const callBack = this.eventObject[eventKey]; if (callBack && callBack.length) { callBack.forEach((cb: Function) => { cb(...params); }); } } static getInstance(): GlobalEvent { if (!

人工智能常用网站及论坛

网站1 Microsoft C++、C 和汇编程序文档网站: https://docs.microsoft.com/zh-cn/cpp/?view=msvc-160 网站2 菜鸟教程网站: https://www.runoob.com/cplusplus/cpp-tutorial.html 网站3 微软开发者论坛: https://social.msdn.microsoft.com/forums/zh-cn/home 网站4 C++参考手册网站: https://zh.cppreference.com 网站5 从GitHub下载STL的网站: https://github.com/steveLauwh/SGI-STL 网站6 从glibc下载STL的网站: http://ftp.gnu.org/gnu/glibc 网站7 Qt英文版官方文档网站:https://doc.qt.io 网站8 Qt中文版官方文档网站:https://www.qtdoc.cn 或者http://qtdocs.sourceforge.net 网站9 Java英文版官方文档网站: https://docs.oracle.com/en/java/index.html 网站10 Java中文版官方文档网站: https://tool.oschina.net/apidocs 网站11 R工具包下载网站:https://cran.r-project.org/web/packages 网站12 GitHub官方网站:https://github.com 网站13 TortoiseSVN官方网站:https://tortoisesvn.net 网站14 VisualSVN官方网站:https://www.visualsvn.com 网站15 中国国家图书馆网址:http://www.nlc.cn 网站16 上海图书馆网址:https://library.sh.cn 网站17 谷歌学术网址:https://scholar.google.com 网站18 AMiner网址:http://www.aminer.cn 网站19 Acemap网址:https://www.acemap.info 网站20 Semantic Scholar网址:https://www.semanticscholar.org 网站21 微软学术网址:https://academic.microsoft.com/home 网站22 百度学术网址:https://xueshu.baidu.com 网站23 中国知网网址:https://www.cnki.net 网站24 arXiv网址:https://arxiv.org 网站25 WikiCFP网址:http://www.wikicfp.com/cfp 网站26 中国计算机学会网址:https://www.ccf.org.cn 网站27 Journal Citation Reports(JCR)网址:https://clarivate.com/webofsciencegroup/solutions/journal-citation-reports 网站28 小木虫期刊投稿辅助系统网址:http://muchong.

pip使用指南

pip是Python包管理工具,该工具提供了对Python包的查找、下载、安装、卸载的功能。 目录 1 pip安装 2 pip换源 3 pip常用命令 4 pip升级 1 pip安装 pip 官网:pip · PyPI Python 2.7.9 + 或 Python 3.4+ 以上版本都自带 pip 工具。 你可以通过以下命令来判断是否已安装: pip --version # Python2.x 版本命令 pip3 --version # Python3.x 版本命令 如果没有安装可以参考:Python pip 安装与使用。 2 pip换源 默认情况下pip使用的是国外的镜像,在下载的时候速度非常慢,所以需要将pip的官方软件源服务器换成国内的镜像服务器,从而提升Python软件包安装效率和成功率。 pip常用国内镜像地址 中国科学技术大学 : https://pypi.mirrors.ustc.edu.cn/simple清华大学:https://pypi.tuna.tsinghua.edu.cn/simple豆瓣:http://pypi.douban.com/simple/阿里云:http://mirrors.aliyun.com/pypi/simple/ 镜像源的使用(以清华大学开源软件镜像站举例) 临时使用,我们可以直接在 pip 命令中使用 -i 参数来指定镜像地址,例如: pip3 install SomePackage -i https://pypi.tuna.tsinghua.edu.cn/simple 这种只对当前安装命令有用,如果需要全局修改,则需要修改配置文件,在Windows下,你需要在当前用户目录下(C:\Users\XX\AppData\Roaming\pip,XX表示当前使用用户,比如张三)创建一个 pip.ini,并在pip.ini文件中输入以下内容: [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple [install] trusted-host = pypi.tuna.tsinghua.edu.cn 注意:AppData文件夹需要将电脑隐藏的项目设置为可见才能找到 3 pip常用命令 显示版本和路径

pymol安装

PyMOL是一个开源基础上的用户赞助的分子可视化系统,由薛定谔维护和分发。 1. conda 安装 # 安装conda # 安装conda环境并激活 conda install -c schrodinger pymol-bundle pip3 install PyQt5 ##注意:远程服务器上不能启动,本地安装可以启动。 ## 永久试用 # 安装路径下的 /path/to/lib/site-packages/pymol下找到licensing.py,把里面跟授权相关的代码注释掉,或者修改licensing.py文件 cp $con_env/lib/python3.8/site-packages/pymol/licensing.py $con_env/lib/python3.8/site-packages/pymol/licensing.py.bak vim $con_env/lib/python3.8/site-packages/pymol/licensing.py ## ## Incentive PyMOL licensing helpers ## import sys import os import threading USE_DIRECTORIES = False USE_FILENAMES = True LICENCE_DIRECTORY = u'$PYMOL_PATH/licenses' LICENCE_DIRECTORY_USER = u'~/.pymol/licenses' LICENCE_FILENAME = u'$PYMOL_PATH/license.lic' LICENCE_FILENAME_USER = u'~/.pymol/license.lic' post_ns = {} from os.path import expanduser def post_license_check(msg): try: print("CRACKED", post_ns, msg) post_ns['callback'](msg) except KeyError: post_ns['message'] = msg def set_post_license_check_handler(callback): post_ns['callback'] = callback try: callback(post_ns.

解决方案:MacBook如何安装多版本JDK?

操作系统:MacOs 电脑芯片:M1 1、Oracle官网全版本JDK下载地址: ​​​​​ Java Archive | Oracle 中国https://www.oracle.com/cn/java/technologies/downloads/archive/ 2、下载多版本jdk 根据电脑芯片下载对应版本的jdk,(JDK17以及之后才加入Arm版本)。这里我们提前下载好需要的几个版本的jdk等待安装即可。 3、安装jdk 本文使用的是 .dmg 安装版本。和正常mac中App安装方式一样,双击 .dmg 安装程序,依次安装完成多版本的jdk即可 4、验证安装 安装完成之后的jdk可以在 “/Library/Java/JavaVirtualMachines/” 看到多版本的jdk目录,我这里是安装了3个版本,如下图: 5、配置环境变量 当我们成功安装完成所有需要的jdk之后,我们开始进行配置jdk的环境变量。由于是多版本的jdk,系统总会采用一个默认版本的jdk,也只能同时启用 一个版本的jdk,这里我们使用别名的形式指定生效的jdk路径。配置文件: ~/.bash_profile(个人具体使用的确定) # 配置多版本jdk export JAVA_7_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home export JAVA_8_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home export JAVA_17_HOME=/Library/Java/JavaVirtualMachines/jdk-17.0.1.jdk/Contents/Home # jdk版本别名 alias jdk8='export JAVA_HOME=$JAVA_8_HOME' alias jdk7='export JAVA_HOME=$JAVA_7_HOME' alias jdk17='export JAVA_HOME=$JAVA_17_HOME' # 默认jdk8 export JAVA_HOME=$JAVA_8_HOME export PATH=$JAVA_HOME/bin:$PATH export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar 6、使环境变量生效 配置完成之后我们执行 “source ~/.bash_profile” 让配置文件立即生效 source ~/.bash_profile 7、验证是否生效 配置完成之后我们可以打开一个 “终端” 窗口进行测试。 例如查看当前使用jdk版本“java -version”,由于我们配置文件设置了默认使用jdk8,所以我们打印出来的jdk版本就是jdk8的信息。 8、验证多版本间切换 如果我们现在由于jdk8的语法不支持新版本语法,可以直接使用命令切换jdk使用版本即可。可以看见我们直接就可以切换成使用jdk17。 jdk17 大功告成!!!

webpack-SplitChunksPlugin学习

前言 Webpack 默认会将尽可能多的模块代码打包在一起,优点是能减少最终页面的 HTTP 请求数,但缺点也很明显: 1 页面初始代码包过大,影响首屏渲染性能; 2 无法有效应用浏览器缓存,特别对于 NPM 包这类变动较少的代码,业务代码哪怕改了一行都会导致 NPM 包缓存失效。 理解chunk chunks代码块 assets资源 file文件 区别 modules: 模块,每个文件就是一个模块chunks: 打包的每个文件属于独立的模块,然后webpack通过入口开始寻找依赖图,每个入口文件及其依赖的模块就是一个chunksassets: 资源,chunks打包后输出资源,内容就是字符串。file: 打包后的资源会写入硬盘,生成main.js文件 chunk详细 Chunk 是 Webpack 内部一个非常重要的底层设计,用于组织、管理、优化最终产物,在构建流程进入生成(Seal)阶段后: 1 Webpack 首先根据 entry 配置创建若干 Chunk 对象; 2 遍历构建(Make)阶段找到的所有 Module 对象,同一 Entry 下的模块分配到 Entry 对应的 Chunk 中;(同步chunk) 3 遇到异步模块则创建新的 Chunk 对象,并将异步模块放入该 Chunk;(异步chunk) 4 分配完毕后,根据 SplitChunksPlugin 的启发式算法进一步对这些 Chunk 执行裁剪、拆分、合并、代码调优,最终调整成运行性能(可能)更优的形态; 5 最后,将这些 Chunk 一个个输出成最终的产物(Asset)文件,编译工作到此结束。 Chunk 分包结果的好坏直接影响了最终应用性能,Webpack 默认会将以下三种模块做分包处理: 1 Initial Chunk:entry 模块及相应子模块打包成 Initial Chunk; 2 Async Chunk:通过 import('.

【python socket】TCP客户端断线重连

主要思想:用一个线程每1s发一组数据,判断当前服务端是否还存活,如果活着就等1s再继续发数据,如果服务端挂了就等2s重新connect def Thread_ConnectSocket_CAN(): while True: try: global tcp_client_socket_CAN tcp_client_socket_CAN = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_client_socket_CAN.connect(("127.0.0.1", 6000)) while True: try: sendData = "7E7EC2880001004BAA55" tcp_client_socket_CAN.send(bytes.fromhex(sendData)) time.sleep(1) except: break except socket.error: print("未连接,尝试重连中..") time .sleep(2) except Exception as e: print(e) time.sleep(2) if __name__ == '__main__': # 启动线程 thread_obj_CAN = threading.Thread(target=Thread_ConnectSocket_CAN) thread_obj_CAN.setDaemon(True) thread_obj_CAN.start()

big.Int

big.Int是Go超大整型数据的结构。它可以进行超大收据的运算和比较等操作。 初始化 通过整型字面量或int64创建 big.NewInt函数可以基于一个int64整型数据或整型字面量创建一个big.Int实例: package main import "math/big" func main() { var ( num int = 6 ) number1 := big.NewInt(int64(num)) number2 := big.NewInt(6) } 通过字符串创建 big.Int实例的SetString方法可以通过字符串来创建一个big.Int实例。该方法返回两个数据,一个big.Int实例,和一个bool值用来表示成功还是失败。 package main import ( "fmt" "math/big" ) func main() { number, ok := new(big.Int).SetString("123000001230011", 10) if !ok { fmt.Println("create big.Int failed") return } fmt.Println(number) // 123000001230011 } SetString允许指定数字的进制。创建的结果仍然是十进制的大整型数据: package main import ( "fmt" "math/big" ) func main() { number, ok := new(big.Int).SetString("110000011010101010101", 2) if !

Docker启动Mysql

操作系统:windows docker桌面:Docker Desktop DockerHub账号:xxxx 操作步骤: 1、docker hub下载mysql镜像。直接在“image”菜单主界面搜索框搜索“mysql”,根据需求下载指定版本。这里以latest为例,选中某版本镜像,点击“Pull”即可拉去该镜像。 2、下载完成之后在“image”菜单中即可看见对应的镜像信息。 3、有了镜像之后就可以直接点击运行按钮,配置上基本的初始化信息即可生成对应的container。配置项如图(使用最基本的配置项,足够正常使用mysql),配置完成点击“Run”即可运行。 4、成功运行之后在“containers”菜单中即可看见此运行中container,点击container名称即可实时查看运行状况。最酷的是提供直接进入container内部的“Terminal”,通过此工具我们可以直接操作container内部的所有内容。 5、测试mysql是否成功启动并可以使用,命令行尝试登录mysql,使用命令“mysql -uroot -proot”,这里为了方便直接将密码加在命令行中,实际操作万万不可将密码直接放在命令行中,应当使用“mysql -uroot -p”,等待提示再输入密码(此时密码不显示,不要误认为没有输进去!) 6、此时可见已经成功通过命令进入mysql命令模式,说明我们已经成功完成基本操作。我们尝试执行一下sql语句。成功运行。 7、接下来我们可以通过连接工具远程连接。 大功告成!!! 避坑事项: 1、mysql不允许远程连接(举例:一般虚拟机安装会出现该问题) container内部进入命令模式,登录mysql,进行修改mysql的host值,将允许所有host登录root账号。 执行命令: # 修改host “update user set host = ‘%’ where user = ‘root’;” # 刷新 “flush privileges;” 2、navicat无法连接(mysql密码加密模式增强) 执行命令: # 更改mysql密码加密模式 “ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'newPassword';” 3、命令行也无法登录“Access denied for user ‘root‘@‘localhost‘(using password:YES/NO)” ①密码输入错误/未输入密码 重新输入正确密码进行尝试。 ②账号问题 主机提供跳过密码验证方式登录,登录完成修改root密码即可 # 跳过密码认证 "mysqld -console --skip-grant-tables --shared-memory" # 切换为mysql数据库 "use mysql;"

redisTemplate 批量获取指定key下所有数据,并删除

使用redisTemplate.keys(str),版本问题会报 ERR unknown command KEYS, with args beginning with: `… 因此可使用 String pattern = "Impl:*"; AtomicInteger count = new AtomicInteger(); List<String> lis = new ArrayList<>(); ScanOptions options = ScanOptions.scanOptions().match(pattern).count(1000) .build(); Cursor<String> cursor = (Cursor<String>) redisTemplate.executeWithStickyConnection( redisConnection -> new ConvertingCursor<>(redisConnection.scan(options), redisTemplate.getKeySerializer()::deserialize)); cursor.forEachRemaining(key -> { redisTemplate.delete(key); }); System.out.println(lis.toString());

jmeter的使用

一、jmeter介绍和下载 1.1 jmeter介绍 Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。 另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。 1.2Jmeter的下载和安装 下载地址 下载.zip结尾的包 1.3运行Jmeter 进入bin目录执行 jmeter.bat 设置页面显示中文 二、并发接口测试 模拟请求一个接口 参数就是 id是 1-10的用户 请求这个接口 2.1 添加线程组 右键测试计划,添加一个线程组,可以设置对应多少秒有多少个线程数来访问这个接口。 2.2 添加http请求 2.3 添加http请求的响应 2.4:添加一个计数器 这个计数器主要用来计 id 1-10的用户的 2.5:测试添加的请求 我们这样设置计数器里面的值,然后进行测试查看 可以看到我们请求,返回的响应数据

golang工程组件篇 字段验证器val idator之自定义字段、结构体补充及自定义验证

Golang是一种快速、安全、高效的编程语言,被广泛用于构建高性能、分布式系统。在Golang中,组件化编程是一个非常重要的概念。组件化编程可以使代码更加清晰简洁,易于维护和扩展。 在本文中,我们将讨论Golang工程组件篇中的字段验证器val idator之自定义字段、结构体补充及自定义验证。 一、自定义字段 在val idator中,我们可以使用现有的标准类型进行验证,也可以通过自定义类型来实现更加灵活的验证。下面是一个简单的示例: package main import ( "github.com/go-playground/validator/v10" ) type Age int func (a Age) Validate(fl validator.FieldLevel) bool { return a > 0 && a < 100 } type User struct { Name string `validate:"required"` Age Age `validate:"required,age"` } func main() { user := &User{ Name: "John Doe", Age: 120, } validate := validator.New() validate.RegisterValidation("age", Age(0).Validate) err := validate.Struct(user) if err != nil { for _, e := range err.

spring boot 中如何配置国际化/多语言

在Spring Boot中配置国际化(Internationalization,简称i18n)可以通过以下步骤: 在resources目录下创建一个messages文件夹,用于存放不同语言的国际化资源文件。在messages文件夹下创建对应语言的属性文件,例如messages.properties为默认的英文资源文件,messages_zh_CN.properties为中文资源文件。根据需要可以创建其他语言的资源文件,如messages_fr.properties为法语资源文件。在属性文件中定义键值对,其中键为消息的标识符,值为对应语言的消息文本。例如: greeting=Hello! farewell=Goodbye! 在Spring Boot的配置文件(如application.properties或application.yml)中配置国际化相关的设置: 对于application.properties文件,添加以下配置: spring.messages.basename=messages/messages spring.messages.encoding=UTF-8 对于application.yml文件,添加以下配置: spring: messages: basename: messages/messages encoding: UTF-8 在需要使用国际化的地方,注入MessageSource对象,并调用其getMessage方法来获取对应的消息。例如,在控制器中: @Autowired private MessageSource messageSource; public String getGreetingMessage(Locale locale) { return messageSource.getMessage("greeting", null, locale); } 在上述代码中,getMessage方法接收三个参数:消息的键、参数数组(如果有动态参数)、Locale对象,然后返回对应语言的消息文本。 配置locale: Locale对象是Java中表示特定区域设置(Locale)的类。它包含了关于语言、地区和国家等信息,用于在应用程序中进行国际化和本地化的操作。Locale对象提供了获取和设置语言、地区、国家和变体等属性的方法。 Locale对象通常由语言和地区两个部分组成,可以使用以下方式创建Locale对象: 使用语言代码创建Locale对象:Locale locale = new Locale("en");使用语言代码和地区代码创建Locale对象:Locale locale = new Locale("en", "US"); 在国际化应用程序中,可以根据用户的首选语言或系统默认语言设置来确定Locale对象。Locale对象用于在资源文件中选择对应语言的文本消息,以实现多语言支持。 例如,Locale.US代表英语(美国)的Locale,Locale.CHINA代表中文(中国)的Locale。通过使用Locale对象,可以在应用程序中根据不同的Locale来获取相应的本地化资源,实现国际化功能。 通过以上步骤,你可以在Spring Boot应用中实现国际化功能,根据用户的Locale设置动态获取对应语言的消息文本。

Jackson 反序列化 “yyyy-MM-dd“ = > LocalDateTime

Jackson 反序列化 “yyyy-MM-dd” = > LocalDateTime LocalDateTime日期格式讲解 标准格式 yyyy-MM-dd’T’HH:mm:ss 全局配置 import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; import com.gientech.lcds.generator.commons.biz.convert.SystemConvertor; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Locale; /** * web配置 * * desc: LONG转STRING; 解决web返回的json数据中long类型精度丢失问题。 */ @Configuration public class WebConfiguration { @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder .

SDF(Signed-distance-field: 有向距离场)(3): 空间划分原理(源码解释)

下面这是SDF常用的三个函数: // intersect(求交) vec2 mult(vec2 tA, vec2 tB) { if(tA.x > tB.x) return tA; return tB; } // union(合并) vec2 add(vec2 tA, vec2 tB) { if(tA.x < tB.x) return tA; return tB; } // difference(差异) vec2 subtract(vec2 tA, vec2 tB) { tB.x = -tB.x; if(tA.x > tB.x) return tA; return tB; } 这三个函数用于计算一个空间点位于一个一个空间分布函数所描述的空间的"里面"还是外面,如果是"里面",那这个点所对应的空间分布函数所描述的空间的对应位置就可见。 那么,他们的原理是什么呢? 先从2D平面说起。一个2D平面,默认是无限大的,但是一条这个平面上的直线可以将它分为两个部分,也就是两个空间。如果直线定义了正方向,那么这两部分各自就有了正负空间这个称呼。 这个2D空间中的一个圆或者一个三角形,是由曲线围起来的一片区域:一个封闭空间,这时候,我们就可以断定一个2D平面上的点在这个封闭空间里面还是外面。 这里可以规定在这个区域里为负值,在其外面就为正值。 接着看3D空间。在3D空间里,原本3D空间是无限延伸的。而一个3D空间中的平面(当然也有曲面,这里先只看平面),将3D空间划分为两部分,我们都知道3D空间中的平面需要一个法线n(nx,ny,nz)来描述 可以认为法线的方向上的空间为正空间,反之为负空间。例如一个球体或者长方体,球体是个封闭空间是个曲面,将3D空间分为两部分,球体里面和外面,按照上述规定,里面为负值外面为正值。 同理,长方体也一样,展开来讲只要空间分布函数(你可以任意构造这个函数)能描述都可以。 因为3D空间中的封闭空间只能由面来决定,所以空间分布函数的实现只能是面或者曲面的某种集合 现在来看上述三个函数 A.intersect(求交): vec2 mult(vec2 tA, vec2 tB),和乘法类似,因此可以这么理解:一个空间点,必须同时属于两个封闭空间,才能视为可见 B.add(求和): vec2 add(vec2 tA, vec2 tB), 和加法类似,因此可以这么理解:一个空间点,只要属于两个封闭空间中的任何一个,就能视为可见

vue项目html导出到word

用到的插件名称 html-docx-js npm i html-docx-js 封装js方法 import htmlDocx from 'html-docx-js/dist/html-docx' // 对应插件名 html-docx-js // 下载文件 function saveAs (blob, fileName) { const a = document.createElement('a') const url = URL.createObjectURL(blob) a.href = url a.download = fileName a.display = 'none' document.body.appendChild(a) a.click() document.body.removeChild(a) URL.revokeObjectURL(url) } /** * * @param element 要打印元素的id * @param filename 导出文件名 */ export function exportword (element, filename) { /* 步骤1 :因为canvas是运行在内存中的,所以也不能通过cloneNode方法克隆下来(克隆下来是空的), 所以先克隆再在克隆的dom上进行操作是不可取的。所以需要在原DOM上生成img, 设置display: none从而使图片不影响页面展示,并插入到对应canvas元素之前(为了保证顺序不变)。 */ const app = document.

rtl仿真器-vcs安装和测试(一)

#准备 ## 下载文件解压 sysynopsys installer:synopsys软件安装工具,通过该软件安装VCS和Verdi vcs_mx_vO-2018.09-SP2:VCS Verilog+VHDL 混合仿真软件 vcs_vO-2018.09-SP2:VCS Verilog仿真软件 verdi-2018.9:Verdi软件 安装目录 vcs2018 安装vcs 的目录 verdi2018 安装verdi 的目录

PIL图像处理(4)

pillow有用函数 pillow图像缩放 指定不同的插值方式: image = image.resize((nw,nh), Image.BICUBIC) label = label.resize((nw,nh), Image.NEAREST) pillow图像翻转 image = image.transpose(Image.FLIP_LEFT_RIGHT) label = label.transpose(Image.FLIP_LEFT_RIGHT) PIL.Image与OpenCV PIL.Image转换成OpenCV格式 import cv2 from PIL import Image import numpy image = Image.open("plane.jpg") image.show() img = cv2.cvtColor(numpy.asarray(image),cv2.COLOR_RGB2BGR) cv2.imshow("OpenCV",img) cv2.waitKey() OpenCV转换成PIL.Image格式 import cv2 from PIL import Image import numpy img = cv2.imread("plane.jpg") cv2.imshow("OpenCV",img) image = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) image.show() cv2.waitKey() PIL.Image中有用属性 img.format img.filename img.mode img.format_description img.size pillow报错分析 IOError: image file is truncated 解决办法: from PIL import ImageFile ImageFile.

PIL图像处理(3)

pillow的像素索引 单像素操作 pillow区域操作 # 对图像一个区域的操作转化为对这个区域的每个像素进行操作 box = (100, 100, 400, 400) region = im.crop(box) region = region.point(lambda x:x+100) im.paste(region, box) im.show() pillow中paste操作 pillow掩模操作 If a mask is given, this method updates only the regions indicated by the mask. You can use either “1”, “L” or “RGBA” images (in the latter case, the alpha band is used as mask). Where the mask is 255, the given image is copied as is.

PIL图像处理(2)

显示图像 from PIL import Image im = Image.open("hopper.ppm") from _future_ import print_function print(im.format, im.size, im.mode) im.show() 显示缩略图 示例代码如下: im.thumbnail(size) im.save(outfile, "JPEG") 写图像 示例代码如下: im.save(outfile, "JPEG") # 或者 im.save(r'C:\Users\Administrator\Desktop\rabbit_copy.jpg') Image与ndarray之间的转换 Image转化为ndarray ndarray=np.array(Image) # 或者 ndarray = np.asarray(Image) ndarray转化为Image im = Image.fromarray(a) 高宽或size的顺序 Image读图片的大小是图片的(width, height),即img.size的返回值 Image没有shape属性 box或rect的顺序 box is a 4-tuple, where coordinates are (left, upper, right, lower),即(x1,y1,x2,y2) pillow的坐标系统 横为x轴,纵为y轴

【Linux】项目自动化构建工具-make和Makefile 的使用和进度条的实现

文章目录 一、什么是make/makefile二、如何编写makefile三、make 的工作原理1.make的使用2.make的依赖性3.项目清理4..PHONY伪目标 四、Linux第一个小程序 -- 进度条1.\r&&\n2.行缓冲区概念3.进度条process.hprocesstest.cmakefile 一、什么是make/makefile 什么是makefile 在我们以后的工作环境中,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作 Linux中提供了自动化构建工具–makefile来帮我们解决这个问题,makefifile带来的好处就是——“自动化编译”,makefile一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率 此外,会不会写makefifile,从一个侧面说明了一个人是否具备完成大型工程的能力 什么是make make是一个命令工具,是一个解释makefifile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefifile都成为了一种在工程方面的编译方法 总结:make是一条命令,makefifile是一个文件,两个搭配使用,完成项目自动化构建 二、如何编写makefile makefile的编写重要的是编写依赖关系和依赖方法,依赖关系是指一个文件依赖于另一个文件,即我们想到得到一个文件,在目录下我们必须先有的另外一个文件,依赖方法是指如何依赖文件来得到对应的目标文件 我们在编写makefile的时候需要注意一下几点: 1.makefile文件名必须是makefile/Makefile,不能是其他的文件名,否则make无法识别 2.依赖文件可以有多个,也可以没有 3.依赖方法必须以Tab键开头,不能是四个空格 我们以下面的例子来说明如何编写makefile文件 #include <stdio.h> int main() { printf("hello makefile\n"); return 0; } makefile文件: test.out:test.c // 依赖关系 gcc test.c -o test.out // 依赖方法 .PHONY:clean //伪目标 clean: rm -f test.out 如上,在makefile文件中,test.out 依赖于test.c ,我们以冒号作为分隔符,依赖方法是gcc 编译执行,clear不依赖于任何文件,依赖方法为rm -f指令,其中,.PHONY修饰的clear表示其是一个伪目标,表示它总是被执行 三、make 的工作原理 1.make的使用 在Linux在,我们输入make命令之后,make会在当前目录下找名字叫“Makefifile”或“makefifile”的文件,如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“test.c”这个文件,并把这个文件作为最终的目标文件,如果找不到,就会打印提示信息 在我们上面的例子中,makefile中一共有两个目标文件,test.out和clear,如下,我们输入make它会默认执行第一个目标文件,此外,我们也可以指定多个目标文件来让它执行多个目标文件 1.没有编写makefile文件: 2.使用一个指令: 3.同时使用多个指令 2.make的依赖性 我们将上面例子的makefile修改成如下内容: test.out:test.o gcc test.o -o test.out test.o:test.s gcc -c test.

TRUNCATE TABLE t 和DELETE FROM t的区别

背景 最近再工作中,遇到一个问题,就是再代码执行过程中,出现异常时并不会去回滚代码.导致数据不一致,最初以为是@Transactional这个注解没有生效 Spring中什么时候@Transactional会失效 因为Spring事务是基于代理来实现的,所以某个加了@Transactional的方法只有是被代理对象调用时,那么这个注解才会生效,所以如果被代理对象来调用这个方法,那么@Transactional是不会失效的同时如果这个方法是private的,那么@Transactional也会失效,因为底层cglib是基于子父类来实现的,子类是不能重载父类的private方法的,所以无法很好的利用代理,也会导致@Transactional失效异常没有被正确抛出,那么@Transactional也会失效.@Transactional默认情况下只对未捕获的运行异常进行回滚,而对已检查异常不会回滚事务,默认只回滚RuntimeException,如果需要对特定异常进行回滚,可以使用rollbackFor属性来指定需要回滚的异常类型 经排查代码中不存在以上问题,后来才知道是SQL的问题,只因为使用了一条SQL: TRUNCATE TABLE user 代码 使用代码模拟当时场景; 数据准备 DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic; INSERT INTO `user` VALUES ('be079b29ddc111eda9b20242ac110003', '张三', '北京市海淀区xx街道123号'); INSERT INTO `user` VALUES ('be079b53ddc111eda9b20242ac110003', '李四', '上海市徐汇区xx路456号'); INSERT INTO `user` VALUES ('be079b95ddc111eda9b20242ac110003', '王五', '广州市天河区xx街道789号'); INSERT INTO `user` VALUES ('be079ba4ddc111eda9b20242ac110003', '赵六', '深圳市南山区xx路321号'); INSERT INTO `user` VALUES ('be079bb8ddc111eda9b20242ac110003', '周七', '成都市高新区xx街道654号'); INSERT INTO `user` VALUES ('be079bc5ddc111eda9b20242ac110003', '黄八', '武汉市江汉区xx街道234号'); INSERT INTO `user` VALUES ('be079bd4ddc111eda9b20242ac110003', '罗九', '南京市秦淮区xx路567号'); INSERT INTO `user` VALUES ('be079be2ddc111eda9b20242ac110003', '钱十', '重庆市渝北区xx街道890号'); INSERT INTO `user` VALUES ('be079befddc111eda9b20242ac110003', '周十一', '长沙市岳麓区xx路432号'); INSERT INTO `user` VALUES ('be079bfbddc111eda9b20242ac110003', '吴十二', '西安市雁塔区xx街道765号'); 涉及代码 service代码:

Python报错 UnicodeDecodeError: ‘gbk‘ codec can‘t decode bytein position 2: illegal multibyte sequence

错误的意思是:Unicode的解码(Decode)出现错误了,以gbk编码的方式去解码(该字符串变成Unicode),但是此处通过gbk的方式,却无法解码(can’t decode).''illegal multibyte sequence"的意思是非法的多字节序列,也就是说无法解码了。 出现这样的错误,可能是要处理的字符串本身不是gbk编码,却是以gbk编码去解码。 比如,字符串本身是utf-8的,但用gbk去解码,必然出错。比如有中文的存在,老老实实用 utf-8 (1)encoding=‘utf-8’ 指明打开方式 f=open(“path”,encoding=‘gbk’) (2) encoding=‘gbk’ (3) encoding=‘gb18030’ 文本中出现的一些特殊符号超出了gbk的编码范围,可以选择编码范围更广的‘gb18030’ (4)encoding=‘gb18030’,errors=‘ignore’ 可以使用‘ignore’属性忽略非法字符 或者 error_bad_lines=False 针对以上的这个问题,查阅网上资料,可以按照如下的步骤进行尝试: 原文链接1 原文链接2

Vue--如何自己实现双向数据绑定v-model ?

1. Vue 响应式实现原理 vue2响应式的原理是借助数据劫持和发布订阅者模式 1、数据劫持: 目的:能够感知到数据的改变。 数据劫持是:使用ES5的Object.defineProperty()。把data配置项中的所有数据进行遍历,转成setter和getter(或者说,给每个属性增加set和get函数)既就是:访问器属性。 2、发布订阅者模式: 目的:当数据改变时,(直接和间接)使用该数据的模板处都会有相应的改变(模板会重新渲染) Vue 3 的响应式原理基于 Proxy 对象和 Reactive API 实现 2. Vue v-model双向数据绑定实现原理 v-model 指令是 Vue 提供的一个语法糖,它可以在表单控件上双向绑定数据。 实际上,v-model 的背后是一个与组件相同的语法糖,其原理也是基于组件的通信功能。 v-model的本质是利用事件和属性的结合,例如: 1)、针对文本框(单行和多行):value属性和input事件。 如果加上修饰符 lazy。事件变成了change事件。 2)、针对radio:使用的checked属性和change事件。同时,需要给radio加上value属性。 3)、针对checkbox:使用的checked属性和change事件。 3.1)、如果应用在多选时,需要给checkbox加上value属性。 3.3)、如果应用在单选时,不需要加。 4)、针对select:使用value属性和change事件。 以下是 v-model 实现原理的详细步骤: 1. 将表单控件封装成自定义组件 通过将表单控件封装成自定义组件,我们可以使用组件的 props 和 emit 方法方便地处理数据的双向绑定。 <template> <input :value="innerValue" @input="onInput"> </template> <script> export default { name: 'MyInput', props: { value: String, }, emits: ['update:value'], data() { return { innerValue: this.value, }; }, methods: { onInput(event) { this.

分布式监控平台——Zabbix6.0

市场上常用的监控软件: 传统运维:zabbix、 Nagios云原生环境: Prometheus (go语言开发的) 一、zabbix概述 作为一个运维,需要会使用监控系统查看服务器状态以及网站流量指标,利用监控系统的数据去了解上线发布的结果,和网站的健康状态。 利用一个优秀的监控软件,我们可以: 通过一个友好的界面进行浏览整个网站所有的服务器状态可以在Web 前端方便的查看监控数据可以回溯寻找事故发生时系统的问题和报警情况 1 zabbix是什么? zabbix是一个基于Web界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。zabbix由2部分构成,zabbix server 与可选组件zabbix agent。 通过c/s 模式采集数据,通过B/s模式在web端展示和配置。zabbix server 可以通过SNMP(简单网络管理协议),zabbix agent,ping, 端口监视等方法提供对远程服务器/网络状态的监视,数据收集等功能,它 可以运行在Linux等平台上。(支持多个平台,windows也支持)zabbix agent需要安装在被监视的目标服务器上,它主要完成对硬件信息或与操作系统有关的内存,CPU等信息的收集。 2. zabbix监控原理 zabbix agent安装在被监控的主机上,zabbix agent 负责定期收集客户端本地各项数据,并发送至zabbix server 端,zabbix server收到数据后,将数据存储到数据库中,用户基于zabbix WEB可以看到数据在前端展现图像。 当zabbix 监控某个具体的项目,该项目会设置一个触发器阈值,当被监控的指标超过该触发器设定的阈值,会进行一些必要的动作,动作包括:发送信息(邮件、微信、短信)、发送命令(shell 命令、reboot、 restart、 install 等)。 用户可以基于zabbix-web可以在WEBUI界面中查看展现的数据图像,以及进行相关的配置管理用户还可以在WEBUI界面中设置监控项的触发器,如被监控的数据指标超过触发器设定的阈值,会进行发送通知信息或者一些应急操作指令。 3. zabbix常见的五个程序 zabbix监控部署在系统中,包含常见的五个程序: zabbix server、 zabbix agent、 zabbix proxy、zabbix get、zabbix sender 等。 (1) zabbix server: zabbix 服务端守护进程,其中zabbix_agent、 zabbix_ get、zabbix_sender、 zabbix_proxy的数据最终都提交给zabbix server; (2) zabbix agent: 客户端守护进程,负责收集客户端数据,例如:收集CPU负载、内存、硬盘使用情况等; (3)zabbi xproxy: zabbix分布式代理守护进程,通常大于500台主机,需要进行分布式监控架构部署;

python数据分析学习笔记—python基础知识

基本概念 1、数 在Python中有4种类型的数——整数、长整数、浮点数和复数。一般我们默认只使用整数—int;浮点数—float两种。 可以用type(object)来检测一个数是什么类型的。 type(4) <class ‘int’> 2、变量 变量就是我们想要的东西——它们的值可以变化,即你可以使用变量存储任何东西。变量只是你的计算机中存储信息的一部分内存。 在python中,变量不需要提前申明,只需要在用的时候直接给这个变量进行赋值就行。在赋值的时候支持多元赋值,比如:X,Y=3,4表示将3,4同时赋值给X,Y。 3、标识符 变量是标识符的例子。 标识符是用来标识某样东西的名字。在命名标识符的时候,你要遵循这些规则: ● 标识符的第一个字符必须是字母表中的字母(大写或小写)或者一个下划线(‘ _’)。 ● 标识符名称的其他部分可以由字母(大写或小写)、下划线(‘ _ ’)或数字(0-9)组成。 ● 标识符名称是对大小写敏感的。例如,myname和myName不是一个标识符。注意前者中的小写n和后者中的大写N。 ● 有效标识符名称的例子有:i、__my_name、name_23和a1b2_c3。 ● 无效标识符名称的例子有:2things、this is spaced out和my-name。 4、字符串(str) 字符串是由零个或多个字符组成的有限串行。下面告诉你如何在Python中使用字符串。 ● 使用单引号(') 你可以用单引号指示字符串,就如同’Quote me on this’这样。所有的空白,即空格和制表符都照原样保留。 ● 使用双引号(") 在双引号中的字符串与单引号中的字符串的使用完全相同,且在双引号中使用单引号时,单引号不表示字符串的意思,会被当做字符串内容的一部分输出。例如: ● 使用三引号(‘’‘或’‘’) 利用三引号,你可以指示一个多行的字符串。在三引号中自由的使用单引号和双引号会被当成字符串内容的一部分一起输出。例如: ● 转义符(\) (1)可以通过用’来指示单引号本身,而不是字符串的开始。例如: (2)可以用转义符\来指示反斜杠本身。 (3)可以在一个字符串的行末的单独加一个反斜杠表示字符串在下一行继续,而不是开始一个新的行。例如: ● 字符串是不可变的,一旦你创造了一个字符串,你就不能再改变它了。 ● 字符串的简单操作 (1)两字符串直接相加: (2)字符串可以赋值给变量: (3)字符串复制: (4)字符串的长度-len: (5)字符串索引: (6) 字符大小写的转换: 对于英文,有时候要用到大小写转换。在python中有下面一堆内建函数,用来实现各种类型的大小写转化: S.upper() #使S中的字母大写 S.lower() #使S中的字母小写 S.capitalize() #使S中首字母大写 S.istitle() #判断S中单词首字母是否大写的,且其它为小写, S.isupper() #判断S中的字母是否全是大写

VUE使用watch响应数据的变化

1. 直接写一个监听处理函数,当每次监听到 cityName 值发生改变时,执行函数。 new Vue({ el: '#root', data: { cityName: 'shanghai' }, watch: { cityName(newName, oldName) { // ... } } }) 也可以在所监听的数据后面直接加字符串形式的方法名: watch: { cityName: 'nameChange' // nameChange是一个方法名 } 2. immediate和handler 当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值的时候也执行函数,则就需要用到immediate属性。 比如当父组件向子组件动态传值时,子组件props首次获取到父组件传来的默认值时,也需要执行函数,此时就需要将immediate设为true。 new Vue({ el: '#root', data: { cityName: '' }, watch: { cityName: { handler(newName, oldName) { // ... }, immediate: true // immediate表示在watch中首次绑定的时候,是否执行handler } } }) 3. deep 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听。 new Vue({ el: '#root', data: { cityName: {id: 1, name: 'shanghai'} }, watch: { cityName: { handler(newName, oldName) { // .

002. java.lang.NumberFormatException: Infinite or NaN,怎么破?

你好,我是YourBatman:当我老了,也写代码;不为别的,只为爱好。 📚前言 如果你工作超5年,100%遇到过这个异常:java.lang.NumberFormatException: Infinite or NaN Infinite中文释义:极大的、无法衡量的、无穷尽的;NaN:Not a Number,不是一个数,它是计算机科学中数据类型的一种,代表不可表示的值,常用于浮点数计算中,于1985年纳入浮点数标准IEEE 754。 在 Java 中只有浮点类型(Float&Double)实现了IEEE 754标准 它还有些变种异常:阅完本文就知道这些异常本质上其实是一回事了 java.lang.NumberFormatException: For input string: NaNjava.sql.SQLException: 'NaN' is not a valid numeric or approximate numeric value ✍正文 java.lang.NumberFormatException: Infinite or NaN异常并不算常见(毕竟开发中浮点数远远没有整数使用场景多),但也绝不罕见。so,知道为何会出现此异常,以及如何解决它是每个开发者必知必会的知识点。 🌈异常哪里抛出来的? (假设你看不到异常栈)从抛出的异常中可以提取到两个关键信息供以我们查找异常源头: 异常类型:java.lang.NumberFormatException异常detail msg:Infinite or NaN 首先当然是利用Java语言强类型的优势,看看哪些地方引用到了java.lang.NumberFormatExceptionNumberFormatException: OMG,在641个地方出现过,看到这个数字该当场死心了:这条信息基本就是无效信息。 无奈再根据关键字Infinite or NaN搜索试试: 太幸运了,有且仅有一处代码里存在。看看是哪里: 破案了: java.lang.NumberFormatException: Infinite or NaN异常有且仅在构造BigDecimal实例的时候才有可能抛出。 🌈抛出此异常的原因 既然抛出此异常的源码都找到了,并且还只有一处,回答此问题就非常容易了: public BigDecimal(double val, MathContext mc) { if (Double.isInfinite(val) || Double.isNaN(val)) throw new NumberFormatException("Infinite or NaN"); .

python-自定义函数(定义调用、默认参数、返回值)

python-自定义函数 文章目录 python-自定义函数初识函数函数的定义与调用函数的定义:参数列表:函数体:函数调用 默认参数定义默认参数:默认参数的使用:默认参数的位置:默认参数为可变对象:默认参数为None:关键字参数传递: 函数返回return返回单个值:返回多个值:返回空值:返回多个值的解包:返回值作为参数传递:返回函数: 本篇文章讲解了python中自定义函数的一些知识点,包括了函数的定义和调用,默认参数,函数返回,其中也添加了比较高级的用法,能适应任何场合 初识函数 函数是什么:函数是一段可执行的代码块,用于执行特定的任务或完成特定的操作。它由函数名、参数(可选)和函数体组成。 函数的定义:函数定义是创建函数的过程,可以使用关键字def来定义函数。函数定义包括函数名和函数体,函数名用于唯一标识函数,函数体是由一系列语句组成的代码块。 函数的参数:函数可以接受零个或多个参数作为输入。参数是函数定义中用于接收外部数据的占位符,用于在函数内部进行操作和处理。 函数的返回值:函数可以返回一个或多个值作为结果。返回值是函数执行完毕后将结果返回给函数调用者的方式,可以用return语句来指定返回的值。 函数的调用:函数的调用是指在程序中使用函数来执行特定的操作。通过函数名和实际参数的组合,可以调用函数并传递相应的数据,函数将执行相应的代码逻辑并返回结果。 函数的作用:函数的主要目的是将一段可重复使用的代码逻辑封装起来,以便在程序中的不同位置多次调用。通过函数,可以实现代码的模块化,提高代码的可读性、可维护性和可重用性。 代码的模块化:函数的使用可以将程序划分为模块,每个函数负责完成特定的任务。这种模块化的组织方式使得代码更易于理解和维护,同时也便于团队合作和代码复用。 可读性和可维护性:通过将重复的代码逻辑封装在函数中,可以使程序的结构更加清晰,易于阅读和理解。当需要修改代码时,只需要修改函数内部的实现,而不必修改所有调用该函数的地方,从而提高了代码的可维护性。 重用性:通过函数的调用,可以在不同的地方复用相同的代码逻辑,避免了代码的重复编写。这样可以提高开发效率,减少代码量,同时也减少了潜在的错误和bug的出现。 函数的定义与调用 当讲解函数的定义和调用时,可以包括以下知识点: 函数的定义: 在Python中,可以使用关键字def来定义函数。函数的定义通常包括函数名、参数列表和函数体。函数名用于唯一标识函数,参数列表是函数接受的输入参数,函数体是由一系列语句组成的代码块。 def function_name(parameter1, parameter2, ...): # 函数体 # 执行特定的操作 # 可能包含一些语句和算法逻辑 参数列表: 函数可以接受零个或多个参数作为输入。参数是函数定义中用于接收外部数据的占位符。可以在参数列表中指定参数的名称,并可以为参数提供默认值。 def greet(name): print("Hello, " + name + "!") def add_numbers(x, y): print(f"你输入x={x},y={y}") 函数体: 函数体是由一系列语句组成的代码块,用于执行特定的操作或完成特定的任务。函数体中的语句可以是任何有效的Python代码。 def greet(name): print("Hello, " + name + "!") print("Welcome to our website!") def add_numbers(x, y): result = x + y print(f"结果是{result}") 函数调用 def greet(name): print("

C2360 “×××”的初始化操作由“case”标签跳过

错误如图: 错误原因: switch里面的语句属于同一范围,即case 1里面定义的变量在switch任何范围都是可以使用的,理论上case 2也可以使用case 1的变量。 但是如果变量定义在case 1里面,但是n直接等于2的话,就没有运行case 1的语句,这样的话就会导致变量还没有定义,所以会报错误! 为了防止这样的情况,我们一般有两种解决方法: 用{ }将case1整个语句括起来将变量定义在switch外面

CentOS7安装部署DM8

文章目录 DM8下载一、操作系统配置二、安装前准备检查Linux操作系统信息检查内核信息检查操作系统版本检查CPU信息检查内存信息 关闭防火墙创建用户组及用户修改文件打开最大数规划安装目录 三、数据库安装命令行安装 四、数据库实例配置命令行配置实例 五、注册服务命令行注册服务 六、启动、停止数据库命令行启停数据库 七、登录数据库命令行登录数据库 总结 DM8下载 下载链接:link 一、操作系统配置 处理器: 1个 内核: 2个 内存: 2G 硬盘: 50G 二、安装前准备 检查Linux操作系统信息 检查内核信息 uname -r 检查操作系统版本 cat /etc/redhat-release 检查CPU信息 lscpu 检查内存信息 free -h cat /proc/meminfo | grep 'Comm' 关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service systemctl status firewalld.service 创建用户组及用户 groupadd dinstall mkdir -p /home/dmdba useradd -g dinstall -m -d /home/dmdba/dm -s /bin/bash dmdba passwd dmdba 修改文件打开最大数 vi /etc/security/limits.conf ##添加以下内容 dmdba soft nofile 65536 dmdba hard nofile 65536 dmdba soft core unlimited dmdba hard core unlimited 规划安装目录 目录路径说明/opt/tmp安装包存放路径/mnt镜像文件挂载路径/home/dmdba/dm数据库安装路径/dm/dbdata/dmdata数据文件路径/dm/dbbak/dmbak数据备份路径/dm/dbarch/dmarch数据归档路径 mkdir -p /opt/tmp mkdir -p /mnt ##上传安装部署文件dm8_20230104_x86_rh6_64.

svg教程-初识svg

第一章 认识svg 简单来说: 位图:放大会失真图像边缘有锯齿;是由像素点组成;前端的 Canvas 就是位图效果。 矢量图:放大不会失真;使用 XML 描述图形。 我在 知乎 上找了一个图对说明一下。 左边是位图,右边是矢量图 那么 SVG 是什么呢?它是矢量图的其中一种格式。它是用 XML 来描述图形的。 对于初学 SVG 的前端来说,可以简单的理解为 “SVG 是一套新标签”。 所以可以使用 CSS 来设置样式,也可以使用 JS 对 SVG 进行操作。 基本使用: 可以在html中直接使用svg,< svg>< /svg>标签,不需要像canvas在js中操作。 <svg></svg> //在不给 <svg> 设置宽高时,它的默认宽度是 300px ,默认高度是 150px 。这点和 <canvas> 是一样的。 第二章 基础图形 矩形 画一个200宽,100高的矩形 svg的默认值 填充色:默认黑色 svg大小:默认宽度300px,默认高度150px <svg style="border: solid 1px red"> <rect width="200" height="100"></rect> </svg> 调整矩形位置 通过 x 和 y 可以设置矩形位置 <svg style="border: solid 1px red"

QObject类介绍

QObject特性 QObject是Qt库中最重要的类之一。作为所有Qt类的基类,QObject提供了信号槽机制、对象树、动态属性、元对象系统、事件处理机制、线程安全、国际化等许多重要特性,这些特性可以帮助开发者轻松实现模块间通信、组件化、程序设计以及事件处理等方面的功能。 在Qt框架下编程,不管用不用到Qt的特性,都推荐自定义类继承QObject类,这样在需要的时候,就可以随时使用Qt基于QObject类提供的各种特性和机制,而且可以让自定义的类很好地融入到Qt的框架之中。 具体来讲,QObject主要实现了以下特性: 1.信号槽机制:QObject通过定义信号(signal)和槽(slot)来实现对象间的通信。当信号被触发时,与该信号相对应注册的槽函数将会被自动调用。一个信号可以连接到多个槽函数上,也可以将多个信号连接到同一个槽函数。信号/槽机制是Qt中最强大和最独特的功能之一,可以帮助开发者在不同的对象之间进行通信,处理事件等。 2.对象树:QObject支持管理对象树结构的方式。它允许对象包含一个父对象和零个或多个子对象。当父对象被删除时,其所有子对象也会被自动销毁。这个特性使得我们在Qt程序中组织和管理QObject及其子类之间的依赖关系变得更容易。 3.动态属性:QObject支持添加动态属性。这意味着,除了一组已经存在的静态属性之外,每个对象实例还可以动态地创建和设置新的属性,这些属性不需要在编译器层面进行定义和声明。这种灵活性使得QObject能够适应各种场景的需求。 4.元对象系统:元对象系统(Meta-Object System)是QObject的另一个重要特性。它为每个QObject和其子类提供运行时类型信息,包括对象的类名、属性、方法和信号等信息,这些信息都可以在运行时被访问或者修改。元对象系统赋予了Qt框架独特的能力,例如能够自动序列化和反序列化对象以及其成员等,同时也是实现Qt信号槽机制的关键技术。 5.事件处理机制:QObject支持通过发送和接收事件来实现对象间的通信。Qt中的事件是指某种对象发生的一些动作或状态变化,通常包含一个事件类型和一些参数。QObject可以捕获并处理各种类型的事件,也可以派发(dispatch)事件给其他对象进行处理。 6.线程安全:QObject被设计为线程安全的基础构建单元。这意味着QObject默认可以在多线程环境下直接使用,而无需考虑同步问题。但是,如果需要在不同线程之间交互对象,还是需要小心地设计和管理线程模型。 7.国际化:QObject提供国际化(Internationalization / i18n)函数,帮助开发人员使应用程序能够方便地本地化,支持多语言切换。i18n函数提供消息翻译,日期和时间格式化以及数字格式转换等功能。 QObject 类接口 QObject 类是 Qt 里的基础类,其接口非常丰富。下面是其中一些重要的接口及其作用: objectName() 和 setObjectName(): 分别用于获取和设置对象名称,在使用 Qt 的 GUI 编程时非常常用。因为 QObject 实例可以被组织成一个树形结构,有了名称,就能方便地在整个对象树中查找和通信。 parent() 和 setParent(): 分别用于获取和设置父对象。当子对象的父对象被删除时,子对象也会自动地被删除,这是通过 Qt 手工管理的内存分配方式实现的。 signals: 槽函数用于连接到信号(即事件),并且能够传递参数。这样,当发生某个信号时,与之相连的槽函数就会被执行。 slots: 响应事件的函数,与 signal 配对使用。它们的作用是接受来自信号所触发的数据,并采取相应的操作。 event():主要是消息处理函数,用于处理事件。每个 QObject 有一个事件队列(Event Queue), 所有从活动线程(postEvent)或当前线程(sendEvent)发送的事件都会加入此队列,而所有的来自应用程序或窗口系统的事件最终都通过此函数进行分发处理。 startTimer() 和 killTimer(): 利用定时器(Timer)实现定期执行一些操作。startTimer()的返回值是一个计时器 ID,可以通过 killTimer() 取消某个定时器。 moveToThread(): 使用移动机制在其他线程中执行某段代码。简单来说就是将 QObject 对象转移到新的线程中,并与新线程事件循环相关联。 metaObject():获取QObject类的元对象,即QMetaObject类型的对象,用于获取该类的信号、槽、属性等元信息。 deleteLater():延迟删除 QObject,它大多数情况下会被应用于子对象。此函数会在当前调用栈上添加到事件队列中。 blockSignals(bool block):控制所发布信号的阻塞和非阻塞状态。当参数为true时,意味着所有接收对象(期望使用该信号作为输入)将不再收到这个信号。 dumpObjectInfo()/dumpObjectTree(): 输出列表格式,对象及其父级或子级名称、地址等,便于debug。 QObject头文件 由于QObject类过于重要,因此将其头文件列于此,方便隔三差五地复习一下。QObject用得好,可以做很多需要运行时动态处理的工作,大大地提高程序的灵活性。 class Q_CORE_EXPORT QObject { Q_OBJECT Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged) Q_DECLARE_PRIVATE(QObject) public: Q_INVOKABLE explicit QObject(QObject *parent=nullptr); virtual ~QObject(); virtual bool event(QEvent *event); virtual bool eventFilter(QObject *watched, QEvent *event); #if defined(QT_NO_TRANSLATION) || defined(Q_CLANG_QDOC) static QString tr(const char *sourceText, const char * = nullptr, int = -1) { return QString::fromUtf8(sourceText); } #if QT_DEPRECATED_SINCE(5, 0) QT_DEPRECATED static QString trUtf8(const char *sourceText, const char * = nullptr, int = -1) { return QString::fromUtf8(sourceText); } #endif #endif //QT_NO_TRANSLATION QString objectName() const; void setObjectName(const QString &name); inline bool isWidgetType() const { return d_ptr->isWidget; } inline bool isWindowType() const { return d_ptr->isWindow; } inline bool signalsBlocked() const noexcept { return d_ptr->blockSig; } bool blockSignals(bool b) noexcept; QThread *thread() const; void moveToThread(QThread *thread); int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer); #if __has_include(<chrono>) Q_ALWAYS_INLINE int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer) { return startTimer(int(time.

chatgpt赋能python:Python中的取除数函数:divmod()

Python中的取除数函数:divmod() Python是一种常用的编程语言,也是一种高级语言。它可以帮助开发人员轻松地解决问题。Python中的divmod()方法可以帮助开发人员取得商和余数。下面是有关Python divmod()函数的详细介绍。 什么是divmod()函数? divmod()是Python中的一个内置函数,用于取得两个数字的商和余数。函数divmod(a, b),其中a和b是数字参数。该函数将a与b进行除法运算,返回两个数值:第一个是商,第二个是余数。它返回一个元组,第一个值是商,第二个值是余数。 语法 divmod()函数的语法如下: divmod(a, b) 其中,a和b是两个要进行除法运算的数字。 示例 下面是一个示例,演示如何使用Python的divmod()函数: a = 10 b = 3 x, y = divmod(a, b) print("商:", x) print("余数:", y) 运行结果: 商: 3 余数: 1 适用场景 Python的divmod()函数通常用于那些需要的商和余数的计算中。在一些问题中,需要同时计算商和余数,然后继续使用这些计算结果。 结论 Python中的divmod()函数是一个非常有用的函数,用于取得两个数字的商和余数。它可以帮助开发人员在他们的代码中更轻松地完成这个任务。不仅如此,divmod()还可以提高代码的效率,使代码更容易维护。如果您在Python开发中需要计算商和余数,那么divmod()就是您需要使用的函数之一。 最后的最后 本文由chatgpt生成,文章没有在chatgpt生成的基础上进行任何的修改。以上只是chatgpt能力的冰山一角。作为通用的Aigc大模型,只是展现它原本的实力。 对于颠覆工作方式的ChatGPT,应该选择拥抱而不是抗拒,未来属于“会用”AI的人。 🧡AI职场汇报智能办公文案写作效率提升教程 🧡 专注于AI+职场+办公方向。 下图是课程的整体大纲 下图是AI职场汇报智能办公文案写作效率提升教程中用到的ai工具 🚀 优质教程分享 🚀 🎄可以学习更多的关于人工只能/Python的相关内容哦!直接点击下面颜色字体就可以跳转啦! 学习路线指引(点击解锁)知识定位人群定位🧡 AI职场汇报智能办公文案写作效率提升教程 🧡进阶级本课程是AI+职场+办公的完美结合,通过ChatGPT文本创作,一键生成办公文案,结合AI智能写作,轻松搞定多场景文案写作。智能美化PPT,用AI为职场汇报加速。AI神器联动,十倍提升视频创作效率💛Python量化交易实战 💛入门级手把手带你打造一个易扩展、更安全、效率更高的量化交易系统🧡 Python实战微信订餐小程序 🧡进阶级本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。

利用引用计数对C++对象进行管理

利用引用计数对C++对象进行管理 引用计数(reference count)是这样一个技巧,它允许有多个相同值的对象共享这个值的实现。 在引用计数中,每一个对象负责维护对象所有引用的计数值。当一个新的引用指向对象时,引用计数器就递增,当去掉一个引用时,引用计数就递减。当引用计数到零时,该对象就将释放占有的资源。 引用计数的使用常有两个目的: 一旦一个对象通过调用new被分配出来,记录谁拥有这个对象是很重要的,因为其所有者要负责对它进行delete。但是对象所有者可以有多个,且所有权能够被传递,这就使得内存跟踪变得困难。引用计数可以跟踪对象所有权,并能够自动销毁对象。节省内存,提高程序运行效率。如何很多对象有相同的值,为这多个相同的值存储多个副本是很浪费空间的,所以最好做法是让左右对象都共享同一个值的实现。 下面是一个简单的使用引用计数实现C++对象间共享的示例代码: class RefCounted { public: void addRef() { ++refCount_; } void releaseRef() { --refCount_; if (refCount_ == 0) { delete this; } } protected: RefCounted() : refCount_(0) {} virtual ~RefCounted() {} private: int refCount_; }; class Foo : public RefCounted { public: Foo(int value) : value_(value) {} int getValue() const { return value_; } void setValue(int value) { value_ = value; } private: int value_; }; void test() { // 创建Foo对象 Foo* foo = new Foo(42); // 创建两个指向Foo对象的引用 foo->addRef(); Foo* anotherFoo = foo; anotherFoo->addRef(); // 输出Foo对象的值 std::cout << "

08.Stack和Queue

栈:先进后出 队列:先进先出 JVM的栈就是平常所说的一块内存。 此处所说的栈是数据结构 1. 栈(Stack) 1.1 概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈:栈的删除操作叫做出栈。出数据在栈顶。 1.2 栈的使用 方法功能Stack()构造一个空的栈E push(E e)将e入栈,并返回eE pop()将栈顶元素出栈并返回E peek()获取栈顶元素(只是看看栈顶,并不删除)int size()获取栈中有效元素个数boolean empty()检测栈是否为空 public static void main(String[] args) { Stack<Integer> s = new Stack(); s.push(1); s.push(2); s.push(3); s.push(4); System.out.println(s.size()); // 获取栈中有效元素个数---> 4 System.out.println(s.peek()); // 获取栈顶元素---> 4 s.pop(); // 4出栈,栈中剩余1 2 3,栈顶元素为3 System.out.println(s.pop()); // 3出栈,栈中剩余1 2 栈顶元素为3 if(s.empty()){ System.out.println("栈空"); }else{ System.out.println(s.size()); } } 1.3 栈的模拟实现 import StackEmptyException.StackEmptyException; import java.util.Arrays; public class MyStack { private int[] elem; private int usedSize; public MyStack() { this.

深度学习AI编译器-TVM简介

1.为什么需要深度学习编译器 深度学习编译器主要为解决不同框架下训练的模型 部署到指定的某些设备上时所遇到的一系列复杂的问题,即将各种深度学习训练框架的模型 部署到各种硬件所面临的问题; 首先深度学习领域,从训练框架看,当前可选的框架有pytorch、TensorFlow、Mxnet、paddle,oneflow、caffe/caffe2、mindspore等,具体选择哪个,不尽相同,但如果项目要部署落地,则面临很多问题,即从推理框架角度来看,无论我们选择何种训练框架训练模型,我们最终都是要将训练好的模型部署到实际场景的,在模型部署的时候我们会发现我们要部署的设备可能是五花八门的,例如Intel CPU/Nvidia GPU/Intel GPU/Arm CPU/Arm GPU/FPGA/NPU(华为海思)/BPU(地平线)/MLU(寒武纪),如果我们要手写一个用于推理的框架在所有可能部署的设备上都达到良好的性能并且易于使用是一件非常困难的事。 为了解决上面的问题,科学家为编译器抽象出了编译器前端,编译器中端,编译器后端等概念,并引入IR (Intermediate Representation)的概念。解释如下: 编译器前端:接收C/C++/Java等不同语言,进行代码生成,吐出IR 编译器中端:接收IR,进行不同编译器后端可以共享的优化,如常量替换,死代码消除,循环优化等,吐出优化后的IR 编译器后端:接收优化后的IR,进行不同硬件的平台相关优化与硬件指令生成,吐出目标文件 因此我们可以将各个深度学习框架训练出来的模型看做各种编程语言,传入深度学习编译器,之后吐出IR,由于深度学习的IR其实就是计算图,所以可以叫做Graph IR,针对这些Graph IR可以做一些计算图优化在吐出IR分发给各种硬件使用,这样就解决了上述很多繁琐的问题,如下图所示: 深度学习编译器VS传统编译器 图中与传统编译系统进行了对比,发现存在相似之处:如都有中间表示、前端和后端分别硬件无关优化和硬件相关优化以及最后的代码生成模块; 同时也有一定的区别:深度学习编译系统是针对神经网络这一特定领域的编译系统,采用了以Python为主的动态解释器语言的前端、多层IR(如图层/算子层/codegen)设计、以及面向神经网络的特定优化(如自动微分、量化/混合精度、大规模并行、张量运算、循环优化等)。 深度学习编译器的架构 前端:将现有深度学习框架中的深度学习模型作为输入,然后将模型转换为计算图表示。前端需要实现各种框架不同格式的转换,并进行了结合了通用编译系统的优化技术和深度学习特定的优化技术的硬件无关的计算图优化,优化图逻辑,减少了冗余,提高了图IR的效率。计算图优化包括代数简化、算子融合、算子下沉、CSE公共子表达式消除、DCE死代码消除、静态内存规划和布局转换等。在前端之后,将生成优化的计算图并将其传递到后端。 中间表示IR:分布在前端和后端,是介于源语言和目标语言之间的程序表示,能够极大程度地提高编译流程的可拓展性,同时也能降低优化流程对前端和后端的破坏 后端:将高级IR转换为低级IR,并执行特定于硬件的计算图优化、算子选择以及内存分配这三个任务。计算图优化是在不影响模型的数值特性的基础上,通过图变换达到减少资源开销、适配硬件的执行能力、提升执行性能的目的。例如与硬件无关的算子内存 IO 优化和为了适配特定硬件指令限制而做的子图变换。数据存在多种存储格式和计算精度,不同的存储格式和计算精度在不同场景下对算子计算性能有较大的影响,算子选择是为 IR 图中的每个计算节点选择一个最适合在设备上执行的算子。经过计算图优化和算子选择以及常用的特定于硬件的优化包括硬件内部映射、内存分配和获取、内存延迟隐藏、并行化以及面向循环的优化后。使用JIT或AOT编译优化的低级IR,以生成不同硬件目标的代码,运行时要实现算子选择和内存分配等技术。 深度学习编译系统整体架构图 此外,对应深度学习工作流,完整的深度学习编译框架还包括:编程接口、硬件加速器、数据处理、模型部署、分布式训练等模块。深度学习编译系统以加速器为核心,硬件加速器模块提供丰富的编程接口;数据处理模块负责数据的读取、存储以及预处理;分布式训练模块为应对单个机器上内存及算力资源不足,并行加速模型训练的过程;模型部署模块负责进行模型压缩、针对推理硬件平台模型算子优化、进行模型混淆设计保证模型安全等。 中间表示 网络模型传递给编译系统后会被转成IR,深度学习编译系统中IR的设计需要考虑:正确处理张量数据类型;自动微分实现的简洁性、性能以及微分的扩展能力;支持静态图和动态图,可以针对任务需求灵活选择合适的模型;支持高阶函数和闭包,以抽象通用问题、减少重复代码;编译优化;JIT及时编译能力等因素。 常采用多级IR的设计方法将前后解耦,常见的一种设计是分为High-Level IR,Low-Level IR以及代码生成时用到的LLVM IR,如图所示: High-Level IR :也称为图形IR,表示计算和控制流,与硬件无关。高级IR的目标是在操作符和数据之间建立控制流和依赖关系,并为图形级优化提供接口,进行常数折叠、代数化简、公共子表达式、Layout转换、算子融合、优化图逻辑等优化。 Low-Level IR:用于针对不同硬件目标的特定于硬件的优化和代码生成。因此,低级别IR应该足够细粒度以反映硬件特性并表示特定于硬件的优化,如算子选择、循环变换、循环切分,与硬件intrinsic映射、内存分配等后端pass优化。 深度学习编译系统中的IR设计趋势 深度学习的计算任务的特点是比较结构化,即控制依赖相对较少;且数据以张量为主,访问比较有规律。从图中可以看到深度学习编译系统的IR设计的其中一种变化趋势是变得越来越“厚”,即层数越来越多。这些不同层次间的IR之间一般通过progressive lowering可以从高层到低层进行转化。就像接力一样,每一层抽象上处理本层适合干的事,然后将变换后的IR往下层丢。另一方面,如MLIR也变得越来越灵活和开放 前端 深度学习编译系统的起点是将网络模型转换为图IR,首先介绍前端中的计算图。 计算图: 用来表示深度学习网络模型在训练与推理过程中计算逻辑与状态的工具,由张量Tensor、算子Operator以及有向线段表示的张量状态、依赖关系构成。用于对输入数据、算子和算子执行顺序进行统一表达;定义中间状态和模型状态,从而帮助框架更好地管理内存;自动化分析模型定义、在自动微分过程中计算梯度;分析算子执行关系,发现将算子进行异步执行的机会,从而优化程序执行 目前主流的深度学习框架的执行模式有两种,分别为静态图模式和动态图模式。 静态图模式下,程序在编译执行时先生成神经网络的图结构,然后再执行图中涉及的计算操作。因此,在静态图模式下,编译器利用图优化等技术对执行图进行更大程度的优化,从而获得更好的执行性能,有助于规模部署和跨平台运行,包括以下两种实现方式: Tracing模式:框架把Python假执行一遍,记录算子执行序列作为正向图,并以此进行自动微分生成反向图,然后进行正反向图的编译优化 AST转换:框架获取Python代码的AST,通过编译技术转换成正向图,基于正向图生成反向图,同时进行编译优化 动态图模式下,程序采用解析式的执行方式,编译与执行同时发生,采用前端语言自身的解释器对代码进行解析,利用计算框架本身的算子分发功能,按照计算依赖关系进行调度执行,动态生成临时的图拓扑结构。计算框架依照算子调度顺序记录参与反向计算的算子与张量。当前向计算执行完毕,计算框架根据动态生成的前向计算图结构拓扑关系,利用记录的反向计算算子和张量动态生成反向计算图,最终完成神经网络模型的梯度计算与参数更新,更加节省内存占用,同时方便用户编写和调试神经网络模型。 目前,深度学习编译系统中均动静态图两种模式,并逐步呈现由动静分离到动静融合再到动静统一的趋势,动静融合中的动静态图转换的技术常见于模型部署阶段,当动态图模式训练完成模型参数后,可以将整体网络结构转换为静态图格式,将神经网络模型和参数文件进行序列化保存,与前端代码完全解耦,扩大模型部署的硬件支持范围;动静统一具体是指静态图可以支持尽量多的动态图语法,同时使得静态图提供接近动态图的语法使用体验。 生成计算图IR之后,为了有效减少程序在运行时可能出现的错误,编译系统的前端引入了类型系统(Type System)和静态分析(Static Analysis)系统。 类型系统是类型的集合以及使用类型来规定程序行为的规则,用于定义不同的类型、指定类型的操作和类型之间的相互作用,可以防止程序在运行时发生类型错误, 静态分析是指在不实际运行程序的情况下,通过词法分析、语法分析、控制流、数据流分析等技术对代码进行分析验证的技术,能够为编译优化提供线索和信息,有效减少代码中存在的结构性错误、安全漏洞等问题。在编译系统前端的编译过程中,静态分析可能会被执行多次,有些框架还会通过静态分析的结果判断是否终止编译优化。 此外,还进行与传统编译系统通用的常见硬件无关优化:代数简化、CSE公共子表达式消除、DCE死代码消除、静态内存规划和布局转换等。 微分求解通常有手动求解、数值微分、符号微分以及自动微分几种方法。 手动求解法:求解出梯度公式,然后编写代码,代入实际数值得出真实的梯度。但每次修改算法模型都需要修改对应的梯度求解算法。 数值微分法:根据导数的原始定义 ,当h取很小的值时,用户就能根据给出的目标函数和要求解的变量就可以方便地自动给出相应的梯度。但计算量大。 符号微分法:使用代数软件实现一些公式,然后对用户提供的具有闭包形式的数学表达式进行自动微分求解。但会存在表达式膨胀问题,即可能会使得问题符号微分求解的表达式急剧膨胀,导致最终求解速度变慢。 自动微分法是一种介于符号微分和数值微分的方法,将符号微分法应用于最基本的算子(常数、幂函数、指数函数、对数函数、三角函数等),然后代入数值保存中间结果,最后再应用于整个函数。 深度学习编译系统中为何需要自动微分?

SSM整合中的配置详情

目录 所需配置文件: 1、web.xml 2、springmvc-config.xml springmvc核心配置文件 3、applicationContext.xml spring核心配置文件 4、mybatis-config.xml mybatis的核心配置文件 5、db.properties 数据库连接信息 6、log4j.properties 日志文件 具体案例: 1、web.xml 2、springmvc-config.xml springmvc核心配置文件 3、applicationContext.xml spring核心配置文件 4、mybatis-config.xml mybatis的核心配置文件 5、db.properties 数据库连接信息 6、log4j.properties 日志文件 所需配置文件: 1、web.xml (1)配置前端控制器dispatcherServlet (2)配置spring监听器(必须配置) (3)配置编码过滤器(为了避免中文乱码问题) 2、springmvc-config.xml springmvc核心配置文件 (1)配置视图解析器 (2)配置注解驱动(必须配置) (3)配置拦截器 (4)开启controller注解 (5)放行静态资源文件 3、applicationContext.xml spring核心配置文件 (1)读取db.properties (2)配置数据源 (3)配置事务管理器 (4)开启事务注解 (5)配置mybatis工厂 (6)配置mapper基于接口开发 (7)开启service层的注解 4、mybatis-config.xml mybatis的核心配置文件 (1)设置别名 5、db.properties 数据库连接信息 6、log4j.properties 日志文件 具体案例: 1、web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--配置前端控制器--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-config.

c++学习笔记(8)继承

目录 继承 基本语法 继承方式 继承中构造和析构顺序 继承同名成员处理方式: 继承同名静态成员处理方式 多继承语法 菱形继承 继承 基本语法 面向对象三大特性之一 一些类除了有上级别类的共性之外,还有自己的特性 可以利用继承,减少重复代码 语法: class 子类 : 继承方式 父类 class Python :public BasePage 子类:派生类 父类:基类 #include<iostream> using namespace std; #include <string> //模拟网页 class BasePage { public: void header() { cout << "公共头部" << endl; } void footer() { cout << "公共底部" << endl; } }; //Java页面 class Java :public BasePage { public: void content() { cout << "java学科内容" << endl; } }; class Python :public BasePage { public: void content() { cout << "

markdown编辑器

文章目录 ✅ 当前markdown方案2023.5.292023.5.25 🌈 milkdown及其他类似的编辑器引入关于milkdown其他 😂 伤心的typora(美化typora,主题)1.1 如何使用新主题1.2 一些比较好看的主题blubook主题orange-heart主题Gitbook主题(包含三种颜色样式)Mint主题(支持暗色模式)Notion主题(也是三种颜色模式) 1.3. 自定义主题 ✅ 当前markdown方案 2023.5.29 masOS的笔记软件(不是个单纯的markdown编辑器),有导航栏的文件目录结构 https://github.com/glushchenko/fsnotes 2023.5.25 其实如果是macos的话,其实可以直接在APP里搜索 markdown, 我现在用的是One Markdown,不是所见即所得显示,但是有目录,可以直接粘贴图像(存到提示让你选择的目录里)软件大小也很小,启动速度很快,主题需要额外付费才行,但是默认这个主题已经很不错了 尝试了以下内容: sublimeText+markdown插件macdown编辑器vscode+插件 当前的解决方案: 预览上,使用macdown编辑器,轻量级,打开快,默认双栏,UI界面美观度还可以编辑上,使用vscode+Markdown Paste插件,vscode打开稍微有点慢,重了些;这个插件就是直接粘贴图像会帮你保存到一个默认位置。就是我找了好久想要的功能,哈哈哈;marktext很丑,typora。。 🌈 milkdown及其他类似的编辑器 结论: 看了一圈,算了,还是不折腾这种npm前端的包了,老老实实用vscode+插件吧,也不要什么WYSIWYG了,有兴趣和前端基础的可以去折腾一下 引入 稀里糊涂发现在vscode的markdown文件右击,可以看到Milkdown这个东西,也就是说:VScode的markdown功能实现是使用的Milkdown插件。 关于milkdown Milkdown是一个所见即所得的Markdown编辑器,基于prosemirror和remark构建,完全开源,可以运行在浏览器和electron中。类似开源可自由扩展的Typora。适用于需要混合富文本和Markdown的使用场景,例如需要使用markdown作为存储但需兼顾不熟悉markdown的用户。或喜欢所见即所得的编辑模式的用户。入门开发者可以学习到如何使用prosemirror来开发富文本编辑器,以及如何设计一个针对编辑器的插件系统。不同于其它Markdown编辑器,Milkdown是插件驱动的,因此用户可以根据自己的需要定制编辑器的能力,例如扩展特有的markdown语法,渲染特殊节点,定制主题。 参考: 自荐项目 | Milkdown #1803V2EX( way to explore)-Milkdown 中文文档,有项目主要作者的回答,有什么好用的轻量级的Markdown编辑器吗?,从这个回答来看,markdown编辑器基本都是前端的人写的掘金社区:呀!这款markdown编辑器我太钟意啦!任由文字肆意流淌,更自由的开源 Markdown 编辑器 其他 除了这个milkdown,其实还有很多类似的前端(基于JavaScript或者Typescript的)写的markdown编辑器,基本都是基于vue或者react框架的,对于前端小白来说,不是很能快速上手。同类型的还有: Github-pandao/editor.md 主页:https://pandao.github.io/editor.md/ 还有vditor 介绍主页:https://b3log.org/vditor/demo/index.html 另外,值得一提的是,名气比较大的思源笔记,就是基于这个vditor做的, 以前叫链滴笔记现在就是:思源笔记-github-siyuan-note/siyuan思源笔记官网:https://b3log.org/siyuan/思源笔记是付费的,和obsidian差不多,都是构建个人知识管理系统也可以看看这个:Vditor的开发痛点思考——“vditor 目前是作为思源笔记的底层实现存在,所以对思源笔记的修复支持是首位的 ” 所以这些笔记软件,最终都会从开发版本变成一个成熟的软件,付费版本,也没什么问题。milkdown的作者也说这个可能会变成一个独立的软件补充一个,常见的WYSIWYG指的是 所见即所得,what you see is what you get,类似word这样的编辑器就是的 参考:最适合程序员的笔记软件-阮一峰 😂 伤心的typora(美化typora,主题) 进入typora的主题网页:https://theme.typora.io,如果打不开请考虑科学上网。不能科学上网的也没关系,我下面会放一些主题的图片,自行选择。 注意,这些主题并不一定经过完全的测试,可能导出pdf会有问题,可能显示会有问题,请自行斟酌/修改使用 我最后选择的是 orange-heart主题

Lombok @Data注解趟坑计

1、背景描述 开发过程中大家创建对象或者通过MyBatis插件自动反转生成实体类的时候,可能经常会使用Lombok的注解,Lombok是一个很优秀的Java库,简单的几个注解,可以干掉一大片的模版代码,比如@Data注解,可以减少很多get set方法,使代码看起来更加优雅,但是这个注解在有些情况下会有坑,我们在使用过程中还是要慎用,接下来,我会通过一个例子来复现这个坑 前段时间在做一个需求,背景是一个包裹装了多个商品的情况,测试反馈在出库的时候报错了,第一反应就是去看出库相关的代码,发现都是一年前的代码,然后就去查数据库,发现包裹关联的数据没有对应的出库单明细,想来肯定是生成包裹的时候,更新的数据不对,然后去看拣货下架的代码,发现也都是一年前的代码,感觉十分诡异,然后在测试环境加了很多日志,抓取日志报文后,一通debug,最后发现是Lombok @Data注解的坑 2、这个坑是什么呢? 子类对象如果只添加了@Data注解的时候,会自动重写hashCode() equals() toString()方法方法,且这些方法不关注父对象属性,多个子类对象,如果只有父类属性有值,计算出来的hash值会相同,如果有使用hashCode() equals()的地方,可能会有问题。 3、问题复现 创建父类Person @Data public class Person { private Integer id; private String name; private String sex; } 创建子类Student,手写get set方法 public class Student extends Person { private String school; private Integer grade; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public Integer getGrade() { return grade; } public void setGrade(Integer grade) { this.

AutoSAR软件架构基础(一)

文章目录 AutoSAR简介与展望基本概念历史进程AutoSAR构成背景软件系统架构图AutoSAR软件架构分层简介实时运行环境层(RTE)微控制器抽象层(Microcontroller Abstraction Layer)ECU抽象层(ECU Abstraction Layer)复杂的驱动程序(Complex Drivers)服务层(Service Layer) AutoSAR软件开发AutoSAR基本实现方式概要图 总结 AutoSAR简介与展望 随着汽车ECU控制器的逐步发展,汽车电子领域需求也日益复杂,在这一环境之下,整车厂和 零部件制造商均不得不考 虑软件重复性,可裁剪性,质量保证等等问题,AutoSAR便是基于这些种种要求,由几大零部件提供商和主机厂联合提 出的要求。统一解决方案针对问题。 挑战:E/E系统复杂度快速增加目标:重复使用、不断测试功能代码爆炸式增长提高软件质量,降低开发成本硬件平台种类增多重复使用功能层软件开发流程和文件格式未统一重复使用基础层软件汽车电子系统设计复杂化造成的可靠性隐患,导致汽车因安全隐患被“召回”的现象频繁发生重复使用开发方法论和开发工具规范汽车电子产品,软件和元器件的互通性 基本概念 AutoSAR是AUTomotive Open System Architecture的缩写,是由整车制造商、供应商、服务 提供商以及来自汽车电子、半导体和软件行业的公司共同组成的世界范围内的汽车电子软件联 盟。AutoSar是一种软件系统架构,它从汽车ECU控制器角度带来了一整套系统软件解决方案, 它提供了一套标准化的接口和通信协议,使不同的软件组件可以相互协作。AutoSAR软件架构 有众多的优越性。下图是汽车有无AutoSAR架构的对比,“Yesterday”是指在使用AutoSar架构 之前的软件系统架构,也就是说,在AutoSAR诞生早期,便已经存在汽车软件系统架构,例 如OSEK,OSEK/VDX也基于分层架构的软件平台。 只是,AutoSAR从整个软件汽车的平台化、统一化着眼,方法论也涵盖了整个ECU统一开发、统一流程的各个开发环节。可以说OSEK就是AutoSAR,比如AutoSAR使用的OS部分就是OSEK操作系统。主要区别在于,OSEK是一个操作系统标准,而AutoSAR是一个软件架构标准,以及由于基于嵌入式系统,OSEK的实现通常比较底层,而AutoSAR是实现通常是比较高层的。在此处我们主要需要清楚AutoSAR通过交互文档可以方便实现OEM与TIL1之间的软件统一设计、开发与交互;而OSEK只能通过 one by one的设计方式去独立开发单控制器,更是无法实现SWC层级的软件复用。种种结构均表明AutoSAR凸显出的不仅仅是一个简单的软件架构所具备的优越性。 ​ 关于OSEK和AUTOSAR的更多信息,请参考以下链接: OSEK标准AUTOSAR标准 历史进程 2003成立 2005发布第一个AutoSAR标准; 2006年完成基础软件定义; 2013年AutoSAR成立10年,发布4.1.1 2014年发布4.3.0,加入面向服务的通讯协议,包括Extended Buffer Access forRapid Prototyping;SOME/IP Transport Protocal Decentralized Configuration 2017年发布v4.3.1 2018年发布v4.4,是当前最新版本。 AutoSAR构成背景 本次介绍的重点仍然是AutoSAR软件架构,因为在目前的主机厂环境之中主要使用Autosar架构独立开发自己的控制器,还未涉及从公司层面按照软件开发方式设计软件全功能的模式,毕竟这是一个消耗成本的事情,这个话题就不再阐述。Autosar软件架构作为分层式软件架构,具有其相关的所有目标和设计优势。在IOS26262中专门有对待软件的要求。 一般而言,软件架构设计要达到如下的目标: 可靠性(Reliable) 软件系统对于用户的商业经营和管理来说极为重要,因此软件系统必须非常可靠。 安全性(Secure) 软件系统所承担的系统安全性非常重要。 可扩展性(Extensible) 在新技术出现的时候,一个软件系统应当允许导入新技术,从而对现有系统进行功能和性能的扩展。例如,在AUTOsar中有复杂驱动这一层,这样就保证了整个系统的灵活度和可扩展性。 可维护性(Maintainable) 客户体验(Customer Experience) 软件系统必须易于使用。 市场时间(Time to Market) 软件用户要面临同行竞争,软件提供商也要面临同行竞争。以最快的速度争夺市场先机非常重要。例如AutoSAR在当前的市场大环境下被广泛采用在新能源汽车,自动驾驶领域的控制器,控制器开发就足以说明采用AutoSAR架构所带来的商业上的时机在一个新兴领域被大家认可。 软件系统架构图 下面来看架构图:

单体项目偶遇并发漏洞!短短一夜时间竟让老板蒸发197.83元!

引言 事先声明:以下故事基于真实事件而改编,如有雷同,纯属巧合~ 眼下这位正襟危坐的男子,名为小竹,他正是本次事件的主人公,也即将成为熊猫集团的被告,嗯?这究竟怎么一回事?欲知内幕如何,且听下回分解……,啊不对,欲知内幕如何,还需将时间拨回三周之前… 哒、哒、哒,那是高跟鞋接触地板发出的碰撞声,而此时慵懒瘫坐在工位上的小竹浑然不知,身后有着一位女子正在快速接近,只见此女身穿黑丝色职业装,定睛一看,原来正是熊猫集团董事长的千金! 一声呼喊突然打破了正在悠哉游哉般摸鱼的小竹: 小竹小竹,这里有个紧急的商城项目,你快来搞一下,三周后要上线! 一个完整项目,三周时间就要上线!!怎么办?为了按期交付出产品,小竹遵循着“能跑就行”的原则,动用了他的CV大法,平均日码3W行!不到三周时间,小型商城项目快速完工。 需求验收时,小竹发现每点一个功能,浏览器都要转半分钟圈圈,此时客户的眉头紧皱,小竹见状急忙开口道: 王总,虽然看着慢了点,可又不是不能用!三周时间还要啥自行车,你说是吧? 于是就这样,产品在客户的万般不满下顺利交付,小竹还贴心的送上了“上线部署”一条龙服务。 视角拉回三周后的今天…… 王总再次来到了公司,并站在小竹身前大声质问道:“昨晚这事必须得给我一个解释!否则你等着被我起诉吧!” 嗯?具体咋回事?哦~,原来是上线的商城项目,突然遇到了并发,导致王总损失197.83元! 咳咳,看到这里,不是Java开发的看官可以撤了,后续内容已经雨女无瓜~ PS:个人编写的《技术人求职指南》小册已完结,其中从技术总结开始,到制定期望、技术突击、简历优化、面试准备、面试技巧、谈薪技巧、面试复盘、选Offer方法、新人入职、进阶提升、职业规划、技术管理、涨薪跳槽、仲裁赔偿、副业兼职……,为大家打造了一套“从求职到跳槽”的一条龙服务,同时也为诸位准备了七折优惠码:3DoleNaE,感兴趣的小伙伴可以点击:https://s.juejin.cn/ds/USoa2R3/了解详情! OK,下面开始本文的正式内容,看完如果有所收获,请记得点赞、收藏、关注三连支持一下噢~ 一、真实事件的来龙去脉 开局我提到一句话,上述故事基于真实事件改编,其实具体情况和故事差不多,这是来自于一位在微信找我解决Bug的读者,为了方便称呼,这里我们将其化名为:小帅。 小帅是一位工作近三年的全栈开发,任职于一家小的项目型外包公司,平时工作就是负责开发Boss从外部承接过来的项目,由于近期项目过多,所以CV大法用上头了,写代码的技巧只有一个:梭哈! 正因如此,给某位客户写的项目突然遇到了并发,造成做项目的老板出现损失,先来看问题: 做的是个商城类型的项目,但平台内所有的交易,没有直接对接支付渠道,而是设计了“平台币”这种形式。用户可以通过常用支付渠道充值“平台币”,接着可以用“平台币”购买商品;同时,为了资金的合理性,“平台币”也可以反向提现,如提现到微信、支付宝、银行卡。 PS:实际项目中,现金和平台币的比率并非1:1,下面为了便于说明,我们假设为1:1。 所以目前的交易种类,总共有“下单、提现”这两种(实际还有其他种类,这里不展开),数据库里也有几张关于交易的表,最核心的是有张账户表,省略其他业务字段如下: 账户表:{账户ID、账户名、账户余额} 此时问题来了,由于是接过来的小项目,开发时的第一准则追求的是:速度,只要需求能实现,质量、安全啥的都不重要,所以“小帅”在开发项目时,结合MVC思想与三层架构模型,将整个项目分为了: 数据层:就是mapper/dao包,提供操作数据库表的接口;业务层:基于数据层的接口,结合实际业务,实现业务方法;表现层:调用业务层的方法,对外提供可访问的网络接口。 这个结构相信大家应该再熟悉不过了,接着小帅在业务层写了“提现、下单”两个方法,如下: // --------------数据层--------------- public interface AccountMapper { // 修改账户表的接口 int update(Account account); // 根据账户名查询账户信息的接口 Account getAccountByName(String accountName); // 省略其他接口...... } // --------------业务层--------------- public class AccountServiceImpl implements IAccountService { @Autowired private AccountMapper accountMapper; // 提现的业务方法 public boolean cashWithdrawal(String accountName, int type, String target, BigDecimal money){ // 先根据账户名查询出账户信息 Account account = accountMapper.

Pandas DataFrame对象索引及常见错误写法

fPython语言Pandas库的DataFrames数据类型的索引写法比较多,既提供了方便也容易出错。一般的Python书籍上对Pandas索引都有介绍,本文总结一些个人体会,大体分为用中括号索引和用loc/iloc[]索引。 先生成一个DataFrame对象为例: df=pd.DataFrame(np.random.rand(4,4), index=list('abcd'), columns=list('ABCD')) ABCDa0.9592450.5522850.2659930.249411b0.7438800.5826830.3109400.675503c0.6442870.7962470.2023140.232712d0.1494950.5702650.0953890.029824 1. 用中括号的索引 在用中括号索引时最容易犯错的是混淆了行索引和列索引。基本原则如下: (1)单值索引只能索引列 df['A']是正确的写法,等同于df.A。如果想索引某一行,不能写成df['a']或df['a',:],否则会报错。但可以改用df[df.index=='a']或者df.loc['a']的形式。当需要创建一列时只能用df['列名']的形式。 (2)列表索引也只能索引列 如果想同时索引多列,可以写成df[['A','B']],记住有两层中括号,不能少一层中括号。如果写成df['A','B']会报错,因为逗号被解释成了维度之间的分隔符。这里行索引只有'a',而没有'A',而且要表示'a'行'B'列应该用df.loc['a','B'],不能少了loc。列表索引可以改变索引列的顺序,例如写成df[['C','B','A']]将按C、B、A的顺序显示,这叫花式索引。 (3)切片只能索引多行 切片索引写成df['a':'c']或df[:2]表示索引a到c三行,但不能写成df['A':'C']或df[:,'A':'C']来索引三列。这点跟numpy的array不同,如果df是ndarray类型的,可以用df[:, 1:3]来切片第1~2列。要想切片多列可以写成df.loc[:,'A':'C'],但这里不能少了loc和:,,否则也报错。另外,切片只能用中括号或loc索引,而不能写成对象属性的形式,df.loc[:, df.A:df.C]也会报错。 2. 用loc/iloc[]的索引 上面说了中括号不能对单个行进行索引,而用loc/iloc就解决了这个问题,例如df.loc['b']或df.iloc[2],所以要想索引某一行只能用loc/iloc的形式。由于loc可以索引单个行,为了不引起混淆,索引单个列时必须在前面加上符号“:,”,例如df.loc[:,'A']表示索引A列,如果写成df.loc['A']就会报错,因为Notebook会将df.loc['A']解读为df的A行而实际上df并没有A行。同样,可以用iloc[]来索引一个元素或切片,例如df.iloc[2][3]跟df.iloc[2,3]是等价的,都得到0.232712。df.iloc[2][3]相当于先从df中取出df.iloc[2]这一行,再从这行中取出第3个数。同理,df.iloc[2][1:3]表示第2行的1到2切片。但博主不建议用两个方括号iloc[][]的写法,有时程序会出意外错误。 3. 关于布尔索引 (1)布尔条件索引既可以索引行又可以索引列,既可以用于中括号索引又可以用于loc/iloc索引。但我建议尽量用loc索引,尤其是对列索引操作时不容易出错,用iloc或直接用方括号索引有时会出现未知错误。如果逻辑表达式是关于变量(列)取值的,布尔索引返回的是行数据,例如写成df.loc[关于列的条件]返回的是行数据,例如df.loc[df['A']>0.5]。如果逻辑表达式是关于行索引取值的,例如写成df.loc[关于行的条件],则返回的是列数据,例如df.loc[:, df.loc['c']>0.1]。另外还需注意df.loc[df['A']>0.1]中内层的df不能漏了,如写成df[['A']>0.1]或df['A'>0.1]系统只会把'A'当成是一个字符而报错,系统不知道A是指df的一列。还有一个原因,是内侧用于逻辑判断的表跟外侧被索引的表可以不相同,即df1.loc[df2['A']>0.1]的写法,假定df1和df2不是同一个表,这里[df2['A']>0.1]返回一个df2中为True的元素位置的索引列表,然后在df1中按照同样的位置把行取出来。因此用于逻辑判断的字段就必须带上表名,否则不知道是指哪个表里的字段。如果只需要显示A列数据,不能写成df.A[df>0.1],而应该写成df.A[df.A>0.1]。 (2)当逻辑表达式是关于列名的,布尔索引可以用于对列索引,例如df.iloc[:, df.columns!='B']或df.loc[:, df.columns!='B']都能执行,但此处不能少了loc和iloc,否则也报错。总之凡是把行索引写成“:,”再写列的选取条件的形式只能用在loc/iloc格式。 (3)如果要用布尔关系将多个条件组合起来,要给每个条件加小括号,例如df.loc[(df['A']>0.7) & (df['B']<0.5) & (df['C']>0.6)],漏写小括号也会出错。注意这里的运算符是位运算符&,而不是布尔运算符and,后者也会出错。如果需要返回整个矩阵,只能用中括号索引,而不能用loc/iloc[]。例如返回df中大于0.1的值应当写成df[df>0.1],而不能写成df.loc[df>0.1]

配置Maven仓库私服

在项目的pom.xml文件中配置,将下面代码复制粘贴到文件的最下方即可 <repositories> <repository> <id>nexus-aliyun</id> <name>nexus-aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>public</id> <name>aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> **注意:不要超出最后一层标签的包裹范围

js中async与await详解

引言 JavaScript 是一门基于事件驱动和异步编程的语言,而异步编程是 JavaScript 中最常用的编程方式之一。在异步编程中,我们通常使用回调函数或 Promise 对象来处理异步操作的结果。而在 ES2017 中,引入了 async 和 await 关键字,使得异步编程更加简洁和易读。 Promise 对象 在介绍 async 和 await 之前,我们先来了解一下 Promise 对象。Promise 对象是 JavaScript 中处理异步编程的一种机制,它可以将异步操作封装成一个对象,使得异步操作的结果可以像同步操作一样被处理。 一个 Promise 对象表示一个异步操作的最终完成或失败,并且可以将其结果返回给异步操作的调用者。Promise 对象有三种状态:pending(等待中)、fulfilled(已完成)和rejected(已失败)。当一个 Promise 对象处于等待中状态时,它表示异步操作正在进行中;当一个 Promise 对象处于已完成状态时,它表示异步操作已经成功完成;当一个 Promise 对象处于已失败状态时,它表示异步操作已经失败。 在使用 Promise 对象时,我们通常使用 then 方法处理异步操作的结果,或者使用 catch 方法处理异步操作的错误。以下是一个简单的例子,演示如何使用 Promise 对象处理异步操作的结果: javascript Copy code fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)); 在上面的例子中,我们使用 fetch 函数从服务器获取数据,并将其解析为 JSON 格式。然后,我们使用 then 方法处理解析后的数据,或者使用 catch 方法处理错误。 async 函数 async 函数是一种特殊的函数,它的返回值是一个 Promise 对象。使用 async 关键字声明的函数可以在内部使用 await 关键字来等待异步操作完成,并返回一个 Promise 对象。在 async 函数中使用 await 关键字可以让异步操作的结果像同步操作一样被处理,从而避免了回调地狱的问题。

纵览轻量化卷积神经网络:SqueezeNet、MobileNet、ShuffleNet、Xception

点击上方“小白学视觉”,选择加"星标"或“置顶” 重磅干货,第一时间送达 仅作学术分享,不代表本公众号立场,侵权联系删除 转载于:机器之心 本文就近年提出的四个轻量化模型进行学习和对比,四个模型分别是:SqueezeNet、MobileNet、ShuffleNet、Xception。 目录 一、引言 二、轻量化模型 2.1 SqueezeNet 2.2 MobileNet 2.3 ShuffleNet 2.4 Xception 三、网络对比 一、引言 自 2012 年 AlexNet 以来,卷积神经网络(简称 CNN)在图像分类、图像分割、目标检测等领域获得广泛应用。随着性能要求越来越高,AlexNet 已经无法满足大家的需求,于是乎各路大牛纷纷提出性能更优越的 CNN 网络,如 VGG、GoogLeNet、ResNet、DenseNet 等。由于神经网络的性质,为了获得更好的性能,网络层数不断增加,从 7 层 AlexNet 到 16 层 VGG,再从 16 层 VGG 到 GoogLeNet 的 22 层,再到 152 层 ResNet,更有上千层的 ResNet 和 DenseNet。虽然网络性能得到了提高,但随之而来的就是效率问题。 效率问题主要是模型的存储问题和模型进行预测的速度问题(以下简称速度问题) 第一,存储问题。数百层网络有着大量的权值参数,保存大量权值参数对设备的内存要求很高; 第二,速度问题。在实际应用中,往往是毫秒级别,为了达到实际应用标准,要么提高处理器性能(看英特尔的提高速度就知道了,这点暂时不指望),要么就减少计算量。 只有解决 CNN 效率问题,才能让 CNN 走出实验室,更广泛的应用于移动端。对于效率问题,通常的方法是进行模型压缩(Model Compression),即在已经训练好的模型上进行压缩,使得网络携带更少的网络参数,从而解决内存问题,同时可以解决速度问题。 相比于在已经训练好的模型上进行处理,轻量化模型模型设计则是另辟蹊径。轻量化模型设计主要思想在于设计更高效的「网络计算方式」(主要针对卷积方式),从而使网络参数减少的同时,不损失网络性能。 本文就近年提出的四个轻量化模型进行学习和对比,四个模型分别是:SqueezeNet、MobileNet、ShuffleNet、Xception。 (PS:以上四种均不是模型压缩方法!!) 以下是四个模型的作者团队及发表时间 其中 ShuffleNet 论文中引用了 SqueezeNet;Xception 论文中引用了 MobileNet

Java Stream流学习日志

什么是Stream流? 在Java 8中,得益于Lambda所带来的函数式编程, 引入了一个全新的Stream流概念。 目的:用于简化集合和数组操作的API。 Stream流式思想的核心: 先得到集合或者数组的Stream流(就是一根传送带) 把元素放上去 然后就用这个Stream流简化的API来方便的操作元素。 Stream流的三类方法 获取Stream流 创建一条流水线,并把数据放到流水线上准备进行操作 中间方法 流水线上的操作。一次操作完毕之后,还可以继续进行其他操作。 终结方法 一个Stream流只能有一个终结方法,是流水线上的最后一个操作 import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Set; /*Stream<T> filter(Predicate<? super T> predicate) 用于对流中的数据进行过滤。 Stream<T> limit(long maxSize) 获取前几个元素 Stream<T> skip(long n) 跳过前几个元素 Stream<T> distinct()去除流中重复的元素。依赖(hashCode和equals方法) static <T> Stream<T> concat(Stream a, Stream b)合并a和b两个流为一个流*/ /*Stream<T> filter(Predicate<? super T> predicate) 返回由与此给定谓词匹配的此流的元素组成的流。*/ public class Stream_01 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); Collections.addAll(list,"lynk&co", "

Digicert证书是什么?有哪些类型?

Digicert是谁 DigiCert,全球领先的数字信任提供商;提供市场所需的基石,包括制定全球标准、提供全球合规性和运营、提供证书生命周期管理以实现公共与私有的信任,并将信任扩展到供应链和互联生态系统。 Digicert收购Symantec数字证书业务后,已经是全球首屈一指的互联网安全品牌。在网站安全、电子邮件安全、数据泄露防护和SSL证书领域,没有任何一品牌可以替代Digicert/Symantec的地位。所有Digicert SSL证书,都支持在有效期内免费重新签发服务。 Digicert品牌优势 证书品牌多 全球著名CA机构,包含Symantec在内的所有证书品牌; 证书加密程度强 支持SHA256和ECC算法,RSA位数高达4096位,以及256位加密强度,安全性高; 支持重新签发 所有Digicert证书产品都支持在有效期内免费重新签发的服务; 提升网站转化率 广受信任的Norton安全认证签章,有效提升网站转化率; 证书颁发速度快 Digicert OCSP服务响应速度迅捷,证书签发速度业界领先; CDN加速ICA定制 斥资打造更加适应中国地区的ICA,高效的CDN加速,让证书响应更上一个台阶。 Digicert证书类型 证书类型:OV SSL证书 签发时间:1-3个工作日 适配范围:单域名 证书续签:1年/次 证书类型:OV 通配符证书 签发时间:1-3个工作日 适配范围:通配符 证书续签:1年/次 证书类型:EV SSL证书 签发时间:1-3个工作日 适配范围:单域名 证书续签:1年/次 证书类型:邮件证书个人版 签发时间:1个工作日 适配范围:邮件签名 证书续签:1年/次 Digicert证书合集:永久免费SSL证书_永久免费https证书_永久免费ssl证书申请-JoySSL