引入 在做一道很基础的python题的时候,老师提醒我可以用到decimal类型进行优化。
原题是这样的:分析一下程序的输出结果,说明出现该结果的原因,应该如何修改程序
x=2.1 y=2.0 if x-y==0.1: print("Equal") else: print("Not Equal") print(x-y) 程序会输出"Not Equal"
原因解释: 首先,程序定义了两个浮点数变量 x 和 y,分别赋值为 2.1 和 2.0。然后,程序执行条件判断 x-y==0.1,这个条件判断是否 x 和 y 的差是否等于 0.1。由于浮点数的精度问题,2.1 - 2.0 并不等于精确的 0.1,而是一个非常接近 0.1 的浮点数。 所以,条件判断 x-y==0.1 会返回 False,因此程序会执行 print("Not Equal")。
接下来,程序执行 print(x-y) 来输出 x 和 y 的差,这会显示一个非常接近 0.1 的浮点数,但它并不等于精确的 0.1,这是因为浮点数在计算机内部以二进制表示,有时无法准确地表示十进制小数。
这时,老师提醒我可以运用decimal类型进行优化,下面我为大家整理了decimal类型的大致内容:
decimal 类型 在 Python 中,decimal 类型是用于高精度的十进制浮点数运算的数据类型。它属于 Python 标准库中的 decimal 模块,可以用于处理需要高精度计算的场景,尤其是在涉及到金融、科学计算、精确度要求较高的计算任务时非常有用。
decimal 类型的特点和用途包括:
高精度计算: decimal 类型可以表示高精度的十进制数,避免了浮点数的精度问题。这对于需要准确表示小数或进行精确计算的任务非常重要。
避免浮点数问题: 浮点数(float 类型)在计算机内部以二进制表示,有时无法精确表示十进制小数,可能会导致精度损失和舍入错误。decimal 类型解决了这个问题。
1、介绍
在实体Bean中中有大量的Getter/Setter方法,以及toString, hashCode等方法,而且很多时候要重复写多次,为消除模板代码getter、setter、构造器、toString()、equals()等,使用lombok插件。
lombok通过注解自动实现代码生成。
2、Springboot中通过添加依赖使用lombok
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.10</version> </dependency> 3、lombok注解介绍
@NonNull : 主要作用于成员变量和参数中,做非空判断,如果传入空值会直接抛出异常NullPointerException。
@Setter/@Getter : 自动生成set和get方法,这两个注解如果作用于类上,会生成所有成员变量的getter/setter方法,如果作用于成员变量上,会生成该成员变量的getter/setter方法,可以设定访问权限及是否懒加载等。
@ToString : 自动生成toString方法,默认会包含所有类属性,使用@ToString.Exclude注解可以排除属性的生成。
@EqualsAndHashcode : 从对象的字段中生成hashCode和equals的实现,默认包含所有类属性,使用@EqualsAndHashCode.Exclude可以排除属性的生成。
@NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor 这三个注解作用于类上,用于生成构造函数,有staticName、access等属性,staticName属性一旦设定,将采用静态方法的方式生成实例,access属性可以限定访问权限。
自动生成构造方法。@NoArgsConstructor:生成无参数构造函数,@RequiredArgsConstructor:生成包含final和@NonNull注解的成员变量的构造函数,@AllArgsConstructor:生成包含所有参数的构造函数。
@Data : 作用于类上,是以下注解的集合:@ToString、@EqualsAndHashCode、@Getter、@Setter、@RequiredArgsConstructor
@Builder : 作用于类上,将类转变为建造者模式,建造者模式加链式调用,创建对象非常方便。
@Log : 作用于类上,生成日志变量,针对不同的日志实现产品,有不同的注解,如@Log、@Log4j、@Log4j2、@Slf4j等。
@val:使用val注解可以取代任意类型作为局部变量,这样我们就不用写复杂的ArrayList和Map.Entry类型了,当我们使用了val注解后,Lombok会从局部变量的初始化表达式推断出具体类型。
@Value : 使用@Value注解可以把类声明为不可变的,声明后此类相当于final类,无法被继承,其属性也会变成final属性。
@CleanUp : 当我们在Java代码中使用资源时,需要在使用后关闭资源,使用@Cleanup注解可以自动关闭资源,这个注解针对实现了java.io.Closeable接口的对象有效,如:典型的IO流对象。
@SneakyThrows : 可以对受检异常进行捕捉并抛出。
@Synchronized : 作用于方法级别,可以替换synchronize关键字或lock锁
@With :使用@With注解可以实现对原对象进行克隆,并改变其一个属性,使用时需要指定全参构造方法。
4、Lombok的优缺点
优点:可以通过注解方式,自动生成一些代码,开发效率提高;代码整洁度提高,减少一些简单方法;便于属性修改。
缺点:不支持多种构造函数,降低了代码的可读性。
注意:lombok 的注解不能被继承。
5、举例
@Data @Builder public class User { private String name; private Integer age; }
文章目录 相关网址汇总: 一、软件安装:VS、CUDA、QT1 安装VS1.1 下载1.2 vs2017安装1.3 vs2015安装 2 安装CUDA2.1 下载2.2 安装2.3 测试2.4 卸载 3 安装QT3.1 下载3.2 安装 二、QT使用cuda1 .pro文件 三、常用操作1 NVIDIA控制面板:显卡、驱动版本、驱动类型、CUDA2 命令行:查看显卡驱动版本3 测试cuda安装是否成功 相关网址汇总: 查看显卡支不支持cuda及算力:https://developer.nvidia.com/cuda-gpus#collapse4显卡驱动下载:https://www.nvidia.cn/Download/Find.aspx?lang=cn#查看显卡驱动版本对应的cuda:https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.htmlcuda下载:https://developer.nvidia.com/cuda-toolkit-archive查看cuda版本对应的vs版本:https://docs.nvidia.com/cuda/archive/ 一、软件安装:VS、CUDA、QT 1 安装VS 1.1 下载 软件安装管家:https://mp.weixin.qq.com/mp/homepage?__biz=MzA4MjU4MTg2Ng==&hid=18&sn=2dccf8223c0bac443c2b8f260731278a&scene=21#wechat_redirect 1.2 vs2017安装 参考管家的教程。2017是在线安装,安装时只选C++ 1.3 vs2015安装 参考管家的教程。2017是离线安装,安装时断网(不然会报错),只选C++
2 安装CUDA 2.1 下载 (要翻墙):https://developer.nvidia.com/cuda-toolkit-archive
2.2 安装 一路next,自定义安装。组件只选CUDA。如果安装cuda前没安装vs,取消勾选Visual Studio Integration。
参考教程:https://blog.csdn.net/chen565884393/article/details/127905428
2.3 测试 查看已安装cuda版本 nvcc -V 运行cuda自带例程 cd C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\extras\demo_suite bandwidthTest.exe 2.4 卸载 用geek卸载,卸载NVIDIA相关的,仅下面3项不卸载 3 安装QT 3.1 下载 官网下载,从QT5.15.0版本开始,官方不再提供离线版安装包,除非你充钱买商业版。
header和trailer元数据传输 header和trailer元数据最后会设置到http header。 用于传输除了proto定义以外的额外信息。比如用户身份认证信息,代理信息,访问令牌等。在grpc里统称为metadata.MD
元数据构建 元数据数据结构
// MD is a mapping from metadata keys to values. Users should use the following // two convenience functions New and Pairs to generate MD. type MD map[string][]string //grpc 元数据处理 func getMetadataByMap(mp map[string]string) metadata.MD { // 返回值 type MD map[string][]string // 通过map 初始化元数据,后续要放到上下文中 md := metadata.New(mp) return md } // 根据键值对获取 元数据 func getMetadataByKV(kv ...string) metadata.MD { md := metadata.Pairs(kv...) return md } // 元数据附加 func appendMetadata(md *metadata.
初次看到“无测试组织”的朋友可能会觉得有标题党之嫌,类似“测试岗位已死”的论调每几年就会在媒体和圈子里传播一轮。难道“狼”又要来了吗?
实际上,行业对测试工程师的招聘数量不降反升,随着新兴公司的蓬勃发展,测试工程师的薪酬也水涨船高。显然,“无测试组织”的发展势头在这些年并没有显现出来。
在高度成熟的敏捷研发团队中,测试工作应该如何开展,以及由谁来承担呢?
今天的测试工程师,面向可能的未来变革开始长期修炼,肯定有百益而无一害。
敏捷团队中,测试技能是“永生”的,但传统意义上的“测试团队”可以“无”。无测试组织延展了测试内涵的四化:服务化、标准化、智能化、全员化。品质保障不再由专职的测试工程师团队全权负责,而是由业务团队全员、专家、标准、平台及每一个用户协力保障。
这样的“无测试组织”可能在很多年后还是一股特立独行的清流,但我坚信它会是价值认可度最高、回报最高的典范团队。它也是在本质上契合敏捷研发价值观的理想形态。
正如武侠小说中所描述的,做到“手中无剑,心中有剑”是一个艰苦和长期的改进过程,这个过程充满着尝试、误解、风险和快乐。如果只是习惯了现在的稳定工作分工,只顾着解决眼前的麻烦,就无法引领团队走向正确的方向。
今天,随着云计算、AI、大数据等技术的商业化进程,整个技术行业又在快速迭代和演进。过去建设起来的研发或测试体系也面临更多的新挑战。在保持产品品质、效率、体验不断提高的要求下,这些年的全栈能力发展、去测试化发展的呼声也日渐高涨。很多测试同人也有很大的顾虑。测试领域的未来如何发展?测试从业者未来应该如何思考、综合提升而不至于掉队落伍?今天推荐一本鼎叔的《无测试组织:测试团队的敏捷转型 》,应该可以给大家答疑解惑。
这本书从两个维度剖析了测试领域的发展侧重点:
1)如何组建测试团队和实施测试管理;
2)如何提升测试的综合技能。
如果你是测试领域的管理人员,推荐阅读本书的第一部分,这部分介绍了测试管理的体系化搭建框架方案,内容涉及测试职责范畴的扩散/定义、测试的度量、测试积累沉淀管理,以及团队人员技能和人力管理等多个方面。
一些测试人员在测试岗位时间越久,会越来越缺乏竞争力。归其原因,他们更多是偏向黑盒/系统测试,专注测试用例设计分析和执行,没有关注对被测产品的架构、实现技术的理解,深度问题定位甚至解决能力,以及更创造性的测试能力等方面的提升。这会让自身在更具挑战性的质量和效率提升要求到来时无所适从。
本书第二部分系统介绍了测试人员的能力提升方向和建议,同时介绍了很多实际方法。从基本测试分析设计,到测试自动化并关注自动化ROI,再到探索式测试、众包测试、精准测试和用户体验测试的开展方法等,书中都给出了专业的建议/方案,相信对那些立志提升自己专业技能的读者会有很大帮助。
很多人在职业初期选择进入测试领域的原因是觉得它的门槛较低,这是对测试领域的误解。每个领域都有各自核心竞争力、困难以及挑战。测试技术不断发展,不过测试领域的核心能力要求本质不变。每个人只有抓住本质,聚焦核心竞争力的提升,才能让自己以不变应万变,始终保持职业上的竞争优势。
最后,当前ChatGPT对各行各业的冲击正在驱动不同行业大力思考,积极应对。测试领域同样会面临挑战。只有保持学习和总结,关注落地结果及改进,保持创造性思维,保持接纳和融合意识,让自身具备充足的技能竞争力,才能在技术和时代的变化中抓住更多的新机遇!
购买链接:购书直达
paimon的写入流程paimon的读取流程为什么Paimon值得期待Flink进行Paimon写入源码分析Flink+Paimon多流拼接性能优化实战
getMsg() { var myChart = echarts.init(document.getElementById("left")); let option = { tooltip: { trigger: "item", formatter: "{b} : {c} ({d}%)" }, legend: { bottom: 10, left: "center", data: this.topInfo.list, textStyle: { color: "#333333", fontSize: "10", fontWeight: 400 }, type: "scroll" }, series: [ { type: "pie", radius: "65%", center: ["50%", "45%"], selectedMode: "single", data: this.topInfo.details, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: "rgba(0, 0, 0, 0.5)" } } } ] }; console.
在屏幕坐标上有一个多边形,给定一个点,判断该点和多边形的关系。
例如在下图中,点A位于多边形内,点B位于多边形外,点C位于多边形上。
注意:
1.屏幕坐标系中,x轴从左往右为正方向,y轴从上到下为正方向,如示例中的坐标轴:
输入:
第一行为多边形数据,第一个数为整数,表示顶点个数,之后是顶点坐标,依次为各个点的x、y坐标的浮点数值。
例如 3 3.7 5 2 4 2.5 1.5 ,则表示有三个点组成的三角形。第二行表示待判断的点坐标,例如1.5 8.3
输出:
如果点在多边形内部,则返回0,如果在多边形上则返回1,如果在多边形外面则返回2
代码:
#include <iostream> #include <vector> #include <string> #include <algorithm> using namespace std; struct Point{ double x; double y; }; bool PointInPolygon2D(Point p, vector<Point>& Polygon){//判断点与多边形的关系 int nPointNumber = Polygon.size(); if (nPointNumber == 0) return false; int nSideNumber = nPointNumber; if (Polygon[0].x == Polygon[nPointNumber - 1].x && Polygon[0].y == Polygon[nPointNumber - 1].y) nSideNumber--; double epsilon = 0.
OWT Server整体架构分析 目录 相关文章:
Ubuntu环境安装OWT Server[Open WebRTC Toolkit]Docker环境安装OWT Server[Open WebRTC Toolkit]OWT Server整体架构分析 [Open WebRTC Toolkit]OWT Server信令分析 (上) [Open WebRTC Toolkit]OWT Server信令分析 (下) [Open WebRTC Toolkit]OWT Server进程结构和JS代码处理流程 [Open WebRTC Toolkit]OWT Server REST API 1. OWT Server架构 OWT Server秉承模块化的架构原则,根据组件的功能可以分为五大块,如下图所示。 1. 信令组件 信令组件,负责和客户端进行信令交互。 WebRTC Portal负责和WebRTC客户端进行信令交互。SIP Portal负责和SIP客户端进行信令交互。
2. 媒体对接组件 媒体对接组件,负责把媒体数据接入到系统内,以及把媒体数据接出到其他系统。 WebRTC Agent负责和WebRTC客户端进行媒体数据的传输。SIP Agent负责和SIP客户端进行媒体数据的传输。Streaming Agent负责RTSP/RTMP/HLS/Dash流的输入输出。Recording Agent负责服务端录制。
3. 媒体处理组件 媒体处理组件,负责音视频数据的转码、合并、分析等处理。 Audio Agent负责音频转码和混音。Video Agent负责视频转码和合成。Analytics Agent则提供了一些服务端的音视频流分析功能,并且支持自定义插件进行分析处理。
4. 呼叫控制组件 呼叫控制组件,负责房间、用户的控制和管理,比如加入房间、发布音视频流、订阅音视频流等,都是由Conference Agent进行处理的。
5. 支持组件 支持组件包括: OWT Server即便在单机运行时也是按照集群形式管理的,Cluster Manager就是一个简单的集群管理器。创建房间、获取用户信息和流信息之类的功能都是通过RESTful API的形式提供的接口,而这些接口都由Management API进行提供。Management Console是管理员控制台,提供了一个网页服务。OWT Server需要持久化的数据都保存在MongoDB中,各个组件之间的通信则是利用基于RabbitMQ的RPC调用来实现的。 上面这些组件部署时都是独立的进程,实际上部署时各个组件都是独立的目录,它们既可以都运行在同一台服务器上,也可以运行在不同的服务器上。这样模块化和强隔离的架构保证了错误隔离,一个组件中产生的异常不会传染影响其他组件,另外各个组件在运行时也都可以单独进行升级替换。
网络编程——socket定义和地址格式 目录 socket 是什么?套接字地址格式 1. socket 是什么? 网络编程中, socket 翻译为套接字或套接口,指可以通过插口接入的方式,快速完成网络连接和数据收发。上图表示网络编程中,客户端和服务器工作的核心逻辑。服务器端,在客户端发起连接请求之前,服务器端必须初始化好。 初始化 socket。执行 bind 函数,将服务能力绑定在一个可知的地址和端口上。然后执行 listen 操作,将原先的 socket 转化为服务端的 socket。服务端最后阻塞在 accept 上等待客户端请求。 当服务器端已经准备就绪,客户端需要先初始化 socket,再执行 connect 向服务器端的地址和端口发起连接请求,这里的地址和端口必须是客户端预先知道的。connect请求就是TCP 三次握手(Three-way Handshake)。三次握手完成后,客户端和服务器端建立连接,就进入了数据传输过程。 客户端进程向操作系统内核发起 write 字节流写操作,内核协议栈将字节流通过网络设备传输到服务器端,服务器端从内核得到信息,将字节流从内核读入到进程中,并开始业务逻辑的处理,完成之后,服务器端再将得到的结果以同样的方式写给客户端。所以一旦连接建立,数据的传输就不再是单向的,而是双向的。 当客户端完成和服务器端的交互后,比如执行一次 Telnet 操作,或者一次 HTTP 请求,需要和服务器端断开连接时,就会执行 close 函数。 操作系统内核此时会通过原先的连接链路向服务器端发送一个 FIN 包,服务器收到之后执行被动关闭,这时候整个链路处于半关闭状态。此后,服务器端也会执行 close 函数,整个链路才会真正关闭。半关闭的状态下,发起 close 请求的一方在没有收到对方 FIN 包之前都认为连接是正常的。而在全关闭的状态下,双方都感知连接已经关闭。 以上所有的操作,都是通过 socket 来完成的。无论是客户端的 connect,还是服务端的 accept,或者 read/write 操作等,socket 是用来建立连接,传输数据的唯一途径。
2. 套接字地址格式 在使用套接字时,首先要解决通信双方寻址的问题,需要套接字的地址建立连接,套接字的地址格式如下。
1. 通用套接字地址格式 套接字的通用地址结构: /* POSIX.1g 规范规定了地址族为 2 字节的值. */ typedef unsigned short int sa_family_t; /* 描述通用套接字地址 */ struct sockaddr{ sa_family_t sa_family; /* 地址族.
1. mediasoup基本介绍及Ubuntu/Docker环境下部署mediasoup 0. 目录 mediasoup基本介绍Ubuntu环境mediasoup-demo安装部署Docker环境mediasoup-demo安装部署 相关文章:
mediasoup基本介绍及Ubuntu/Docker环境下部署mediasoupmediasoup-demo server源码分析 1. mediasoup基本介绍 根据mediasoup官网介绍,mediasoup是一个开源的、基于SFU网络架构的WebRTC媒体服务器,低层采用C++实现,外层使用Node.js进行封装。mediasoup服务器端以Node.js模块的形式提供。 mediasoup主要用于构建实时通信应用程序,如视频会议、音频聊天、屏幕共享和实时流媒体等。关于WebRTC网络架构见: mediasoup特点: 基于 WebRTC 标准:使用 WebRTC 技术作为核心,支持实时音视频通信。可扩展性:可轻松扩展媒体服务器的规模,以适应不同应用的需求。灵活性:提供了丰富的 API,可以定制各种媒体处理和传输操作。安全性:支持 DTLS 和 SRTP,保护媒体通信的安全性。开源性:完全开源,可自由使用和修改。 mediasoup整体架构: 2. Ubuntu环境mediasoup-demo安装部署 mediasoup-demo是一个基于mediasoup的示例应用程序,用来演示mediasoup的功能和用法。下面使用Ubuntu环境安装mediasoup-demo。
1. 安装nodejs环境 安装 Node.js:在安装mediasoup-demo之前,需要先安装 Node.js 运行环境。 sudo apt-get update sudo apt-get install nodejs sudo apt-get install npm //备注,直接安装的nodejs版本可以后续下载依赖会报错,我使用的是:node-v16.14.0-linux-x64 wge https://nodejs.org/dist/v16.14.0/node-v16.14.0-linux-x64.tar.gz tar -zxvf node-v16.14.0-linux-x64.tar.xz cd node-v16.14.0-linux-x64/ sudo ln -s ./bin/node /usr/local/bin/ sudo ln -s ./bin/npm /usr/local/bin/ 2. 克隆mediasoup-demo代码 克隆mediasoup-demo仓库中代码: git clone https://github.com/versatica/mediasoup-demo.git 3. 安装mediasoup-demo依赖并配置 安装依赖:进入mediasoup-demo项目目录,安装项目所需的依赖: 注:npm install安装依赖包需要翻墙,不然会无法下载。 cd mediasoup-demo git checkout v3 cd server npm install 安装依赖完成之后拷贝配置文件并配置: 拷贝后修改config.
mediasoup-demo server源码分析 0. 目录 mediasoup-demo是什么?mediasoup-demo代码结构mediasoup-demo server代码分析 config.js代码解析server.js主要逻辑Room.js具体代码解析 相关文章:
mediasoup基本介绍及Ubuntu/Docker环境下部署mediasoupmediasoup-demo server源码分析 1. mediasoup-demo是什么? mediasoup-demo是一个使用mediasoup库实现的视频会议应用程序的示例代码。mediasoup-demo示例应用程序提供了一个基于WebRTC的视频会议解决方案,包括房间管理、媒体流管理、网络传输和音视频编解码等功能,同时提供了前端和后端代码示例,方便进行学习和参考。其中mediasoup是一个开源的WebRTC信令和媒体服务器,用于构建实时音视频通信应用程序。
2. mediasoup-demo代码结构 mediasoup-demo代码结构图如下: 其中各目录或文件作用如下: 目录下一级目录或文件作用app客户端代码broadcasters广播,推流或者拉流server服务端Demoserver.js服务端Demo主程序config.js配置文件cert证书及秘钥connect.js对后面的interactiveClient.js文件进行封装libserver.js使用的库文件Logger.js打印日志Room.js房间管理及信令处理interactiveClient.js运行时内部信息查询客户端interactiveServer.js运行时内部信息查询服务端 重点关注server目录文件内容。
3. mediasoup-demo server代码分析 mediasoup-demo项目中server目录实现了视频会议应用程序的后端功能,包括与mediasoup的集成、WebSocket通信、房间管理、日志记录等功能。 1. config.js代码解析 config.js是配置文件,用于定义mediasoup的配置和服务器的端口等参数。配置文件如下: /** * IMPORTANT (PLEASE READ THIS): * * This is not the "configuration file" of mediasoup. This is the configuration * file of the mediasoup-demo app. mediasoup itself is a server-side library, it * does not read any "configuration file". Instead it exposes an API.
Ubuntu/Docker环境下调试mediasoup-demo 0. 目录 Ubuntu环境下调试mediasoup-demoDocker环境下调试mediasoup-demo 相关文章:
mediasoup基本介绍及Ubuntu/Docker环境下部署mediasoupmediasoup-demo server源码分析Ubuntu/Docker环境下调试mediasoup-demo 1. Ubuntu环境下调试mediasoup-demo 启动webserver.js node webserver.js & 启动server.js node --inspect-brk server.js 在谷歌游览器输入:chrome://inspect 即可弹出调试页面。 点击最下面的server.js的inspect链接即可跳出源码。 注:如果调试页面没有server.js,点击上图中 Configure… 按钮,添加地址端口。 然后就可以开始调试mediasoup-demo了。
2. Docker环境下调试mediasoup-demo 在docker环境下调试mediasoup-demo需要将容器内部的 9229 端口映射到主机的某个端口。以docker环境安装部署mediasoup-demo为例。 详细链接:mediasoup基本介绍及Ubuntu/Docker环境下部署mediasoup 拉取镜像: sudo docker pull lc0060305/mediasoup-demo:v5 下载 run.sh脚本 wget https://cdn.avdancedu.com/image/article/docker/v1/run.sh 需要修改 run.sh 脚本,添加端口映射,将将容器内部的 9229 端口映射到主机的 9229 端口。 #!/usr/bin/env bash export DEBUG=${DEBUG:="mediasoup:INFO* *WARN* *ERROR*"} export WEBPORT=${WEBPORT:="3000"} export INTERACTIVE=${INTERACTIVE:="false"} export PROTOO_LISTEN_PORT=${PROTOO_LISTEN_PORT:="4443"} export HTTPS_CERT_FULLCHAIN=${HTTPS_CERT_FULLCHAIN:="/service/certs/fullchain.pem"} export HTTPS_CERT_PRIVKEY=${HTTPS_CERT_PRIVKEY:="/service/certs/privkey.pem"} export MEDIASOUP_LISTEN_IP=${MEDIASOUP_LISTEN_IP:="0.0.0.0"} export MEDIASOUP_MIN_PORT=${MEDIASOUP_MIN_PORT:="44440"} export MEDIASOUP_MAX_PORT=${MEDIASOUP_MAX_PORT:="44500"} # Valgrind related options.
目录
一、栈
1.1 概念
1.2 栈的使用
1.3 栈的模拟实现 1.4 栈的应用场景
1.5 概念区分
二、队列
2.1 概念
2.2 队列的使用
2.3 队列的模拟实现
2.4 循环队列
三、双端队列
四、面试题
一、栈 1.1 概念 栈:一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底,栈中的元素遵循先进后出的原则。
压栈:栈的插入操作,也叫进栈或入栈,在栈顶插入数据;出栈:栈的删除操作,在栈顶删除数据。
1.2 栈的使用 方法解释Stack()构造一个空的栈E push(E e)将 e 入栈,并返回eE pop()将栈顶元素出栈并返回E peek()获取栈顶元素int size()获取栈中有效元素个数boolean empty()检测栈是否为空 public static void main(String[] args) { Stack<Integer> stack = new Stack(); stack.push(1); stack.push(2); stack.push(3); stack.push(4); stack.push(5); System.out.println(stack.size());//5 //获取栈顶元素 System.out.println(stack.peek());//5 System.out.println(stack); //[1, 2, 3, 4, 5] stack.pop();//出栈 5 System.out.println(stack.size());//4 System.out.println(stack); //[1, 2, 3, 4] System.
// ! element-plus vue3.0 import element from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import 'dayjs/locale/zh-cn' //中文 import locale from 'element-plus/lib/locale/lang/zh-cn' //中文 createApp(App).use(router).use(element, { locale }).mount('#app') 2.
<template> <el-config-provider :locale="locale"> <slot name="app"></slot> </el-config-provider> </template> <script> //引入vue方法 import { ElConfigProvider } from 'element-plus' //中文包 import zhCn from 'element-plus/lib/locale/lang/zh-cn' //引入自定义方法 //引入自定义组件 export default { name: 'ZhProvider', components: { [ElConfigProvider.name]: ElConfigProvider }, setup() { let locale = zhCn return { locale } } } </script> <style scoped lang='scss'> </style> 转载:vue3.
mvn archetype:generate \ -DarchetypeGroupId=org.apache.flink \ -DarchetypeArtifactId=flink-quickstart-java \ -DarchetypeVersion=1.17.1 \ -DgroupId=com.example \ -DartifactId=paimon \ -Dversion=1.0.1 \ -Dpackage=com.example \ -DinteractiveMode=false 目录结构
➜ ~ tree paimon paimon ├── pom.xml └── src └── main ├── java │ └── com │ └── example │ └── DataStreamJob.java └── resources └── log4j2.properties 参考文章:
1 https://nightlies.apache.org/flink/flink-docs-release-1.17/docs/dev/configuration/overview/
在开发微信小程序时,做一个上传头像的功能,我这里采用了uViewUi中的u-upload组件,出现了点击上传无效果没有反应问题,排查后问题出现原因是因为小程序没有获取到用户隐私权限导致,组件内部报错,大致意思“请确认是否拥有访问权限”,这就想到了微信小程序官方最近更新的隐私授权问题。
官方公告地址:关于小程序隐私保护指引设置的公告 https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html
解决方法:
在需要访问用户隐私的页面调用微信小程序官方提供的隐私授权弹窗即可,代码如下:
...
<!-- #ifdef MP-WEIXIN -->
<zero-privacy :onNeed='false' color="#0099BD" @disagree="quit" @agree="agreeChange"></zero-privacy>
<!-- #endif -->
...
methods:{
// 隐私授权
quit () {
wx.exitMiniProgram({
success: res => {
uni.$u.toast('即将退出小程序');
}
})
},
// 同意隐私授权
agreeChange () {
// 同意后所执行的代码逻辑,看需添加此方法。
},
}
总结:目前小程序对于用户隐私做了一些调整,在需要获取用户隐私的页面需要授权才行,这个授权弹窗最好加在小程序首页,以防出现各种报错问题。
亲爱的粉丝们,你是否曾经为学习JAVA而苦恼?繁复的代码和复杂的逻辑常常让人感到头大。不过,今天我要为大家介绍一本神奇的书——《漫画JAVA》,它以图文并茂的方式,轻松诙谐地讲解了JAVA的方方面面。在这篇文章中,我将带你走进这本书的世界,一探究竟。
首先,让我们来了解一下这本书的基本情况。《漫画JAVA》是由著名的JAVA编程专家精心打造,通过大量生动有趣的漫画和通俗易懂的文字,阐述了JAVA的核心概念和实际应用。全书共分为五个部分,包括基础知识、进阶知识、实战应用、疑难解析和案例分析。它不仅适合初学者快速上手,也适合有一定基础的程序员巩固提高。
那么,这本书有哪些亮点呢?首先,它打破了传统编程书籍的枯燥模式,通过漫画的形式将复杂的编程知识化繁为简,让人耳目一新。其次,书中的案例分析十分贴合实际应用,可以帮助读者更好地理解和掌握JAVA编程技能。最后,这本书还提供了丰富的课后练习和解答,方便读者巩固所学知识。
当然,我们也不能忽视这本书的特色。与其他编程书籍相比,《漫画JAVA》的最大特点就是通俗易懂。这本书将抽象的编程知识融入具体的漫画场景中,让人在轻松愉快的氛围中学习。此外,这本书还与时俱进地融入了众多热门话题和最新资讯,比如云计算、人工智能、区块链等,让你的学习之旅更加充实。
内容简介 小白兔:“这本书讲了什么内容呢?”
大牛哥:“这本书以漫画的形式介绍了 Java 语言的相关知识。全书共 20 章,书中首先介绍了 Java 语言的历史、特点、开发环境、运算符、数据类型、数组、字符串、判断语句、循环语句等基础知识,接着讨论了函数式编程、类与对象、异常、文件操作、集合、图形用户界面、网络通信、多线程等进阶内容,最后通过一个案例向大家介绍如何爬取图片。
小白兔:“看起来能学到不少 Java 的知识呀,不过一点基础都没有的小白,能学会吗?”
大牛哥:“当然可以,这本书适合对 Java 感兴趣的所有零基础初学者阅读,包括对编程感兴趣的中小学生,从事编程的大学生以及 Java 编程的从业人员哦!”
本书还有一些特色内容,帮助大家巩固知识点: 贴心的“小贴士”幽默的对话总结的重点知识“小结”提高读者动手能力的“实践一下”每章最后配有“同步练习题”同步练习题答案 本书特色 本书以漫画讲解,轻松有趣,幽默简单,全书全彩印刷,带大家轻松愉快理解知识。免费提供 配套Pdf书籍+视频20多年从业人员倾力打造,圈内大咖极力推荐。 精美内页展示 在这里,我强烈推荐所有对JAVA感兴趣的读者都去阅读这本书。相信它会成为你学习JAVA道路上的得力助手,让你在编程领域中游刃有余。正如一位网友所说:“《漫画JAVA》是一本让人眼前一亮的好书,它彻底颠覆了我对编程的认知!”
最后,让我们来总结一下这篇文章的主要内容。今天我们介绍了《漫画JAVA》这本书的概况和亮点特色。通过这本书,读者可以轻松愉快地学习JAVA编程知识,掌握实际应用技能。如果你正在寻找一本与众不同的JAVA书籍,那么《漫画JAVA》绝对是你的不二之选!让我们一起告别编程学习的苦恼,迎接属于我们的程序世界吧!
资料获取:↓↓↓↓↓↓
目录
一.JDK、JRE、JVM的关系
1.1JDK(Java SE Development Kit)
1.2JRE( Java Runtime Environment)
1.3JVM(Java Virtual Machine)
1.4JDK、JRE、JVM的区别与联系
二.Class的生命周期
2.1加载
2.1.1 类加载器
2.1.2类加载机制
2.1.3双亲委派
2.2链接
2.2.1验证
2.2.2准备
2.2.3解析
2.3初始化
2.4使用
2.5卸载
三.JVM 内存模型
3.1.运行时数据区
四.垃圾回收机制
一.JDK、JRE、JVM的关系 Java 程序是运行在 JVM(Java 虚拟机)上的,在开发程序之前都要配置 Java 开发环境,其中首先要做的就是 JDK 的安装和配置,那么 JDK、JVM、JRE 到底有何联系和区别呢?想必并不是每一个程序员都能说得清楚的,接下来将带你了解它们之间的关系。
1.1JDK(Java SE Development Kit) Java标准开发工具包,它提供了编译、运行 Java 程序所需的各种工具和资源,包括 Java 编译器、Java 运行时环境,以及常用的 Java 类库等。下图是 JDK 的安装目录:
1.2JRE( Java Runtime Environment) Java 运行环境,用于解释执行 Java 的字节码文件。普通用户而只需要安装 JRE就能够Java 程序。而程序开发者必须安装 JDK 来编译、调试程序。下图是 JRE 的安装目录:里面有两个文件夹 bin 和 lib,在这里可以认为 bin 里的就是 jvm,lib 中则是 jvm 工作所需要的类库,而 jvm 和 lib 和起来就称为 jre。
ubuntu系统下设置关闭笔记本盖子不休眠方法 sudo gedit /etc/systemd/logind.conf 打开后文件
[Login] #NAutoVTs=6 #ReserveVT=6 #KillUserProcesses=no #KillOnlyUsers= #KillExcludeUsers=root #InhibitDelayMaxSec=5 #HandlePowerKey=poweroff #HandleSuspendKey=suspend #HandleHibernateKey=hibernate #HandleLidSwitch=suspend #HandleLidSwitchDocked=ignore #PowerKeyIgnoreInhibited=no #SuspendKeyIgnoreInhibited=no #HibernateKeyIgnoreInhibited=no #LidSwitchIgnoreInhibited=yes #HoldoffTimeoutSec=30s #IdleAction=ignore #IdleActionSec=30min #RuntimeDirectorySize=10% #RemoveIPC=yes #InhibitorsMax=8192 #SessionsMax=8192 #UserTasksMax=33% 增加一行
HandleLidSwitch=ignore 重启服务
sudo service systemd-logind restart ubuntu系统下设置关闭笔记本盖子不休眠方法----完毕
List < Entity> 转 Map<Entity.getId,Entity> Map<Long, VipEntity> vipMap = vipList.stream().collect(Collectors.toMap (VipEntity::getUserId, v -> v, (v1, v2) -> v1)); 分别代表的含义
1. vipList.stream().collect(Collectors.toMap(....)) : stream()方法里的将list转换为map的方法 2.VipEntity::getUserId : 将每一个VipEntity里的UserId作为map的key 3.v->v : 将原来list里的每一个VipEntity作为map里的value 4.(v1,v2)-> v1 因为map里的key不可以重复,这个是如果发生了键重复,使用第一个作为键,后面的自动舍去,(v1,v2)->v2 则相反。
docker run -v /data1/wiki/confluence:/var/atlassian/application-data/confluence --name="confluence" -d -p 8090:8090 -p 8091:8091 --restart always e3d86929b746 docker run -v /data/data/confluence:/var/atlassian/application-data/confluence --name="confluence" -d -p 8090:8090 -p 8091:8091 --restart always 3e2c26db9138 一、yum -y install mysql 1.yum install mariadb-server mariadb # centos7 安装 systemctl start mariadb #启动MariaDBsystemctl stop mariadb #停止MariaDBsystemctl restart mariadb #重启MariaDBsystemctl enable mariadb #设置开机启动--------------------- 1、数据库创建和设置 CREATE DATABASE confluence CHARACTER SET utf8 COLLATE utf8_bin; GRANT ALL PRIVILEGES ON confluence.* TO 'root'@'%' IDENTIFIED BY 'xxxxx'; 2、my.
响应鼠标事件时:转换坐标、拾取点、或者Actor
Qt5.12.7
vtk-9.2
首先得理解VTK中的坐标系。
VTK_DISPLAY(0):显示坐标系,用于表示屏幕上的像素位置。 VTK_NORMALIZED_DISPLAY(1):归一化显示坐标系,用于表示屏幕上的归一化像素位置。 VTK_VIEWPORT(2):视口坐标系,用于表示在视口中的位置和大小。 VTK_NORMALIZED_VIEWPORT(3):归一化视口坐标系,用于表示在归一化视口中的位置和大小。 VTK_VIEW(4):视图坐标系,用于表示相对于相机视图的位置和方向。 VTK_POSE(5):姿态坐标系,用于表示对象的位置和方向,相对于参考坐标系。 VTK_WORLD(6):世界坐标系,用于表示对象的位置和方向,相对于全局坐标系。 VTK_USERDEFINED(7):自定义坐标系,用于表示用户自定义的坐标系。 这些常量可用于 VTK 中的各种操作,如渲染、变换和坐标转换等。通过选择适当的坐标系,可以确保对象在正确的位置和方向上进行操作和显示。 int * displayPos = Interactor->GetEventPosition();
这行代码可以获取交互器(vtkRenderWindowInteractor)接收到的最近一次事件发生的位置。它返回的是显示坐标系(VTK_DISPLAY)下的坐标。
坐标系转换(vtkCoordinate) vtkSmartPointer<vtkCoordinate> m_pCoordinateSelector= nullptr; m_pCoordinateSelector = vtkSmartPointer<vtkCoordinate>::New(); //设置系统的坐标系类型为VTK_DISPLAY m_pCoordinateSelector->SetCoordinateSystemToDisplay(); int * displayPos = Interactor->GetEventPosition(); m_pCoordinateSelector->SetValue(displayPos[0], displayPos[1], displayPos[2]); //返回世界坐标系中的计算值 auto w = m_pCoordinateSelector->GetComputedWorldValue(DefaultRenderer); //w 就是世界坐标系中的坐标 注意: 使用 vtkPointPicker 也能达到这个效果,但是如果仅需要转换坐标系那就不推荐vtkPointPicker 。因为速度慢很多。
Actor 的拾取(vtkPropPicker) vtkSmartPointer<vtkPropPicker> m_pPropPicker{ nullptr }; m_pPropPicker = vtkSmartPointer<vtkPropPicker>::New(); //启用拾取列表,之后的拾取仅从该列表内匹配 m_pPropPicker->SetPickFromList(true); //添加Actor vtkNew<vtkActor> actor; vtkNew<vtkActor> actor1; m_pPropPicker->AddPickList(actor); m_pPropPicker->AddPickList(actor1); //拾取 if (m_pPropPicker->Pick(displayPos[0], displayPos[1], 0, DefaultRenderer) > 0) { //拾取结果是Assembly auto pPickAssembly = m_pPropPicker->GetAssembly(); //拾取结果是Actor auto pPickActor = m_pPropPicker->GetActor(); }
一.创建自定义镜像 1. 用命令更新镜像 1、根据基础镜像,创建容器 docker run --name mytomcat -p 80:8080 -d tomcat 2、修改容器内容
docker exec -it mytomcat /bin/bash cd webapps/ROOT rm -f index.jsp echo "hello world" > index. html exit 3、提交为新镜像
docker commit -m="描述消息" -a="作者" 容器ID或容器名 镜像:TAG #例: #docker commit -m="修改了首页" -a="测试" mytomcat zhang/tomcat:v1.0 4、使用新镜像运行容器
docker run --name tom -p 8080:8080 -d zhang/tomcat:v1.0 2. 用Dockerfile构建镜像 创建一个Dockerfile文件 `vi Dockerfile` #注意Dockerfile指令须大写 FROM tomcat MAINTAINER zhang RUN rm -f /usr/local/tomcat/webapps/ROOT/index.jsp RUN echo "
1.函数 •所谓函数,就是把 具有独立功能的代码块 组织为一个小模块,在需要的时候调用; •函数的使用包含两个步骤: 1.定义函数 —— 封装 独立的功能;2.调用函数 —— 享受 封装 的成果;
•函数的作用,在开发程序时,使用函数可以提高编写的效率以及代码的 重用
2.函数的参数:函数(参数) 2.1 函数参数的使用 •在函数名的后面的小括号内部填写 参数
•多个参数之间使用 , 分隔
例如:sum_2_num(num1, num2)
2.2参数的作用 函数的参数,增加函数的 通用性,针对 相同的数据处理逻辑,能够 适应更多的数据 ①.在函数 内部,把参数当做 变量 使用,进行需要的数据处理
②.函数调用时,按照函数定义的参数顺序,把 希望在函数内部处理的数据,通过参数 传递
2.3形参与实参 形参(形式上的参数),定义 函数时,小括号中的参数,是用来接收参数用的,在函数内部 作为变量使用
实参(实际要用的参数),调用 函数时,小括号中的参数,是用来把数据传递到 函数内部 用的
可混合使用位置实参、关键字实参和默认值实参。
①位置实参(实参顺序很重要)
def pet(animal_type,pet_name):
snip
pet('dog','lucky')
②关键字实参
关键字实参是传递给函数的名称-值对,直接在实参中将名称和值关联起来了,因此向函数传递实参时不会混淆。不用考虑函数调用的实参顺序。
def pet(animal_type,pet_name):
snip
pet(animal_type='dog',pet_name='lucky')
③默认值实参
•定义函数时,可以给 某个参数 指定一个默认值,具有默认值的参数就叫做 缺省参数(默认值实参)
•调用函数时,如果没有传入 缺省参数 的值,则在函数内部使用定义函数时指定的 参数默认值;如果给形参提供了实参时,则使用指定的实参值
•函数的缺省参数,将常见的值设置为参数的缺省值,从而 简化函数的调用
例如:
小猫爪:嵌入式小知识18-XCP SeedNKey.dll 0 目录1 前言2 生成DLL2.1 下载模板代码2.2 函数简介2.2 DLL编译 3 使用DLLEND 0 目录 小猫爪:嵌入式小知识15-XCP基础简介小猫爪:嵌入式小知识16-XCP协议简介小猫爪:嵌入式小知识17-XCP on CAN简介小猫爪:嵌入式小知识18-XCP SeedNKey.dll 这篇文章应该就是XCP系列文章的最后一篇啦,其实XCP这个在那种复杂算法的应用中是非常有用的,对于通信类人才来说也是必备技能,但是由于XCP的实现原理非常简单,操作对象都是物理地址,所以在Slave端的开发是非常简单的,正规一点的,都是有相对应的上位机配一配,野路子拿到协议栈后也就简单做一下接口适配就可以直接使用了,非常简单。XCP的关键点其实在于那些上位机工具的使用,要想XCP玩的好,工具软件少不了。每一家的XCP上位机都不一样,每一家都有教学视频和文档,看看点点就会啦。
1 前言 上一节提到了XCP会将CMD按照功能分成了四类,并且可以分别给这个四类CMD加一把锁,Master要是想发送这四类CMD,那就需要分别需要对其进行解锁,这种机制就是XCP的Seed&Key机制。
解锁的流程也很简单,Master首先需要使用GET_SEED命令获取对应CMD类的seed,然后根据seed计算出对应Key1,再使用UNLOCK命令发送计算出的Key1,Slave接收到Key1再和本地根据Seed计算的Key2做比较,如果两边的Key相等,那么解锁成功。示例如下:
Slave计算Key可以直接通过写代码实现,非常简单,这里就不多做介绍了,那么那种常见的XCP上位机则是通过DLL文件来实现Seed&Key算法,那么接下来这篇文章主要就来说说怎样去制作自己的DLL文件来适配Slave的算法。
2 生成DLL 2.1 下载模板代码 该资源已与该文章绑定,请查看本文章开头:
2.2 函数简介 在示例代码里只要有两个函数,分别是XCP_GetAvailablePrivileges和XCP_ComputeKeyFromSeed,其介绍如下:
关于这两个函数就不多说啥了,拿着源码看看就知道有啥用了。
2.2 DLL编译 使用Visual Studio打开该工程,然后将你的Seed&Key算法写入其中,随后就是编译过程了。
双击Visual Studio工程文件:
选择编译条件:
编译 经过以上步骤这样DLL文件就编译出来了,如下:
3 使用DLL 上面已经生成了DLL文件,接下来就是使用它了,其实也很简单,就是在上位机中加载一下,就OK,拿CANape举例,在Device Configuration中,如下:
接下来再点击online,就成功了,如下:
因为我的DLL算法Key就等于Seed的取反,可以看到CANape已经成功用起了我的DLL文件里面的算法,至此,DLL就搞定了。
这一节到这里就结束啦,祝大家BUG连连。
END
1、创建一个SpringBooot项目并且打成jar包 2、在Linux中创建一个文件夹,来做docker测试 [root@izwz90lvzs7171wgdhul8az ~]# mkdir /root/docker_test 3、将jar包上传到Linux中 创建存放jar包的文件夹
[root@izwz90lvzs7171wgdhul8az docker_test]# mkdir /root/docker_test/jar 然后利用XShell上传jar包到上面的文件夹中
4、编写Dockerfile文件 # 基于java镜像创建新镜像 FROM java:8 #作者 MAINTAINER Howinfun #将jar包添加到容器中并更名为app.jar ADD jar/app.jar /root/docker_test/app.jar #运行jar包 ENTRYPOINT ["nohup","java","-jar","/root/docker_test/app.jar","&"] 注意:ADD 、 COPY 指令用法一样,唯一不同的是 ADD 支持将归档文件(tar, gzip, bzip2, etc)做提取和解压操作。还有需要注意的是,COPY 指令需要复制的目录一定要放在 Dockerfile 文件的同级目录下。
5、制作镜像 [root@izwz90lvzs7171wgdhul8az docker_test]# docker build -t sbdemo . 命令参数:
-t:指定新镜像名.:表示Dockfile在当前路径 如果我们的 Dockerfile 文件路径不在这个目录下,或者有另外的文件名,我们可以通过 -f 选项单独给出 Dockerfile 文件的路径
[root@izwz90lvzs7171wgdhul8az docker_test]# docker build -t sbdemo -f /root/docker_test/Dockerfile /root/docker_test/ 命令参数:
-f:指定Dockerfile文件的路径 (如果 Dockerfile 文件名是 Dockerfile,那么文件名可省略,再如果 Dockerfile 文件就在当前目录下,那么 -f 选项可省略。)最后参数是当前路径,即上下文路径 制作完成后通过docker images命令查看我们制作的镜像:
文章目录 C++嵌入式笔试面试集锦大纲介绍〇.简历&面试一.编程语言01.汇编02.C/C++03.Python04.版本控制工具 二.计算机基础01.计算机组成原理02.操作系统03.计算机网络04.数据结构05.计算机体系结构06.数据库07.编译原理 三.硬件相关01.硬件基础02.画图03.ARM04.单片机05.FPGA06.接口协议 四.嵌入式Linux01.嵌入式Linux开发环境搭建02.bootloader03.Linux内核04.Linux内核驱动05.文件系统构建06.系统移植07.Linux应用编程08.项目相关 五.其他01.算法02.图形学03.虚拟化04.高性能计算HPC C++嵌入式笔试面试集锦大纲介绍 正在准备秋招C++/嵌入式岗位,将相关资料整理汇集于此。觉得还可以的小伙伴可以关注一起学习。
资料整体上从以下六大方面展开(暂时先放部分目录和介绍,后续不断总结发布后修改为链接)
本集锦特点:
整理:按知识点分类和先后逻辑关系整理,方便学习和记忆。重点:一般题目(蓝色),重点题目(红色),感觉时间不够可以先看重点部分。联系:注明不同章节知识点的联系,学的时候一起学更好。 〇.简历&面试 以后分享投简历、笔试面试相关的东西
一.编程语言 01.汇编 汇编主要了解一些指令
汇编语言是一种低级的计算机语言,它与计算机硬件直接相关,包括机器指令和指令集架构。汇编语言通过使用助记符和符号代替二进制代码来编写,使程序员能够更容易地理解和编写代码。
在计算机发展的早期,汇编语言是编写软件程序的主要方式。虽然现代编程语言已经取代了汇编语言的地位,但在某些特定的应用场景下,如嵌入式系统开发、驱动程序开发、操作系统内核开发等,汇编语言仍然有其重要的地位。
汇编语言是一种面向机器的语言,因此需要对底层计算机硬件的结构和工作原理有深刻的理解。在编写汇编代码时,程序员需要直接操作计算机寄存器、内存地址和其他底层硬件组件,因此需要具备较高的技能水平和经验。
汇编语言的编程难度较大,代码可读性较差,但它具有执行效率高和可控性强等优点。对于需要高效运行和对底层硬件进行直接控制的应用程序,汇编语言仍然是一种重要的编程工具。
02.C/C++ C和C++整理在一起了,主要整理以下几点:
关键字、基本函数、预处理 关键字有static、extern、const、volatile、sizeof和strlen、struct和union、typedef和#define、auto、register、attribute、inline、final和override、mutable和explicit的相关问题
基本函数有strcpy、strncpy、sprintf与memcpy、memmove、strlen(), strstr(), strcat(), strcmp()的相关问题
预处理有头文件宏定义等问题
内存分配 C内存分配/堆栈、内存泄漏、C++内存管理、大小端、越界、字节对齐
指针 指针类型转换、指针的指针、指针与常量、指针与数组、指针与函数、结构体指针、其他(指针和引用、野指针、智能指针)
C++ 相关基础、函数(函数默认参数、函数重载)、类和封装(封装、对象的初始化和清理、对象模型和this指针、友元、运算符重载)继承、多态、模板、STL、面向对象、C++11新标准
其他 选填、代码分析等
C和C++是两种广泛使用的计算机编程语言。它们都是面向过程和面向对象的编程语言,用于编写系统软件、应用程序、驱动程序等。
C语言是由贝尔实验室的Dennis Ritchie在1972年至1973年间设计开发的。它具有简单、高效、跨平台等特点,被广泛应用于系统软件、操作系统、编译器、嵌入式系统、游戏开发等领域。C语言的语法简单、控制结构灵活、运算符丰富,它不提供面向对象编程的支持,但可以使用结构体和指针等特性来实现数据抽象和封装。
C++语言是在C语言的基础上发展而来的。它由Bjarne Stroustrup于1980年代开发,旨在扩展C语言的特性并添加面向对象编程的支持。C++语言是一种多范式编程语言,支持面向对象、泛型编程和过程式编程。C++语言提供了类、继承、多态等特性,使得代码可重用性更高、可维护性更好、开发效率更高。C++语言被广泛应用于游戏开发、图形图像处理、科学计算等领域。
总的来说,C语言和C++语言都是强大而广泛使用的编程语言。C语言适用于需要高效的、底层的编程任务,而C++语言适用于需要面向对象编程和模板元编程的任务。两种语言都有各自的优点和缺点,开发人员可以根据具体需求选择适合的语言。
03.Python Python是一种高级编程语言,由Guido van Rossum于1991年开发。Python是一种解释型语言,它具有简单、易学、易用等特点,被广泛应用于Web开发、数据科学、人工智能、机器学习、科学计算等领域。
Python具有丰富的标准库和第三方库,使得开发人员可以更快速、更高效地开发应用程序。Python的语法简洁,支持面向对象编程、函数式编程等多种编程范式。Python语言还有许多流行的框架和工具,如Django、Flask、Pytorch、Tensorflow等。
Python的语法结构简单易读,适合初学者学习。在编写Python代码时,无需担心内存管理、类型声明等问题,使得开发人员可以更专注于业务逻辑的实现。同时,Python也是一种跨平台的语言,可以运行在多种操作系统上。
总的来说,Python是一种流行且实用的编程语言,它可以帮助开发人员快速开发高质量的应用程序。它的简洁性、易读性和灵活性使得它成为学习编程的良好入门语言,同时也是许多大型项目和数据科学项目的首选语言。
04.版本控制工具 主要是SVN和Git
Git和SVN是两种常见的版本控制工具,它们都可以帮助团队协作开发软件项目。
Git是由Linus Torvalds于2005年开发的分布式版本控制系统。Git的主要特点是速度快、极端分支策略、有强大的命令行界面和大量的第三方工具支持。Git将版本库存储在本地,每个人都可以在自己的计算机上进行开发,并在需要时将其推送到中央存储库(例如GitHub、GitLab、Bitbucket等)。Git支持多个分支同时进行开发,可以合并多个分支的修改,非常适合大型项目和团队协作开发。
SVN是Subversion的缩写,是一种集中式的版本控制系统,由Apache软件基金会开发。与Git不同,SVN的版本库是集中存储在中央服务器上的,开发人员需要从服务器上获取最新代码并将其修改后提交到服务器上。SVN支持锁定机制,即开发人员在修改文件之前必须先锁定文件,以确保文件的一致性。SVN支持基于路径的访问控制和单个文件的版本控制,但对于大型项目和并行开发的场景可能不太适合。
总的来说,Git和SVN都是可靠的版本控制工具,它们各有优点和缺点。Git适合大型项目和分布式团队,支持分支策略和快速版本控制,SVN适合小型项目和集中式团队,支持路径和文件的访问控制。开发人员应该根据具体项目和团队的需求来选择适合的版本控制工具。
二.计算机基础 01.计算机组成原理 计算机组成原理是研究计算机硬件组成及其工作原理的学科。它包括计算机的各个硬件部件如CPU、存储器、输入输出设备、总线等的功能、结构、组成、工作原理、互连方式以及它们之间的相互作用等方面的内容。
计算机组成原理主要包括以下内容:
1.计算机系统结构:包括计算机的层次结构、指令系统、总线结构、存储器层次结构等。
2.数据表示与运算:研究计算机中数据的表示方式,包括二进制、十进制、八进制和十六进制等。还研究数据在计算机中的运算方式,如加、减、乘、除等算法和实现方法。
3.计算机硬件系统:包括CPU、存储器、输入输出设备、总线等硬件部件的组成和功能。
4.指令执行过程:研究CPU执行指令的过程,包括指令译码、指令执行、数据传输等环节。
5.存储器管理:研究存储器的组成、分类、层次结构和管理方式。
6.输入输出系统:研究计算机输入输出设备的种类、接口、控制方式和I/O软件系统。
计算机组成原理是计算机科学的基础学科之一,对于了解计算机硬件结构、理解计算机的工作原理和优化计算机程序都有着重要的意义。
02.操作系统 操作系统是计算机系统中最重要的软件之一,它是管理和协调计算机硬件和软件资源的核心程序。操作系统的主要功能包括资源管理、进程管理、文件系统、网络通信等方面。
感觉这篇文章太过优秀,值的收藏
漫画 | 为什么 MySQL 数据库要用 B+ 树存储索引?-CSDN博客
Flowable中文手册
一、flowable表结构 数据库表命名规则: ACT_RE_*:其中“RE”表示repository(存储)的意思,是RepositoryService 接口操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。ACT_RU_*:其中“RU”表示runtime(运行时)的意思,是RuntimeService接口操作的表。存储着流程变量,用户任务,变量,职责(job)等运行时的数据。flowable 只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。ACT_ID_* :其中“ID”表示 identity (组织机构)。这些表包含标识的信息,如用户,用户组,等等。ACT_HI_* :其中 “HI”表示 history(历史记录),是HistoryService接口操作的表。这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。ACT_GE_* : 普通数据,各种情况都使用的数据。 数据库表,不同版本可能会有些许出入: 表分类
表名
注释
一般数据(2)
ACT_GE_BYTEARRAY
通用的流程定义和流程资源(二进制格式)
ACT_GE_PROPERTY
系统相关属性
流程历史记录 (8)
ACT_HI_ACTINST
历史的流程实例
ACT_HI_ATTACHMENT
历史的流程附件
ACT_HI_COMMENT
历史的说明性信息
ACT_HI_DETAIL
历史的流程运行中的细节信息
ACT_HI_IDENTITYLINK
历史的流程运行过程中用户关系
ACT_HI_PROCINST
历史的流程实例
ACT_HI_TASKINST
历史的任务实例
ACT_HI_VARINST
历史的流程运行中的变量信息
用户用户组表 (9)
ACT_ID_BYTEARRAY
二进制资源数据表
ACT_ID_GROUP
用户组信息表
ACT_ID_INFO
用户信息详情表
ACT_ID_MEMBERSHIP
人与组关系表
ACT_ID_PRIV
权限表
ACT_ID_PRIV_MAPPING
用户或组权限关系表
ACT_ID_PROPERTY
属性表
ACT_ID_TOKEN
系统登录日志表
ACT_ID_USER
用户表
流程定义表 (3)
ACT_RE_DEPLOYMENT
部署单元信息
ACT_RE_MODEL
模型信息
ACT_RE_PROCDEF
已部署的流程定义
这里我们主要分析生命周期从以下方法进入:
bean的实例化(开辟内存空间)-》bean的属性填充-》bean的初始化;
SpringBean的加载肯定是找到Bean的定义信息,来源有xml、yml等文件;
调用如下入口方法,加载配置文件进入源码解析;
先缕清大体脉络,后深入;
入口:
ClassPathXmlApplicationContext()创建spring以用程序上下文, 调用构造方法,设置配置文件路径到当前应用程序中,开始进入容器的创建和刷新环节 refresh(); AbstractApplicationContext()的refresh(); bean的生命周期从创建到销毁共12个流程方法,总体流程脉络如下:
// 刷新spring容器前的准备,例如清空缓存 prepareRefresh(); // 获取一个全新的工厂bean ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 设置一些bean工厂的属性 lijiaqi prepareBeanFactory(beanFactory); // 注册bean的增强器 postProcessBeanFactory(beanFactory); // 调用上面注册的bean工厂的增强器(bean工厂) invokeBeanFactoryPostProcessors(beanFactory); // 注册所有的 Bean 后处理器(bean) registerBeanPostProcessors(beanFactory); // 用于初始化消息源 ! initMessageSource(); // 用于初始化事件多播器! initApplicationEventMulticaster(); // 模板方法模式,用于执行特定方法 onRefresh(); // 注册所有的监听器 registerListeners(); // 完成非惰性单例的实例化 finishBeanFactoryInitialization(beanFactory); // 发布相应的事件 finishRefresh(); bean的实例化主要方法(spring最易懂,只有do开头才是干事的方法)
记住下面流程的方法顺序我们在源码中找出来
getBean()->doGetBean()->createBean()->doCreateBean()->createBeanInstance()->instantiateBean()->instantiate()->BeanUtils.instantiateClass(constructorToUse)->ctor.newInstance(argsWithDefaultValues)->T inst = (T) ca.newInstance(initargs);
开始深入实例化方法的解析:
进入之后主要看最后的方法往里进,需要看两个地方
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
1、页面跳转,先看效果
点击表格中的asin会跳转到亚马逊购物界面
怎么做的呢,直接上代码
<el-table-column prop="asin" label="asin" width="150" fixed> <template slot-scope="scope"> <el-link :href="scope.row.url" type="primary" target="_blank">{{scope.row.asin}}</el-link> </template> </el-table-column> asin那一列通过<template>标签把scope传进去,scope是包含这一行的信息的,在标签里面使用<el-link>标签配合数据里面的url实现页面跳转,获取某个属性可以通过scope.row.属性名 获取
2、路由切换加传参数,先看效果
点击标题
可以看到路由切换到产品分析了,并且asin数据也传递过去了
实现直接看代码(需要注意的是需要传参的话只能使用name属性,使用path属性跳转是不能传递参数的)
<el-table-column prop="title" label="标题" width="150" :show-overflow-tooltip="true"> <template slot-scope="scope"> <router-link :to= "{name: 'productsAnalysis',params: {asin: scope.row.asin }}"> <span> {{scope.row.title}} </span> </router-link> </template> </el-table-column> 可以看到路由切换与页面跳转类似,都是通过<template>标签实现的,区别就是<router-link>里面直接
{{scope.row.title}}不好使,需要借助<span>标签实现内容展示 路由切换使用路由名字
productsAnalysis,点击标题时路由器会找到productsAnalysis路由,并且把参数params传过去,看一下我的路由怎么实现的吧 { path: '/console', component: Layout, redirect: '/console/productsAnalysis', name: 'console', meta: { title: '销售', icon: 'el-icon-s-help' }, children: [ { path: 'productsAnalysis', name: 'productsAnalysis', component: () => import('@/views/products/productsAnalysis'), meta: { title: '产品分析', icon: 'table' } }, { path: 'productPerspective', name: 'productPerspective', component: () => import('@/views/products/productPerspective'), meta: { title: '产品透视', icon: 'table' } } ] }, 可以看到路由名为productsAnalysis的会跳转到
一.介绍 1. Docker是什么 1、Docker是基于Go语言实现的云开源项目,诞生于2013年初,最初是dotCloud公司发起。
2、Docker通过对应用组件的封装、分发、部署、运行等生命周期的管理,达到应用组件级别的“一次封装,到处运行”。这里应用组件,即可以是Web应用,也可以是一套数据库服务,甚至是一个操作系统或编译器。
3、Docker通俗理解就只需要两句口号: “Build, Ship and Run (搭建、发送、运行)”“Build once,Run anywhere(搭建一次,到处能用)” 2、Docker作用 1、快速搭建重复环境 2、保证开发测试等环境完全相同 3. Docker组成 镜像(Image)容器(Container)仓库(Repository) 二.Docker安装 注意:Linux centOS(版本大于等于7.0)
1. 删除旧版本 sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-selinux \ docker-engine-selinux \ docker-engine 2. 安装必备工具 yum install -y yum-utils device-mapper-persistent-data lvm2 3. 添加Docker源 yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo 4. 更新yum缓存 yum makecache fast 5. 安装 yum install docker-ce 6.
1. 安装Anaconda 登录网页:https://www.anaconda.com/ 安装时默认下一步就好,唯一需要注意的是设置的安装路径中最好不要有中文(否则可能会报各种奇奇怪怪的错误)
2. 打开Anaconda Prompt(Anaconda) 第一步安装完成后,开始菜单下会出现如下所示多个图标,找到下图红框内的图标,打开会出现一个命令行窗口。
3. 在命令行中输入命令 关注同名公众号,后台回复:"pymol"获取pymol安装包,将安装包内的文件拷贝到桌面。
在上面打开的命令行中逐行输入如下命令,并逐行回车:
cd desktop conda create -n pymol python=3.8 -y 完成之后出现下图所示页面:
继续在命令行中逐行输入如下命令,并逐行回车:
conda activate pymol pip install Pmw-2.0.1-py3-none-any.whl pip install pymol-2.6.0a0-cp38-cp38-win_amd64.whl 出现下图所示的“Successfully…”提示表明安装正常:
如果你想要让自己的pymol页面框变得更有质感,可以继续在命令行中输入如下内容并回车:(这一步非必须,可以跳过)
pip install PyQt5 -i https://pypi.douban.com/simple 至此,pymol安装完毕。
4. 运行pymol 打开第一步Anaconda安装路径,按照路径envs >> pymol >> Scripts依此打开,在Scripts文件夹下有可执行的pymol.exe。为了方便以后调用,可以左击创建桌面快捷方式。
Rust堆栈 Rust中各种类型的值默认都存储在栈中,除非显式地使用Box::new()将它们存放在堆上,但数据要存放在栈中,要求其数据类型的大小已知。对于静态大小的类型,可直接存储在栈上,如裸指针、布尔、字符、整数浮点数,数组等。
动态大小的(Vec、string)都是存堆的
一些注意事项
栈中的数据赋值给变量的时候,数据是直接放在栈中的。类型的值都默认放在栈中,所以创建引用的时候,引用的是栈里的值。容器中保存的是原始类型的栈里的值或者指向堆数据的引用字符串字面量,static静态变量都会硬编码嵌入到二进制程序的全局内存区const定义的常量,会在编译期间直接以硬编码的方式内联插入到使用常量的地方,即,直接硬编码到对应代码行。同时函数也可以内联,即函数对应代码体会直接展开并插入到调用函数的地方,省去调用函数的开销。
位置与值 位置:某一块内存位置,它有自己的地址,有自己的空间,有自己所保存的值。
值:存储到位置中的数据(即保存在内存中的数据)
位置的产生
会产生变量的时候(初始化)需要保存某个值的时候(函数调用参数和返回值)产生新的值(引用,解引用)
let 语句 let a = 1;
a:为变量名,也是对内存位置的一个可读代号,编译期间会被替换为更低级的代号或者直接为地址。也就是位置,是存值1的一块内存。
每个位置就是它所放值的所有值,因为每个值都只能存放在一个位置中,所以每个值都只能有一个所有者。
let v = vec![1, 2, 3, 4];
v:位置,代表栈中的一块内存,值是一个指针地址,实际数据是放在堆里的。
引用 Rust的引用是一种原始数据类型,位置仍然是栈里,保存的值和指针一样,是一个地址。该地址指向了**位置(**也就是前面的a和v)
如
let n = 33; // 假设n的地址为0x234 let nn = &n; // 假设nn的地址为0x123 那么,nn的位置是0x123,它存的值是0x234,也就是n的地址。
编译器维护栈内存,所以它知道栈中的某个内存是否安全,而堆内存由程序员自己负责,程序员自己的行为是无法保证安全的。
所以,Rust的行为模式是将是涉及到内存安全的概念扔到栈上,让程序员远离对堆的操作。所以,允许允许对栈中同一个数据的多个指向,不允许对堆中同一个内存的多个指向,即变量存在多个引用,但所有权只能有一个。
位置的属性 位置的属性和状态都由编译器在编译期进行维护。
位置有类型,有标记(是否被引用,可变引用还是不可变,共享还是独占等等),根据位置的类型是否实现Copy Trait来决定该位置的是拷贝还是移走。
所有权和借用 变量作用域 我们知道rust 变量在脱离作用域之后就会被销毁,但事实是,变量在跳出作用域时,会自动Drop Trait的drop函数来销毁内存中堆和栈的数据,全局内存中的数据是从程序启动到终止期间一直存在。
另外rust的作用域为一对大括号{},大括号的作用域是可以访问大括号外部的变量,而在函数的作用域内则不行,这被称为捕获环境,函数是不能捕获环境的,而大括号可以捕获环境。
数据的拷贝 由于所有权问题和变量脱离作用域而引起的内存二次释放问题,rust是不允许有两个指针同时指向同一块内存的。所以rust 没有浅拷贝和深拷贝的概念,取而代之的是move、copy和clone。
move:也就是转移所有权,涉及到的过程是拷贝到目标变量,同时会将原来的变量设置到未初始的状态。rust 默认使用的就是move。 当使用值的时候,就会产生位置,那么就会发生移动。解引用,字段访问,索引访问等都会隐式移动。
copy:和move的区别就是,拷贝之后原来的变量还是可以用。如果要使用copy,就需要要拷贝的数据类型实现了Copy Trait,手动实现的时候需要同时实现Clone Trait。clone:clone和copy很接近,区别在于,Copy时,只拷贝变量本身的值,如果这个变量指向了其它数据,则不会拷贝其指向的数据。Clone时,拷贝变量本身的值,如果这个变量指向了其它数据,则也会拷贝其指向的数据。 函数调用之后也是会转移所有权的,有时候这样是很不方便的,所以在传参的时候可以传递到变量的引用,引用时保存在栈里,也实现了Copy Trait,这样效率会更高。
可变引用的排他性 不可变引用是可以共存的,但是可变引用具有排他性,在同一作用域同一数据只能有一个。
这里的排他性,应该看作一把独占锁,在当前作用域内,从第一次使用可变引用开始创建这把独占锁,之后无论使用原始变量(即所有权拥有者)、可变引用还是不可变引用都会抢占这把独占锁,以保证只有一方可以访问数据,每次抢得独占锁后,都会将之前所有引用变量给锁住,使它们变成不可用状态。当离开当前作用域时,当前作用域内的所有独占锁都被释放。
回顾一下可变引用的几个性质
很多时候在工作中会碰到完全由前端导出word文件的需求,因此特地记录一下比较常用的几种方式。
一、提供一个word模板 该方法提供一个word模板文件,数据通过参数替换的方式传入word文件中,灵活性较差,适用于简单的文件导出。需要依赖:docxtemplater、file-saver、jszip-utils、pizzip。
javascript 复制代码 import Docxtemplater from "docxtemplater"; import { saveAs } from "file-saver"; import JSZipUtils from "jszip-utils"; import PizZip from "pizzip"; export function downloadWithTemplate(path, data, fileName) { JSZipUtils.getBinaryContent(path, (error, content) => { if (error) throw error; const zip = new PizZip(content); const doc = new Docxtemplater().loadZip(zip); doc.setData({ ...data.form, // 循环项参数 list: data.list, outsideList: data.outsideList, }); try { doc.render(); } catch (error) { const e = { message: error.
在本博客中,你将学习创建一个 LangChain 应用程序,以使用 ChatGPT API 和 Huggingface 语言模型与多个 PDF 文件聊天。
如上所示,我们在最最左边摄入 PDF 文件,并它们连成一起,并分为不同的 chunks。我们可以通过使用 huggingface 来对 chunks 进行处理并形成 embeddings。我们把 embeddings 写入到 Elasticsearch 向量数据库中,并保存。在搜索的时候,我们通过 LangChain 来进行向量化,并使用 Elasticsearch 进行向量搜索。在最后,我们通过大模型的使用,针对提出的问题来进行提问。我们最终的界面如下:
如上所示,它可以针对我们的问题进行回答。进一步阅读 使用 LangChain 和 Elasticsearch 对私人数据进行人工智能搜索 使用 LangChain 和 Elasticsearch 的隐私优先 AI 搜索
所有的源码可以在地址 GitHub - liu-xiao-guo/ask-multiple-pdfs: A Langchain app that allows you to chat with multiple PDFs 进行下载。
安装 如果你还没有安装好自己的 Elasticsearch 及 Kibana 的话,那么请参考如下的链接:
如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
Kibana:如何在 Linux,MacOS 及 Windows 上安装 Elastic 栈中的 Kibana
第2章 CUDA中的线程组织 2.1 C++语言开发过程 1. 用文本编辑器写一个源代码(source code)。
2. 用编辑器对源代码进行预处理、编译、汇编并链接必要的文件得到可执行文件。这些步骤往往可由一个命令完成。
3. 运行可执行文件得到结果。
2.2 CUDA中的Hello World程序 2.2.1 只有主机的函数的CUDA程序 CUDA程序的编译器nvcc在编译一个CUDA程序时,会将纯粹的C++代码交给C++编译器(如前面提到的g++或cl)去处理,它自己则负责编译剩下的部分。CUDA程序的源文件的扩展名是.cu。
2.2.2 使用核函数的CUDA程序 cuda中的核函数必须被限定词__global__修饰。核函数返回类型必须是空类型。
一个典型、简单的CUDA程序的结构具有以下形式:
1.头文件包含;
2.常量定义(或者宏定义);
3.C++ 自定义函数和CUDA核函数声明(原型);
4.C++ 自定义函数和CUDA核函数的定义(实现);
int main(void) { 分配主机与设备内存; 初始化主机中的数据; 将某些数据从主机复制到设备; 调用核函数在设备中进行计算; 将某些数据从设备复制到主机; 释放主机与设备内存; return 0; } 主机在调用一个核函数时,必须指明需要在设备中指派多少个线程。
2.3 CUDA中的线程组织 2.3.2 使用线程索引 核函数调用格式:
kernal<<<grid_size, block_size>>>(); 其中三尖括号中的数来指明核函数中的线程数目及排列情况。grid_size表示线程块的个数, block_size表示每个线程块中的线程数。
若干线程(thread)构成一个线程块(block)。每个线程块含有相同数目的线程,该数目即为线程块大小(block size)。
一个核函数的全部线程块构成一个网格(grid),而线程块的个数即为网格大小(grid size)。核函数中线程数目 = grid size * block size;
执行配置(execution configuration) : <<<grid_size, block_size>>>。一般来说,grid_szie与block_size是一个结构体类型(dim3 grid_size(x, y, z), dim3 block_size(x, y, z))的变量,但也可以是一个普通的整形变量, 没有指定的成员值将默认取1。
一.背景介绍 ViewResolver主要作用是将逻辑视图名称解析为真正的视图对象View,即将视图解析为可以在客户端呈现的HTML页面。
二.源码分析 ViewResolver 视图解析器:将视图名转换成视图对象
public interface ViewResolver { @Nullable View resolveViewName(String viewName, Locale locale) throws Exception; } View 视图对象:
public interface View { String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus"; String PATH_VARIABLES = View.class.getName() + ".pathVariables"; String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType"; @Nullable default String getContentType() { return null; } void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception; } AbstractView public abstract class AbstractView extends WebApplicationObjectSupport implements View, BeanNameAware { @Override public void render(@Nullable Map<String, ?
nuxt3 useFetch请求封装
首先在composables文件下新建http.js文件,composables文件下不需要引入
import { showToast, showLoadingToast } from 'vant'; import store from "@/store" const request = async (url, options) => { await nextTick(); //解决刷新页面useFetch无返回 const config = useRuntimeConfig(); const reqUrl = config.public.apiBase + url; const customHeaders = {"APP-TOKEN": `${store.state.token}`, "Content-Type": "application/json" } // console.log(reqUrl,'reqUrl') console.log('options:--',options) // console.log('headers:',headers) // const options=options||'' return new Promise((resolve, reject) => { useFetch(reqUrl, { ...options, headers:customHeaders}).then(({ data, error }) => { console.log(data,'data') if (error.value) { reject(error.
前言
最近在部署算法在板子侧遇到的一些问题汇总一下:
一、版本问题 经过测试现在将自己环境配置如下:
本地linux安装rknn-toolkit2-1.5.0 本地Linux使用的miniconda新建的一个python虚拟环境(自行网上查找相关方法)
安装好自己的虚拟环境之后:安装所需的依赖包 sudo apt-get install libxslt1-dev zlib1g-dev libglib2.0 libsm6 libgl1-mesa-glx libprotobuf-dev gcc 将官方的RKNN-Toolkit2库git到linux本地:(如果提示没有找到git命令,使用:sudo apt install git-all安装git工具) git clone https://github.com/rockchip-linux/rknn-toolkit2 进入 Toolkit2 工程文件夹, 根据工程的保存路径修改 cd 命令中的路径。 cd ~/rknn-toolkit2 安装必要相应版本的依赖包(这里我安装和我自己linux匹配的py3.8版本) pip3 install -r doc/requirements_cp38-1.5.0 安装 RKNN-Toolkit2(Python3.6 for x86_64) pip3 install package/rknn_toolkit2-1.5.0+1fa95b5c-cp38-cp38-linux_x86_64 检查 RKNN-Toolkit2 是否安装成功。 出现这个界面,就说明本地linux端的安装已经成功,
可以运行官方的examples案例检测:rknn-toolkit2/examples/onnx/yolov5
板子RK3568环境安装 git源码到板子上 git clone https://github.com/rockchip-linux/rknn-toolkit2 cd ./rknn_toolkit_lite2 文件结构如下:
环境安装 sudo apt update #安装python工具等 sudo apt-get install python3-dev python3-pip gcc #安装相关依赖和软件包 pip3 install wheel sudo apt-get install -y python3-opencv sudo apt-get install -y python3-numpy sudo apt -y install python3-setuptools Toolkit Lite2工具安装: # 进入到rknn_toolkit_lite2目录下, cd rknn_toolkit_lite2/ # ubuntu22 python3.
需求说明: 用户希望我们能提供一个在本地运行的”web+后端“的二进制程序,但是在本地肯定希望运行越简单越好,如果把前端代码放到nginx,增加了用户的操作复杂度。但是如果通过tmpl的方式书写前后端不分离项目,对开发人员又不是很友好。
那怎样才能让开发人员在书写代码的时候,依然和前后端分离项目一样书写代码,但在用户端只需要运行一个二进制程序呢?通过搜索,发现embed 能帮助我们实现该功能,下面是我们的项目说明。
1.准备一个vue cli相关的项目 我项目地址为:
项目地址
前端项目完成后,执行yarn build 生成静态文件
2.golang 后端项目说明 我项目地址为:
项目地址
2.1把vue的静态文件放到golang项目中,并写好html.go文件 2.2修改下index.html中内容 2.3路由配置 2.4本地运行测试 只运行后端
通过后端8877端口访问
测试成功后,直接go build编译go程序即可,编译好后直接运行go程序,通过go的运行端口访问即可。
前言 文章来源:CSDN@LawsonAbs 1.软连接 1.1 语法 ln -s source target
解释下:
ln -s:表示创建一个软连接;
target:表示目标文件(夹)【即被创建的文件(夹)】
source:表示当前已存在的文件(夹)名【故称之为源】
1.2 具体示例 step 1.创建测试文件及文件夹 [root@server6 ~]# mkdir test_chk [root@server6 ~]# touch test_chk/test.txt [root@server6 ~]# echo "hello spark" > test_chk/test.txt [root@server6 ~]# cat test_chk/test.txt hello spark [root@server6 ~]# ll 总用量 84 -rw-------. 1 root root 1257 6月 16 01:17 anaconda-ks.cfg drwxr-xr-x. 25 root root 4096 11月 1 10:28 azkabanJob -rw-r--r--. 1 root root 67322 11月 4 10:24 azkabanJob.
当今的应用程序越来越多地采用了微服务架构,这就引出了一个重要的问题:如何实现单点登录(Single Sign-On,简称SSO)来确保用户在多个微服务之间无需重复登录。Spring Boot是一个流行的Java框架,它提供了一些有用的工具和库来实现SSO。在本文中,我们将探讨如何使用Spring Boot来实现SSO。
什么是单点登录(SSO)? 单点登录是一种身份验证机制,允许用户只需一次登录,即可在多个应用程序或服务之间访问资源,而无需在每个服务中重新输入凭证。这提供了更好的用户体验,同时提高了安全性,因为用户的凭证仅在一处验证。
实现SSO的关键概念 要理解如何在Spring Boot中实现SSO,首先需要了解一些关键概念:
身份提供者(Identity Provider,简称IdP):这是负责验证用户身份并生成令牌的服务。常见的IdP包括Okta、Auth0、Keycloak和Spring Security等。
服务提供者(Service Provider,简称SP):这是应用程序或服务,需要验证用户身份的服务。SP将重定向用户到IdP以进行身份验证,并验证从IdP返回的令牌。
令牌(Token):这是一个包含用户身份信息的数据块,通常是JSON Web Token(JWT)。令牌包含用户的声明,例如用户名、角色和其他有关用户的信息。
单点登录流程:通常包括以下步骤:
用户访问SP。SP检查用户是否已经登录,如果未登录,则重定向到IdP进行身份验证。用户在IdP上进行身份验证。IdP颁发令牌并将用户重定向回SP。SP验证令牌并为用户提供访问。 使用Spring Boot实现SSO 下面是使用Spring Boot实现SSO的基本步骤:
步骤1:创建Spring Boot应用程序 首先,您需要创建一个Spring Boot应用程序,作为服务提供者。您可以使用Spring Initializr或手动创建项目。
步骤2:配置Spring Security 在Spring Boot应用程序中,您可以使用Spring Security来处理身份验证和授权。配置Spring Security以允许SSO,并指定您的IdP的信息。
spring: security: saml2: relyingparty: registration: idp-issuer: <IdP Issuer URL> entity-id: <SP Entity ID> assertion-consumer-service-url: <Assertion Consumer Service URL> 步骤3:设置SSO过滤器 创建一个SSO过滤器,它将拦截需要身份验证的请求并将用户重定向到IdP以进行登录。
import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.security.web.authentication.logout.SamlLogoutProcessingFilter; @Configuration public class SSOConfig { @Autowired private SAMLConfigurer samlConfigurer; @Bean public SamlLogoutProcessingFilter samlLogoutProcessingFilter() { SamlLogoutProcessingFilter filter = new SamlLogoutProcessingFilter(); filter.
文章目录 一、JAR的定义二、JAR的分类三、JAR在Android中的使用四、动态JAR在Android源码中的实现 一、JAR的定义 JAR文件(Java归档,英语:Java Archive)是一种软件包文件格式,以ZIP格式构建,以.jar为文件扩展名,通常用于聚合大量的Java类文件、相关的元数据和资源(文本、图片等)文件到一个文件,以便开发Java平台应用软件或库。
二、JAR的分类 JAR文件,可分为静态JAR包和动态JAR包,其中,
静态JAR包:参与编译,并打包进apk中,占用APK空间;动态JAR包:参与编译,不打包进apk中,运行时加载; 三、JAR在Android中的使用 在Android-Studio环境下
项目的依赖库,需要修改工程下的build.gradle文件: 静态JAR
一般用于引用第三方的依赖库、模块,如: compile files('libs/commonApi.jar') 动态JAR
常见的应用场景就是引用系统框架库,如: compileOnly files('libs/framework.jar') 在Android源码环境下
项目的依赖库,需要修改对应模块下的Android.mk 或 Android.bp文件: 静态JAR LOCAL_STATIC_JAVA_LIBRARIES := commonApi 动态JAR LOCAL_JAVA_LIBRARIES := commonApi 四、动态JAR在Android源码中的实现 添加一个JAR模块将对应JAR包引入Android工程,参与工程编译将JAR添加至PRODUCT_BOOT_JARS(build/target/product/core_minimal.mk) PRODUCT_BOOT_JARS := \ ... framework \ ... commonApi 添加至白名单(build/core/tasks/check_boot_jars/package_whitelist.txt) ################################################### # commonApi.jar com\.zhiqin\.commonApi\..* ps:在Android11未添加该值,功能正常,该条件不确定是否必要
烧写系统system.img,通过adb shell指令验证查看该jar是否导入BOOTCLASSPATH,以验证是否生效 C:\Users\linzhiqin>adb shell $BOOTCLASSPATH /system/bin/sh: /system/framework/core-libart.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/mms-common.jar:/system/framework/commonApi.jar
文章目录 一、使用Docker部署的好处二、Docker 与 Kubernetes 对比三、云耀云服务器L实例 Docker 部署 Redis四、可视化工具连接Redis⛵小结 一、使用Docker部署的好处 Docker的好处在于:在不同实例上运行相同的容器
Docker的五大优点: 持续部署与测试、多云服务平台支持、环境标准化和版本控制、隔离、安全
二、Docker 与 Kubernetes 对比 Docker适用于较为小的应用,并发量不大的情况下、微服务为超过10个,建议适用Docker部署,这样也省资源、可减少开发成本。
K8S适用于大集群的情况,高并发,并且微服务超过了10个,同时性能也是非常好的,性能好的前提下,开发成本也增加了不少!
三、云耀云服务器L实例 Docker 部署 Redis 云耀云服务器L实例购买
打开华为云官网
新用户可以领取更多的大额优惠,购买更划算。
购买后进入 云耀云服务器L实例 控制台,复制IP地址通过xshell远程链接。
进入后复制 公网弹性 IP地址,进行远程链接
连接云耀云服务器L实例
新建回话 输入ip地址,密码 即可链接成功 如下:
docker 查询 redis镜像
docker search redis 获取Reids 最新镜像
docker pull redis:latest 查询docker镜像
运行Redis容器
命令详解
-p 6379:6379:映射容器服务的 6379 端口到宿主机的 6379 端口。外部可以直接通过宿主机ip:6379 访问到 Redis 的服务。
查询运行中的容器信息
docker ps 通过redis-cli测试连接
docker exec -it my-redis /bin/bash 以上命令已设置redis密码为 123456,测试 连接成功~
一、函数(function) 定义:一段可以完成某个功能的代码。
使用函数:通过函数名即可调用函数,可以让计算机完成某个功能
举例:输入两个数,输出两个数中最大的数
a=int(input()) b=int(input()) c=max(a,b) print(c) 分析:max()函数 功能:返回给定参数的最大值,参数可以为序列。 语法:max(x, y, z, ....) #参数可以有若干个 分类:
系统函数:提供给用户的一系列已经编制好的程序
自定义函数:用户根据自己需求编写的一段程序
系统函数 目前python版本提供的系统函数:
官方文档查询:https://docs.python.org/3.7/library/functions.html
Built-in Functions abs()
delattr()
hash()
memoryview()
set()
all()
dict()
help()
min()
setattr()
any()
dir()
hex()
next()
slice()
ascii()
divmod()
id()
object()
sorted()
bin()
enumerate()
input()
oct()
staticmethod()
bool()
eval()
int()
open()
str()
breakpoint()
exec()
isinstance()
ord()
sum()
bytearray()
filter()
issubclass()
pow()
super()
bytes()
float()
iter()
print()
tuple()
callable()
ROS 2官方文档(基于humble版本)学习笔记(三) 理解参数(parameter)ros2 param listros2 param getros2 param setros2 param dumpros2 param load在节点启动时加载参数文件 理解动作(action)ros2 node inforos2 action listros2 action list -tros2 action inforos2 interface showros2 actiong send_goal 使用rqt_console查看日志设置默认日志级别 启动节点记录和回放数据记录多个话题ros2 bag inforos2 bag play 今天继续总结CLI 工具章的学习
理解参数(parameter) 参数是一个节点的配置值,可以把参数看成是节点的配置。节点可以存储整型,浮点型,布尔型,字符串型,列表型的参数。每个节点维护自己的参数。
ros2 param list 此命令用于显示所有节点的参数。
每个节点都有use_sim_time
ros2 param get 此命令用于显示一个参数的类型和当前值。
ros2 param get <node_name> <parameter_name> ros2 param set 此命令在运行时改变参数的值。
ros2 param set <node_name> <parameter_name> <value> ros2 param dump 此命令查看所有节点的参数值。
ros2 param dump <node_name> 默认打印到标准输出,可以将参数值打印到文件中,比如:
一、什么是分支 1.在版本控制系统(如Git)中,分支(Branch)是代码库的不同线路或路径,用于同时进行不同的开发工作。分支可以将代码库的状态 ‘‘复制’’ 到一个独立的环境中,使得在这个分支上进行的更改不会影响到其他分支。
2.使用分支的好处是可以同时进行多个并行的开发任务,每个任务都在自己的分支上进行。这样可以有效地隔离不同的功能开发、修复bug或其他任务,而不会互相干扰。完成一个任务后,可以将该分支的更改合并回主分支(通常是"master"或"main"分支),从而将新功能或修复应用到代码库的主干中。
3.分支让开发团队能够更灵活地管理代码的开发和发布过程。它们可以同时处理多个功能或任务,并且在开发过程中可以频繁地创建、合并和删除分支,以适应不同的开发需求。
4.在分支内部,所有与该分支相关的更改都是相对独立的,因此可以在不影响其他分支的情况下进行实验、测试和修改。分支也有助于团队合作,因为不同的开发人员可以在各自的分支上独立工作,而不会相互干扰。
5.总之,分支是版本控制系统中的一个重要概念,它提供了并行开发、隔离工作和代码管理的机制,使得团队能够更加高效地协同工作和管理代码库。
总结:分支就是基于主支创建出来的一个"副本"(不是简单复制),在分支上修改的内容不会直接影响主支,且各个分支的内容相互独立。在分支上更新调试好后在将分支与主支合并,完成更新。分支只存放修改和更新的内容,而与主支一样的内容会直接引用。
内容补充:
在 Git 中,创建分支并不是将代码库的完整副本复制一份,而只是创建了一个指向特定提交(commit)的指针。实际上,在创建分支时,Git 仅仅创建了一个新的指针,该指针指向当前所在分支的最后一个提交(commit)。这样,新分支就可以独立地进行新增、修改和删除文件操作,而不会影响其他分支。由于 Git 使用的是基于快照(snapshot)的版本控制系统,每次提交(commit)都会记录项目的状态,因此创建新的分支并不需要复制整个代码库的副本。分支间共享大部分历史提交(commits),只有新分支上的更改会产生新的提交记录。因此,通过创建分支,您实际上是在给定的提交(commit)上创建了一个新的指针。这使得在不同的分支之间进行切换、合并和处理独立的开发任务变得非常高效和灵活。
二、相关命令 查看分支
git branch 创建分支
git branch 分支名 删除分支
git branch -d 分支名 切换分支
git checkout 分支名称 分支合并(可能会产生冲突,需要手动解决)
git merge 合并分支的名称 注意:切换分支在合并,会合并到自己所在分支 查看远程分支
git branch -r 推送并创建远程分支
git push origin 分支名字 删除远程分支
git push origin --delete 分支名字 三、简单实例演示 只在本地仓库演示: 1. 新建一个文件夹,在该目录下打开git命名
使用 git init 初始化本地仓库 成功后会出现 .git文件 (如果没有点击 菜单栏上的 查看–勾选 隐藏 项目)
然后 新建一个文件,如果没有文件无法查看分支
要配置Maven,您可以按照以下步骤进行操作:
下载和安装Java Development Kit(JDK):首先,确保您已经安装了适用于您操作系统的JDK版本,并将其正确地设置为JAVA_HOME环境变量。
下载和安装Maven:访问Maven官方网站(https://maven.apache.org/),下载适用于您操作系统的最新Maven版本,并按照安装说明进行安装。
配置Maven环境变量:将Maven的bin目录添加到您的系统路径中。这将使您能够从任意终端窗口运行Maven命令。
验证Maven安装:在终端中运行以下命令来验证Maven是否正确安装:
mvn -v 如果一切正常,您将看到Maven的版本信息。
配置Maven项目:现在您可以开始使用Maven来创建和管理项目。进入您希望使用Maven的项目目录,并执行以下命令:
mvn archetype:generate Maven将提示您选择项目模板(archetype)。根据您的需求进行选择,并按照提示完成项目配置过程。
配置依赖项:在项目的pom.xml文件中,您可以定义所需的依赖项。通过将依赖项的坐标添加到<dependencies>标签下,Maven将自动从中央仓库下载这些依赖项,并将其添加到您的项目中。
构建和运行项目:使用Maven命令构建您的项目,例如:
mvn clean install Maven将执行项目的构建过程,并在目标目录中生成可执行文件或部署包。根据项目需求,您可以使用其他Maven命令进行测试、打包和部署等操作。