SwiftUI 6.0(iOS 18)ScrollView 全新的滚动位置(ScrollPosition)揭秘

概览 在只有方寸之间大小的手持设备上要想体面的向用户展示海量信息,滚动视图(ScrollView)无疑是绝佳的“东牀之选”。 在 SwiftUI 历史的长河中,总觉得苹果对于 ScrollView 视图功能的升级是在“挤牙膏”。这不,在本届最新 WWDC24 重磅打造的 SwiftUI 6.0 中就让我们来看看 ScrollView 又能挤出怎样的新花样吧? 在本篇博文中,您将学到如下精彩的内容: 概览1. SwiftUI 6.0 之前的滚动世界2. SwiftUI 6.0(iOS 18)中全新的 ScrollPosition 类型3. “新老搭配,干活不累”4. 如何判断当前滚动是由用户指尖触发的?5. 实时监听滚动视图的内容偏移(ContentOffset)总结 在 WWDC24 里,苹果对 SwiftUI 6.0 中滚动视图的全新升级无疑解了一众秃头码农们的额燃眉之急。 那还等什么呢?让我们马上开始滚动大冒险吧! Let‘s rolling!!!😉 1. SwiftUI 6.0 之前的滚动世界 苹果从 SwiftUI 2.0 开始陆续“发力”向 ScrollView 增加了许多新特性,其中包括秃头码农们翘首跂踵的滚动位置读取与设置、滚动模式等高级功能。 在 SwiftUI 6.0 之前,我们是通过单一状态来读取和设置滚动位置的: struct ContentView: View { @State private var position: Int? var body: some View { ScrollView { LazyVStack { ForEach(0..<100) { index in Text(verbatim: index.

pyttsx3:Python文本到语音转换库的全面指南

目录 引言 一、pyttsx3 简介 二、安装 pyttsx3 三、基本用法 四、配置语音属性 五、支持的命令和功能 六、高级用法 结语 引言 在当今的软件开发中,提供语音交互功能已成为提升用户体验的一种重要方式。Python,作为一种广泛使用的编程语言,拥有丰富的库来实现各种功能。pyttsx3 是一个强大的文本到语音(Text-to-Speech,TTS)转换库,它允许开发者轻松地将文本转换为语音。本文将详细介绍 pyttsx3 的安装、基本用法以及一些高级功能。 一、pyttsx3 简介 pyttsx3 是一个基于 pyttsx 的库,它使用 SAPI5 (仅限Windows), NSSpeechSynthesizer (仅限macOS) 和 espeak 作为后端来实现文本到语音的转换。这意味着 pyttsx3 可以在不同的操作系统上工作,并且支持多种语言。 二、安装 pyttsx3 安装 pyttsx3 非常简单,你只需要在你的Python环境中运行以下命令: pip install pyttsx3 注意:最好使用默认的pip源地址,不要使用其他镜像源,可能会下载失败,最好更新一下你的pip版本 pip install --upgrade pip 三、基本用法 安装完成后,你可以使用以下代码来测试 pyttsx3 的基本功能: import pyttsx3 # 初始化引擎 engine = pyttsx3.init() # 将文本转换为语音 engine.say('欢迎使用pyttsx3库') # 运行引擎 engine.runAndWait() 四、配置语音属性 pyttsx3 允许你配置语音的多种属性,包括速率、音量和语音类型: # 设置语音属性 engine.setProperty('rate', 150) # 语速 engine.

C语言从入门到进阶(15万字总结)

前言: 《C语言从入门到进阶》这本书可是作者呕心沥血之作,建议零售价1元,当然这里开个玩笑。 本篇博客可是作者之前写的所有C语言笔记博客的集结,本篇博客不止有知识点,还有一部分代码练习。 有人可能会问,作者不会是cv战士吧!作者在这里回答大家,有cv战士的成分,但不完全是。我是将之前博客冗余的部分删除。有句话叫取其精华,去其糟粕当嘛!当然作者除了删除冗余部分还会修改一小部分,因为之前写博客的技术还不太成熟,当然现在也不太成熟。所以还是要靠大家的支持作者才有十分的动力去创作,所以在这里要感谢大家的支持,也感谢每一位能进来看一下的读者。那么废话不多说,我们现在就开始。 注:右下角也有目录,可以通过右下角的目录跳到对应的知识点。 目录: 目录 ​编辑 第一章:初识C语言 1、C语言是什么? 2、第一个C语言程序 3、main函数 4、库函数 4.1 头文件详解 5、关键字介绍 6、字符和ASCII编码 7、字符串和 ' \0 ' 8、转义字符 9、语句和语句分类 12.1 空语句 12.2 表达式语句 12.3 函数调用语句 12.4 复合语句 12.5 控制语句 13、注释是什么?为什么写注释? 13.1注释的2种形式 13.2注释会被替换 第二章:数据类型和变量 1、数据类型的介绍 1.1 字符类型 1.2 整型 1.3 浮点型 1.4 布尔类型 2、signed和unsigned 3、数据类型的取值范围 4、变量 4.1 变量的创建 4.2 变量的分类 5、算术操作符:+、-、*、/、% 5.1 + 和 - 5.2 * 和 / 5.3 %操作符 6、赋值操作符:=和复合赋值 6.1 连续赋值 6.3 复合赋值

Kafka~基础原理与架构了解

Kafka是什么 Kafka我们了解一直认为是一个消息队列,但是其设计初,是一个:分布式流式处理平台。流平台具有三个关键功能: 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。容错的持久方式存储记录消息流:Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险。流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。 Kafka 主要有两大应用场景: 消息队列:建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。大吞吐量流式数据处理: 构建实时的流数据处理程序来转换或处理数据流。 Kafka支持的俩种模型: 队列模型:使用队列(Queue)作为消息通信载体,满足生产者与消费者模式,一条消息只能被一个消费者使用,未被消费的消息在队列中保留直到被消费或超时。 比如:我们生产者发送 100 条消息的话,两个消费者来消费一般情况下两个消费者会按照消息发送的顺序各自消费一半。订阅模型(Pub-Sub) 使用主题(Topic) 作为消息通信载体,类似于广播模式;发布者发布一条消息,该消息通过主题传递给所有的订阅者,在一条消息广播之后才订阅的用户则是收不到该条消息的。 核心概念 Producer、Consumer、Broker、Topic、Partition,我们一一介绍。 Kafka 将生产者发布的消息发送到 Topic(主题) 中,需要这些消息的消费者可以订阅这些 Topic(主题),如下图所示: 生产者(Producer)::生产者负责将消息发布到Kafka集群中的一个或多个主题(Topic),每个Topic包含一个或多个分区(Partition)Consumer(消费者) : 消费者负责从Kafka集群中的一个或多个主题消费消息,并将消费的偏移量(Offset)提交 回Kafka以保证消息的顺序性和一致性。Broker(代理) : 可以看作是一个独立的 Kafka 实例。多个 Kafka Broker 组成一个 Kafka Cluster。 Leader Broker:Leader Broker 是分区的主副本,它是负责处理消息读写请求的节点。生产者将消息发送到Leader Broker,消费者从 Leader Broker中拉取消息。 Follower Broker:Follower Broker 是 Leader Broker的备份节点,它负责与Leader Broker进行数据同步,以保持自己的数据与 Leader Broker保持一致。 Topic(主题) : Producer 将消息发送到特定的主题,Consumer 通过订阅特定的 Topic(主题) 来消费消息。 Partition(分区) : Partition 属于 Topic 的一部分。一个 Topic 可以有多个 Partition ,并且同一 Topic 下的 Partition 可以分布在不同的 Broker 上,这也就表明一个 Topic 可以横跨多个 Broker 。

day2-web安全漏洞攻防-基础-弱口令、HTML注入(米斯特web渗透测试)

day2-web安全漏洞攻防-基础-弱口令、HTML注入(米斯特web渗透测试) 1,漏洞2,弱口令3,爆破(1)Burpsuite(2)攻击类型 4,HTML针剂注入 1,漏洞 挖掘和利用的是什么东西,漏洞(web应用存在的缺陷) 网站的前后端结构,前端是发生在浏览器上的漏洞,后端是发生在服务器上的漏洞 我们如何区分这些前端后端如HTML注入是前端的,将HTML代码注入到页面中就是前端的一个漏洞。 2,弱口令 弱口令(既不是前端也不是后端,关系到自己的安全意识,密码弱点) 也有第二种弱口令(使用社工,人性的弱点姓名首拼音,出生年月) 第一种傻瓜型的弱口令,会给你一份字典,总结了很多的常用型的弱口令 第二种需要使用一款在线的web应用工具,这工具源码会给你们,自己会PHP的也可以自己去读,如果不会PHP的等会安装教你们如何本地使用,这款工具叫密码字典生成工具。这个PHP文件直接放在phpstudy网站根目录下就能本地运行,用本地浏览器可打开。 因为caimima这个PHP文件未能找到,找到了一个替代性工具safe6社工爆破密码生成器的jar包,已经上传到kali系统中,可以运行。 弱口令这么多我们肯定是使用工具的手工不可能一个一个去输入,那所以说,弱口令这个漏洞不是网站的问题,当然网站也有问题(注册时未说明禁止弱口令),一般弱口令在登录处尝试,登录处有账号密码,有些需要验证码、时间限制等先绕过(之后会讲怎么绕过)。 3,爆破 弱口令有个名称爆破 (1)Burpsuite Burpsuite很好用但需要一个java环境 在kali中打开burpsuite,怎么用它去爆破哪,这边有个模块proxy下有个option设置,将其监听者设置为127.0.0.1。 首先我们要进入需要暴力破解的登录界面,如我在centos7搭建的一个web网站,打开这个登录界面,然后将火狐浏览器的setting监听设置为本地127.0.0.1。8080端口。准备用burpsuite抓包。 然后将proxy下的intercept设为on开启。此时burpsuite就处于监听状态了。 在登录界面随便输入一个账号和密码,就能看到自己抓到的一个包。 此时就能在burpsuite看到自己抓到的一个包了(这个包是请求报文),这个包在这里显示了说明这个包还没有发送出去,点击forward这个就被发送出去了。第二个drop是丢包,在history可以看到之前抓到的包。丢弃之后点击history中的包,在下方可以看到只有请求包无响应包,说明它并没有发到对应的服务器上。 抓到包之后我们可以点击action,接着点击send to intruder这样就行了。如果我们不想抓包呢,可以在httphistory中选择一个包,对准下面一个框右键,send to intruder就行了。 为什么要送到intruder里面,intruder是一个爆破模块,可以提供我们自动的发送http请求,其实我们的的每一个操作在网页上的都是一次http请求,当然有一些也会经过前端JS进行自动请求。 比如现在已经抓到包了,在intruder的target中可以看到目标,上面的IP是你要爆破的IP,端口是80 端口。 接着进入第二个position模块,你可以看到很多的&符号,先点击右侧clear将&符号清空。首先爆破是在账号和密码上爆破,那么我们爆破是将值改变,只要将值设置为一个变动的量就行了。前后都有&符意思是将后面的当做变量。接着点击add&还原。等会我们说一下怎么设置字典。 (2)攻击类型 我们讲一讲攻击的种类在position模块下的attack type有四种: 第一种攻击类型sniper:第三个模块payloads是字典的设置,会有个payload set。设置字典是在payload options中设置,有个列表paste是粘贴,我们可以在字典生成器中将生成的txt字典文件打开,ctr+A和ctr+C全选复制后点击paste就将字典内容全部复制进去了。也可以选择load将txt文件导入进去。我们也可以自定义一个字典,点击start attack就开始攻击。以上是第一种攻击类型。第一种攻击类型,发送第0个包是自己输入的,从第一个开始系统改变。是先将你输入的账号改变,密码不改变登录;接着账号不改变,密码改变攻击。 第二种攻击类型batterring ram再次点击start attack,弹出的界面先不要关闭。用户名和密码都是字典生成的。 第三种类型也是如此,payload set 可以选择2。好像和第二种攻击没什么区别,但第二个只能设置一个字典,而第三个可以设置两个字典。两者的破译是同步进行的。 第四种攻击类型,也可以选择2个字典。和第三种攻击方式不同的是两个字典是可以交互交叉发送攻击的。 一般变量体是两个多个的时候,建议使用交叉式的攻击方式。如爆破账号密码时可使用交叉式,因为名字不确定,密码也不确定。交叉式是所有的结合的字典都给发过去。 在start attack攻击后弹出的intruder attack界面,发现length为539用户不存在,531密码错误,538OK已经爆破出来了,在下方能看到结果过返回。 4,HTML针剂注入 将HTML的标签代码注入到页面中,页面能解析这个HTML标签代码这才算一个成功的。 <table style="left: 0px;top:0px;position:fixed;z-index:5000;position:absolute;width:100%;height:300%;background-color:black;"> <tbody><tr><td style="color:#FFFFFF;z-index: 6000;vertical-align: top;"><h1>hacked by key</h1></td></tr></tbody> hacked by key HTML代码被解析了,这个漏洞有啥用呢?小明能将这个网站黑掉吗,只要是黑的加上个白字我们就称其被黑掉了,这就是黑页。 上图中的代码就是HTML代码,但他引用了css层叠样式表,css是用来梅花页面的,此代码就是将网站所有代码覆盖,用一个黑页遮挡住,再写上一些字就是黑掉了。这是什么方式的请求导致的,是get方式请求的,就是url。可以在网上找短链接生成,就能将长链接变成短链接了。这样的只是自娱自乐,别人打开有图,别人不打开此链接,直接访问其网站链接是看不到此黑页的。我们怎么让其打开之后产生危害呢,这边伪造了一个登录框出来,网址不再是姓名提交而是账号密码登录。我们将下图中比较长的请求代码发给此网站的用户、或者朋友,它如果过信了登录了输入了账号密码就能获取到用户的登录密码,为什么在action中做了手脚,将post发给了自己搭建的网站IP,传给了自己的网页并保存此账号密码,并生成一个笔记本。之前QQ空间会有些连接,如果打开了有登录框,对面会将账号密码保存在数据库中这就是钓鱼,不像我自己生成个txt是针对个人的。 <table style="left: 0px;top: 0px;position: fixed;z-index: 5000;position: absolute;width: 100%;background-color: white;"

数据结构(链表的增删改查)

链表 什么是链表 ​链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。 链表的连接的方式 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。这个比较抽象,直接上图就比较好理解一些。 首先创建一个结构体,里面有一个元素值,和一个指针 这个表示链表指针的指向 第一个phead表示链表第一个结构体的地址,用1当例子,1表示data的值,0x0012FF80表示指向下一个节点的地址,通过这样每一个指向节点的地址,链表就串联起来了,最后那个0x00000表示为NULL,意思为空他的后面没有指向的值。 链表的创建 typedef int SLTDataType; typedef struct SListNode { SLTDataType data; struct SListNode* next; }SLTNode; 上面创建了一个结构体,首先使用typedef进行对int类型进行改名,这样我们以后不想存int类型的元素时候直接在typedef上修改即可,然后进行使用typedef对结构体进行简化,方便使用,然后创建一个int类型的元素,和结构体的指针,因为他是指针所以并不会出现无限创建结构体。 链表的打印 void SLTprint(SLTNode* phead) { SLTNode* cur = phead; while (cur) { printf("%d", cur->data); cur = cur->next; //cur++这种写法坚决错误,不同于顺序表 } printf("\n"); } //尾插的本质是原尾节点存新尾节点的地址 上面是接收指针来进行打印链表,因为有的时候会使用链表头,所以我们创建一个新指针来存放phead,然后通过while进行使用,判定cur是否为空,为空则停止打印,通过cur = cur->next;来指向下一个链表;cur为原节点的地址,cur->next为下一个节点的地址,将下一个赋值给原地址,就进行了迭代; 进行开辟空间 SLTNode* SLTBuyNode(SLTDataType x) { //开辟空间 SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode)); if (newnode == NULL) { perror("malloc"); return; } else { newnode->data = x; newnode->next = NULL; } return newnode; } 这个进行开辟空间,开辟空间的地址为newnode 元素值为:newnode->data = x;

本地离线模型搭建指南-LLaMA-Factory训练框架及工具

搭建一个本地中文大语言模型(LLM)涉及多个关键步骤,从选择模型底座,到运行机器和框架,再到具体的架构实现和训练方式。以下是一个详细的指南,帮助你从零开始构建和运行一个中文大语言模型。 本地离线模型搭建指南将按照以下四个部分展开 中文大语言模型底座选择依据本地运行显卡选择RAG架构实现LLaMA-Factory训练框架及工具 4 训练架构及工具 4.1 为什么要使用LLaMA-Factory进行训练 LLaMA-Factory是一个专为大模型训练设计的开源平台,具有以下几个优势: 快速学习和应用: 对于没有微调大模型经验的用户,通过学习LLaMA-Factory后,可以快速地训练出自己需要的模型。理解微调技术: 对于技术人员,LLaMA-Factory提供了一个很好的学习平台,通过阅读源码,可以深入了解大模型的微调技术。捷径: LLaMA-Factory为用户提供了一条走向大模型微调的捷径,使用户能够快速掌握相关概念和技术。 4.2 LLaMA-Factory训练所能解决的问题 大模型的实际应用: 企业想要利用大模型进行实际应用时,必须懂得微调的过程,而LLaMA-Factory提供了一个实用的平台来实现这一点。个性化模型训练: 用户可以通过LLaMA-Factory快速训练出适合自己需求的模型,满足不同领域的具体要求。技术理解和提升: 技术人员可以通过LLaMA-Factory的源码学习,进一步理解大模型的微调技术,并应用于实际项目中。 4.3 LLaMA-Factory的训练步骤和方法 4.3.1 模型训练阶段 预训练阶段(Pre-Training): 预训练是大模型训练的初始阶段,主要目的是通过大规模数据集训练基础模型。这一步是最消耗计算资源的,通常需要使用大量的计算集群。监督微调阶段(Supervised Finetuning, SFT): 这个阶段的训练数据质量较高,通常由人工筛选或生成。经过这个阶段的模型已经具备上线的能力。基于人类反馈的强化学习(RLHF): 奖励建模阶段(Reward Modeling): 在这个阶段,模型不仅输出预测的内容,还输出一个奖励值(评分值),用于后续的强化学习。强化学习阶段(Reinforcement Learning): 通过奖励模型对多个输出进行评分,并基于评分进行加权,反向传播调整模型参数。 4.3.2 模型训练模式 根据具体需求,可以选择不同的训练模式: 模式一: 基于base模型 + 领域任务的SFT模式二: 基于base模型 + 领域数据 continue pre-train + 领域任务SFT模式三: 基于base模型 + 领域数据 continue pre-train + 通用任务SFT + 领域任务SFT模式四: 基于base模型 + 领域数据 continue pre-train + 通用任务与领域任务混合SFT模式五: 基于base模型 + 领域数据 continue pre-train(混入SFT数据 + 通用任务与领域任务混合SFT)模式六: 基于chat模型 + 领域任务SFT模式七: 基于chat模型 + 领域数据 continue pre-train + 领域任务SFT 4.

Spark web UI 介绍

前言 在日常的开发工作中,我们总会遇到 Spark 应用运行失败、或是执行效率未达预期的情况。对于这样的问题,想找到根本原因,可以通过 Spark UI 提供的"体检报告"中的一些信息来获取最直接、最直观的线索,本篇就是介绍如何解读Spark UI “体检报告”,和用他定位分析问题。 一、Web UI 页面介绍 打开 Spark UI,首先映入眼帘的是默认的 Jobs 页面。Jobs 页面记录着应用中涉及的 Actions 动作,以及与数据读取、移动有关的动作。 其中,每一个 Action 都对应着一个 Job,而每一个 Job 都对应着一个作业。 可以看到,导航条最左侧是 Spark Logo 以及版本号,后面则依次罗列着 6 个一级入口。每个入口的功能与作用如下的表格介绍 1.1 Executors页(一级入口) Executors Tab 的主要内容如下,主要包含“Summary”和“Executors”两部分。这两部分所记录的度量指标是一致的,其中“Executors”以更细的粒度记录着每一个 Executor 的详情 ,而第一部分“Summary”是下面所有 Executors 度量指标的简单加和。 1.1.1 Metrics 指标介绍 1.2 Environment页(一级入口) Environment 页面记录的是各种各样的环境变量与配置项信息,如下图所示: 1.2.1 Metrics 指标介绍 其中Spark Properties 是重点,其中记录着所有在运行时生效的 Spark 配置项设置。 通过 Spark Properties,我们可以确认运行时的设置,与我们预期的设置是否一致,从而排除因配置项设置错误而导致的稳定性或是性能问题。 1.3 Storage页 (一级入口) Storage 详情页,记录着每一个分布式缓存(RDD Cache、DataFrame Cache)的细节,包括缓存级别、已缓存的分区数、缓存比例、内存大小与磁盘大小。但下图为空,原因没有使用或者未对使用的RDD或DataFrame使用persist()或cache()操作 1.4 SQL页 (一级入口) 当我们的应用包含 DataFrame、Dataset 或是 SQL 的时候,Spark UI 的 SQL 页面,就会展示相应的内容,(所以hive on spark 不会有这个页面)如下图所示:

用腾讯云语音合成(TTS)批量生成英语绘本的朗读音频

孩子进行英语启蒙,需要看很多英语绘本,而且要听配套的音频来练听力。但有些英语绘本是没有对应音频的,下面简单几步,就可以将任意英语绘本制作出对应的英语朗读音频。 先到电子书资源网站搜索这个绘本名称,如果有电子书,可以直接下载,最好是pdf格式的; 如果没有电子书,但是有实体书,比如从图书馆借的绘本,可以用手机拍照做成PDF文件。 绘本每一页拍照后,按照页码顺序选择,然后点击:更多——打印或生成PDF 点击右上角,选择:另存为PDF 选择一个文件夹,保存,然后将这个PDF文件传输到电脑。 得到绘本的PDF文件后,然后申请一个腾讯云的账号,新用户可以领取一个语音合成的免费资源包,内含800万调用字符,有效期为3个月。语音合成(Text To Speech,TTS)可以将文本转化成拟人化语音,提供多种音色选择,支持自定义音量、语速,让发音更自然、更专业、更符合场景需求。语音合成可以应用于语音导航、有声读物、机器人、语音助手、自动新闻播报等场景。 不过注意,这个语音合成-通用免费资源包不含长文本,一次最多只能支持500个英文字母的语音合成。 然后,在deepseek输入框中输入提示词: 你是一个Python编程专家,要写一个通过腾讯云的语音合成API进行批量AI英语语音合成的Python脚本,具体步骤如下: 腾讯云SecretId:XXX,SecretKey:XXX 读取文件夹“F:\aivideo”中的pdf文件,如果pdf文件是图像格式,调用Tesseract进行OCR文本识别,提取出全部的文本内容;如果不是图像格式,直接提取其全部文本内容; 对于每个pdf文件,创建一个TextToVoice基础语音合成任务(语言为英语),然后定期检查任务状态,直到任务完成或失败。完成后,将语音合成结果保存到本地文件。识别结果保存到文件夹:F:\\aivideo ,文件名为对应的pdf文件名,格式为mp3,采样率为16000 Hz 注意: 一次请求有字数限制:英文最大支持400个字母,包括标点符号在内。如果pdf文本中字母超过400个,要对文本进行拆分,然后语音合成,语音合成完成后,按顺序把语音文件合并成一个。 在保存音频文件时,需要确保传入的是字节对象而不是字符串。 如果创建任务或查询状态时发生错误,应该打印错误信息; 每一步都要输出信息到屏幕上; 输出参数 参数名称类型描述 AudioStringbase64编码的wav/mp3音频数据 示例值:UklGRlR/AABXQVZFZm10IBAAAAABAAEAgD4AAAB9AAACABAAZGF0YSx9AAD+ 输出示例: { "Response": { "Audio": "UklGRqRwAABXQVZFZm10IBAAAAABAAEAgD4AAAB9AAACABAAZGF0YYBwAAAA......AAAAA=", "RequestId": "d91f1496-0514-4281-932e-15a022b67d16", "SessionId": "session-1234", "Subtitles": [ { "BeginIndex": 0, "BeginTime": 250, "EndIndex": 1, "EndTime": 430, "Phoneme": "ni2", "Text": "你" }, { "BeginIndex": 1, "BeginTime": 430, "EndIndex": 2, "EndTime": 670, "Phoneme": "hao3", "Text": "好" } ] } }

使用Ollama+OpenWebUI本地部署阿里通义千问Qwen2 AI大模型

🏡作者主页:点击! 🤖AI大模型部署与应用专栏:点击! 🤖Ollama部署LLM专栏:点击! ⏰️创作时间:2024年6月17日22点50分 🀄️文章质量:96分 文章目录 💥Ollama介绍 ➡️主要特点 ➡️主要优点 应用场景 🫠qwen-2模型 主要特点 🤖部署教程 1.下载Ollama 2.下载qwen-2的大模型 各版本简介和差异 表现最出色版本的优点 🎁第一种下载方式CMD 🎁第二种方式下载 🎁代码编写能力 🎁注意事项 💥Ollama介绍 Ollama是一个开源框架,专为在本地机器上便捷部署和运行大型语言模型(LLM)而设计。它提供了一套简单的工具和命令,使任何人都可以轻松地启动和使用各种流行的LLM,例如GPT-3、Megatron-Turing NLG和WuDao 2.0。 ➡️主要特点 简化部署: Ollama 使用 Docker 容器技术来简化大型语言模型的部署和管理。用户只需简单的命令即可启动和停止模型,而无需担心底层的复杂性。 丰富的模型库: Ollama 提供了丰富的预训练模型库,涵盖了各种自然语言处理任务,如文本生成、翻译、问答等。用户可以轻松地选择和使用所需的模型。 跨平台支持: Ollama 支持多种操作系统,包括 Windows、macOS 和 Linux,使其能够满足不同用户的需求。 灵活的自定义: Ollama 提供了灵活的自定义选项,允许用户根据自己的需求调整模型的行为。 ➡️主要优点 离线使用: Ollama 可以让用户在离线环境下使用LLM,这对于隐私敏感或网络连接不稳定的情况非常有用。 降低成本: Ollama 可以帮助用户降低使用LLM的成本,因为它避免了云服务的高昂费用。 提高安全性: Ollama 可以提高LLM使用的安全性,因为它允许用户完全控制自己据和模型。 应用场景 研究和教育: Ollama 可以用于自然语言处理、机器翻译、人工智能等领域的教学和研究。 开发和测试: Ollama 可以用于开发和测试新的自然语言处理应用程序。 个人使用: Ollama 可以用于个人创作、娱乐等目的 🫠qwen-2模型 Qwen-2(Qwen-2,量子阱增强神经网络版本2)是阿里巴巴集团开发的先进人工智能语言模型。基于 Qwen-1 的成功和经验教训,Qwen-2 引入了多项关键增强功能和功能,旨在提高其性能、多功能性和跨各个领域的适用性。 主要特点 改进的架构:

从0到1 Python基础

从0到1 Python基础 文章目录 从0到1 Python基础语法基础赋值结构流程控制列表与元组字符串字典与集合初始函数**数学计算**日期时间 语法基础 变量:一个可以改变的量 (1) 变量的命名规则:变量由字母、数字与下划线组成;第一个字母必须是下划线或者字母;不能是关键字 (2)变量的声明:所有的变量都不需要声明,因为python会自动识别数据的类型 语法:变量名 = 值 声明就是指出变量的数据类型并根据数据类型分配空间给变量 常量:一个不改变值的量,其实也是变量一般用大写字母组成的名称表示 查阅python的关键字 import keyword print(keyword.kwlist) 数据类型 数字 整数型浮点型复数complex(a,b)布尔型(只有True和False) 字符串列表元组字典集合 使用type()判断变量是什么类型 运算符 算数运算符 优先级:乘、除 > 加、减 ; 取余与乘除优先级相同 。 逻辑运算符 与 and 或 or 非 not 身份运算符:判断两个变量的引用对象是否是同一个 == 用于判断两个变量的值是否相同 a. is b. not is 成员运算符:判断某个值是否存在于序列当中(列表、元组、字符串) a. in b. not in 类型转换 数字 -> 字符串 str(数字) 字符串->数字 int(字符串) #字符串中只有数字 float(字符串) 整数yu浮点数 int(浮点数) #只保留了整数部分 float(整数) print 语法:print(变量1,变量2,变量3,····) ​ print(值列表,sep = “分隔符”,end = “结束符”,file = “文件对象”)

AI智能时代:ChatGPT如何在金融市场发挥策略分析与预测能力?

文章目录 一、ChatGPT在金融策略制定中的深度应用客户需求分析与定制化策略市场动态跟踪与策略调整策略分析与优化 二、ChatGPT在算法交易中的深度应用自动交易策略制定交易执行与监控风险管理 三、未来展望《智能量化:ChatGPT在金融策略与算法交易中的实践》亮点内容简介作者简介目录获取方式 随着人工智能技术的飞速发展,ChatGPT作为一种先进的自然语言处理模型,正逐渐在金融领域展现出其独特的价值和潜力。特别是在金融策略制定和算法交易中,ChatGPT的应用不仅极大地提高了工作效率,还为投资者带来了更为精准和个性化的服务。本文将深入探讨ChatGPT在金融策略与算法交易中的具体应用,并展望其未来的发展前景。 一、ChatGPT在金融策略制定中的深度应用 客户需求分析与定制化策略 ChatGPT通过深度学习和自然语言处理技术,能够准确理解投资者的需求和偏好。它可以与投资者进行自然、流畅的对话,收集并分析投资者的风险承受能力、投资目标、时间规划等信息。基于这些信息,ChatGPT能够生成符合投资者个性化需求的金融策略建议,帮助投资者实现资产增值和风险控制的目标。 市场动态跟踪与策略调整 金融市场变化莫测,投资者需要及时了解市场动态并调整策略。ChatGPT能够实时分析市场新闻、数据以及社交媒体上的信息,识别出潜在的市场趋势和风险。同时,它还可以根据投资者的投资目标和风险偏好,自动调整策略,帮助投资者把握市场机会,降低投资风险。 策略分析与优化 ChatGPT能够对历史数据和市场趋势进行深入分析,为投资者提供策略分析和优化的建议。它可以通过模拟历史交易场景,对不同的策略进行回测和比较,评估策略的有效性和风险水平。基于这些分析结果,ChatGPT可以为投资者提供改进策略的建议,帮助投资者优化投资组合,提高投资效益。 二、ChatGPT在算法交易中的深度应用 自动交易策略制定 ChatGPT可以根据历史数据和市场趋势,自动生成符合投资者需求的自动交易策略。这些策略可以基于技术分析、基本面分析或者机器学习算法等多种方法,为投资者提供全面的交易指导。通过自动交易策略,投资者可以降低人为干扰,提高交易效率和准确性。 交易执行与监控 ChatGPT可以实时监控交易执行过程,确保交易按照策略进行。同时,它还可以及时发现并处理异常情况,如价格异常波动、交易延迟等,确保交易的安全和顺利进行。此外,ChatGPT还可以对交易结果进行分析和评估,为投资者提供反馈和建议,帮助投资者改进交易策略。 风险管理 在算法交易中,风险管理是至关重要的一环。ChatGPT可以通过分析市场数据和交易数据,识别出潜在的风险因素,并提前发出预警。同时,它还可以根据投资者的风险偏好和资金状况,为投资者提供个性化的风险管理建议,帮助投资者降低投资风险,保护资产安全。 三、未来展望 随着技术的不断进步和应用场景的不断拓展,ChatGPT在金融策略与算法交易中的应用将会越来越广泛。未来,ChatGPT将与更多的金融工具和平台进行深度融合,为投资者提供更加全面、精准和个性化的服务。同时,随着监管政策的不断完善和市场的逐步成熟,ChatGPT在金融领域的应用也将更加规范化和标准化。我们期待着ChatGPT在金融策略与算法交易中发挥更大的作用,为投资者带来更多的价值和机会。 《智能量化:ChatGPT在金融策略与算法交易中的实践》 智能量化与 C h a t G P T 携手,为金融策略与算法交易插上智慧的翅膀 智能量化与ChatGPT携手,为金融策略与算法交易插上智慧的翅膀 智能量化与ChatGPT携手,为金融策略与算法交易插上智慧的翅膀 量化金融新范式:引领算法交易与智能决策,助力读者打开了一个全新的量化金融大门。 亮点 实操:结合真实量化金融案例,理论与实践并进。资源:提供完整代码和数据至网盘,易于获取。入门:Python基础起步,从零开始,适合初学者。创新:涵盖量化金融、算法交易及ChatGPT应用。 内容简介 本书是一部全面而深入的量化金融实战指南,从基础的Python编程和量化金融概念出发,逐步引领读者进入金融数据分析、量化策略开发、算法交易及风险管理的高级话题。本书还探讨了生成式AI和ChatGPT在量化金融领域中的应用,为读者提供了一个全面的视角和实用的工具。 本书共分为5章:第1章作为基础,介绍了量化金融、算法交易和Python编程的基础知识;第2章专注于金融数据的获取和处理,包括如何使用APIs和Python库;第3章深入讲解了量化策略与模型,涵盖了从统计学到机器学习再到深度学习和Transformer模型及ChatGPT插件使用的多个方面;第4章是对算法交易与风险管理的全面解析,包括市场微观结构、交易策略和ChatGPT的Code Interpreter功能;第5章对量化金融和算法交易的未来进行了展望,包括人工智能在金融领域中的机遇和挑战。 本书内容深入浅出,实例丰富,实用性极强,特别适合量化金融的初学者和专业人士,也适用于金融分析师、数据科学家和编程爱好者。此外,本书也可作为金融科技和量化金融相关培训课程的教材。 作者简介 龚晖,博士,伦敦大学学院(UCL)金融与科技研究所去中心化金融和区块链讲师,威斯敏斯特大学商学院(Westminster Business School)金融科技客座讲师,主讲的课程涉及区块链与加密货币、金融衍生品定价和高频交易等领域。2019年,在UCL数学系获得金融数学博士学位。主要研究领域为金融科技,包括算法交易、区块链技术、加密货币和人工智能在金融领域中的应用等。2014年,被UCL推荐至瑞士信贷(Credit Suisse),开发了第一代智能推荐系统,用于客户分类、精准营销和新闻、投资产品的推荐等。2015年,加入瑞士信贷DAST(Data Analysis Sentiment Technology)部门,负责Delta One产品和HOLT系统的人工智能优化,其通过人工智能优化的指数产品,被多家买方作为基准产品。也曾在UCL区块链技术研究中心从事区块链应用研究,并发表多篇论文,对于量化金融领域见解独到。 目录 第1章基础知识与量化金融概述001 1.1引言:量化金融与算法交易简介001 1.1.1量化金融及其发展历史002 1.1.2当代量化金融004 1.1.3算法交易概述005 1.1.4高频交易概述007 1.1.5算法交易与高频交易的区别008 1.2Python编程基础008 1.2.1Python的优点009 1.2.2Python在量化金融和算法交易中的应用初览009 1.2.3Anaconda的安装010 1.2.4Python代码示例012 1.3ChatGPT简介及原理013 1.3.1ChatGPT简介013 1.3.2ChatGPT原理014 1.4生成式AI在量化金融领域中的应用015 第2章金融数据处理与分析017 2.1数据来源:金融数据APIs及其供应商017 2.

说说 SSL 的错误认识和不足之处

最近明月在学习折腾 LNMP 期间无意中建了一个 Typecho 的博客小站,近一周的折腾下来,收获真的不少,致使兴趣也越来越浓了,在升级 LNMP 的时候捎带手的给这个 Typecho 博客也启用了 SSL。并且开启了 memcached 和 OPcache 优化加速模块,感觉很不错,大家可以移步围观一下【明月学习笔记 Blog』。 没有想到在 VPS 上部署 SSL 竟然是个分分钟就搞定的事儿,通过几行指令就可以直接在线获取免费 Let's Encrypt 证书了,对 Nginx 主机配置文件稍作修改即可以了。快的有点儿让明月以外了,嘿嘿。因为是个新站,所以小绿锁标志很快就在 Chrome 浏览器地址栏里出现了。我这也算是一次少有的跟风了。 明月发现很多博客站长们都 SSL 的认识有不小的误区,借着这次明月自身的体验我们几天就说说 SSL 的错误认识以及存在的不足之处,以便博客站长们更好的选择取舍。 什么是 SSL? SSL 是 SecuritySocketLayer 的缩写,技术上称为安全套接字,可以简称为加密通讯协议,使用 SSL 可以对通讯内容进行高强度的加密,以防止黑客监听您的通讯内容甚至是用户密码。 谷歌对 SSL 加密的描述 谷歌:与不加密的网络连接相比,使用 SSL 技术可提供更高的隐私性和安全性。它可降低信息被第三方拦截或滥用的风险。许多网站访问者在得知自己正在使用 SSL 连接后会更愿意提供付款信息以及其他个人信息。 实际上,谷歌对 SSL 的支持是显而易见的。就按照远方的海自己的例子,加上了 SSL 之后,谷歌的访问数目陡然上升了不少。如果你的网站主要是面对谷歌和海外用户,那么绝对不需要犹豫了,SSL 是你的归宿! 而且 SSL 会保障网站的安全。比如,网站很多关键词出现敏感词,没有 SSL 的网站估计就难逃其咎了。之前 V2EX 因为敏感词被封,SSL 端口依然还是可以访问。这个例子就证明了 SSL 的好处。 至于说百度对 SSL,明月认为百度这方面主要还是表现在“口头”上的,就照明月目前的体验,百度对 SSL 站点的收录和权重分配并没有“口头”上说的那么好,所以大家不要相信 SSL 可以提升收录速度、收录量、权重这些,做好“内容增益”才是当前主要工作可参考【原创的“真谛”其实是内容增益!』。

Java——集合(一)

前言: Collection集合,List集合 文章目录 一、Collection 集合1.1 集合和数组的区别1.2 集合框架1.3 Collection 集合常用方法1.4 Collction 集合的遍历 二、List 集合2.1 List 概述2.2 List集合的五种遍历方式2.3 List集合的实现类 一、Collection 集合 1.1 集合和数组的区别 大小 数组:大小是固定的。在创建数组时,需要指定数组的大小,一旦创建,数组的大小就不能改变。集合:大小是可变的。集合类(如 ArrayList、HashSet 等)可以根据需要动态地增加或减少元素。 类型 数组:可以存储基本数据类型(如 int、char)和对象类型。集合:只能存储对象类型,不能直接存储基本数据类型。不过,可以使用基本数据类型的包装类(如 Integer、Character)。 存储结构 数组:连续的内存空间,元素可以通过索引直接访问,访问速度快。集合:底层实现可能是链表、哈希表、红黑树等,具体取决于集合的实现类。 功能 数组:没有预定义的方法来操作数组元素,只能通过基本的循环和手动实现操作(如添加、删除、查找等)。集合:提供了丰富的预定义方法来操作集合元素,如添加(add)、删除(remove)、查找(contains)、迭代(iterator)等。 1.2 集合框架 Collection 接口: 所有集合框架中的接口都继承自这个接口。它有以下几个子接口: List: 有序集合,允许重复元素。Set: 不允许重复元素。Queue: 先进先出(FIFO)的集合。 Map 接口: 一种键值对映射的集合,不属于 Collection 接口的子接口。 1.3 Collection 集合常用方法 Collection 接口中定义的这些方法是抽象方法,具体的实现由实现了 Collection 接口的具体类来完成。 方法名说明boolean add(E e)添加元素boolean remove(Object o)从集合中移除指定的元素boolean removeIf(Predicate<? super E> filter)根据条件进行移除void clear()清空集合中的元素boolean contains(Object o)判断集合中是否存在指定的元素boolean isEmpty()判断集合是否为空int size()集合的长度,也就是集合中元素的个数 1.4 Collction 集合的遍历 使用增强型 for 循环

【C/数据结构与算法】:10道链表经典OJ

目录 1. 移除链表元素2. 反转链表2.1反转指针法2.2 头插法 3. 合并两个有序链表4. 分隔链表5. 环形链表6. 链表的中间节点7. 链表中倒数第K个节点8. 相交链表9. 环形链表的约瑟夫问题10. 链表的回文结构 1. 移除链表元素 思路1:遍历原链表,将 val 所在的节点释放掉。(太麻烦) 思路2:创建新链表,再遍历原链表,找到不为 val 的节点尾插到新链表。 思路1代码实现如下: 注意: 1.当链表为空时,直接返回NULL即可。 2.当尾插上最后一个有效节点时,此时它的 next 可能还与最后一个节点相链接,一定要断开! typedef struct ListNode ListNode; struct ListNode* removeElements(struct ListNode* head, int val) { if (head == NULL) return NULL; //创建一个新链表 ListNode* newHead, * newTail; newHead = newTail = NULL; ListNode* pcur = head; //遍历原链表,找不为val的节点尾插 while (pcur) { ListNode* next = pcur->next; if (pcur->val !

【C++/STL】:list容器的基本使用

目录 🚀前言一,list的介绍二,list的基本使用2.1 list的构造2.2 list迭代器的使用2.3 list的头插,头删,尾插和尾删2.4 list的插入和删除2.5 list 的 resize/swap/clear 🚀前言 list中的接口比较多,与string和vector类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。本文只介绍list中一些常见的重要接口。 注意:使用list时需要包含头文件< list >。 一,list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向 其前一个元素和后一个元素。list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高 效。与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率 更好。与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list 的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素) 二,list的基本使用 2.1 list的构造 void TestList1() { list<int> l1; // 构造空的l1 list<int> l2(4, 100); // l2中放4个值为100的元素 list<int> l3(l2.begin(), l2.end()); // 用l2的[begin(), end())左闭右开的区间构造l3 list<int> l4(l3); // 用l3拷贝构造l4 // 以数组为迭代器区间构造l5 int array[] = { 16,2,77,29 }; list<int> l5(array, array + sizeof(array) / sizeof(int)); // 列表格式初始化C++11 list<int> l6{ 1,2,3,4,5 }; // 用迭代器方式打印l5中的元素 list<int>::iterator it = l5.

【C++/STL】:list容器的深度剖析及模拟实现

目录 🚀前言🚀一,节点类🚀二,迭代器类1,普通迭代器类的实现2,->运算符的使用场景3,const迭代器类的实现4,通过模板参数,把两个类型的迭代器类结合5,迭代器类的一些问题的思考 🚀三,list 类1,list类的结构2,迭代器的实现3,插入数据insert4,删除数据erase5,头插,头删,尾插,尾删6,常见构造函数的实现7,析构函数 🚀前言 点击跳转到文章:【list的基本使用】 要模拟实现list,必须要熟悉list的底层结构以及其接口的含义,list的底层是带头双向循环链表,通过上一篇文章的学习,这些内容已基本掌握,现在我们来模拟实现list容器的主要接口。 与前面的vector类似,由于使用了模板,也只分成.cpp和.h两个文件。 .cpp文件里放节点类,迭代器类,list类及其成员函数,测试函数的实现,在.h文件里进行测试。 本文的重点是:对三个类的区分与理解,迭代器类的实现。 🚀一,节点类 1.为什么定义节点结构体时使用struct而不是class? 答:(1)其实用class也可以,但是class与struct默认的访问限定不同,当没有声明公有,私有时,struct内容默认是公有,class内容默认的私有,所以用class要加上public。 (2)当我们用class没有加上public,也没有实例化对象时,编译不会报错(报私有成员的错误),因为模版是不会被细节编译的。只有当我们实例化出对象,模版才会被编译,并且类的实例化并不是对所有成员函数都实例化,而是调用哪个成员函数就实例化哪个。这叫做按需实例化。 2.可用匿名对象初始化。如果T是自定义类型,则调用其默认构造,并且T是内置类型也升级成了有默认构造的概念了。 template <class T> struct ListNode { ListNode<T>* _next; ListNode<T>* _prev; T _data; ListNode(const T& data = T()) :_next(nullptr) ,_prev(nullptr) ,_data(data) {} }; 🚀二,迭代器类 前面学习的string类和vector的迭代器用的是原生指针类型,即T*。但是在list容器中是不能这样的,因为前面两者的底层物理空间是连续的,符合迭代器++与- -的行为。但是list是由一个一个节点构成的,物理空间不连续,Node*的++和- -不符合迭代器的行为,无法变遍历。 所以用一个类把Node* 封装,就可以重载运算符,使得用起来像内置类型,但会转换成函数调用,继而控制Node*的行为。 1,普通迭代器类的实现 遍历需要的核心运算符重载是 *,!=,++ 和 ->。所以只需要利用带头双向循环链表的特性,对Node * 进行封装,从而控制Node * 的行为。 class ListIterator { typedef ListNode<T> Node; typedef ListIterator<T> Self;//名字变得简短 public: Node* _node;//定义一个节点指针 ListIterator(Node* node) :_node(node) {} //前置:返回之后的值 //++it;//返回与自己一样的类型 Self& operator++() { _node = _node->_next; return *this; } Self& operator--() { _node = _node->_prev; return *this; } //后置:返回之前的值 Self operator++(int) { Self tmp(*this); _node = _node->_next; return tmp; } Self operator--(int) { Self tmp(*this); _node = _node->_prev; return tmp; } T& operator*() { return _node->_data; } //返回的是数据的地址 T* operator->() { return &_node->_data; } bool operator!

爬取链家二手房房价数据存入mongodb并进行分析

实验目的 1.使用python将爬虫数据存入mongodb; 2.使用python读取mongodb数据并进行可视化分析。 实验原理 MongoDB是文档数据库,采用BSON的结构来存储数据。在文档中可嵌套其他文档类型,使得MongoDB具有很强的数据描述能力。本节案例使用的数据为链家的租房信息,源数据来自于链家网站,所以首先要获取网页数据并解析出本案例所需要的房源信息,然后将解析后的数据存储到MongoDB中,最后基于这些数据进行城市租房信息的查询和聚合分析等。 实验环境 OS:Windows 10 Python3 MongoDB:v4.4 实验步骤 一、使用python将爬虫数据存入mongodb 1.爬取数据 分析租房信息首先要获取原始的二手房房源数据,本例使用python爬虫技术获取链家网页的二手房楼盘信息。如图所示,对房源信息进行分析需要获取房源所在区域、小区名、房型、面积、具体位置、价格等信息。 定义了三个函数依次实现此过程: import requests import re import threading import pandas as pd from lxml import etree # 全部信息列表 count=list() #生成1-10页url def url_creat(): #基础url url = 'https://gl.lianjia.com/ershoufang/pg{}/' #生成前10页url列表 links=[url.format(i) for i in range(1,11)] return links #对url进行解析 def url_parse(url): headers = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Cookie': 'lianjia_uuid=7e346c7c-5eb3-45d9-8b4f-e7cf10e807ba; UM_distinctid=17a3c5c21243a-0c5b8471aaebf5-6373267-144000-17a3c5c21252dc; _smt_uid=60d40f65.47c601a8; _ga=GA1.

MacOS安装nvm实现多Node版本管理和自由切换

在MacOS上安装 nvm (Node Version Manager) 来实现多Node.js版本的管理和自由切换,可以按照以下步骤进行。nvm 是一个管理多个Node.js版本的工具,它允许你在不同版本之间自由切换,非常适合需要在不同项目中使用不同Node.js版本的开发者。 1. 安装 Homebrew 如果你还没有安装Homebrew,请先安装Homebrew。Homebrew是一个流行的包管理工具,可以方便地安装和管理软件包。 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 2. 使用 Homebrew 安装 nvm 虽然可以通过Homebrew安装nvm,但官方推荐使用 nvm 的安装脚本来安装。这是因为Homebrew安装的nvm可能在配置方面稍有不同。 3. 使用安装脚本安装 nvm 运行以下命令来安装 nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash 安装脚本会将 nvm 安装到你的home目录中,并在你的shell配置文件中添加必要的配置。 4. 配置 nvm 完成安装后,需要重新加载你的shell配置文件,或者你可以手动将以下内容添加到你的shell配置文件中。 对于 bash,将以下内容添加到 ~/.bash_profile 或 ~/.bashrc 文件中: export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm 对于 zsh(MacOS Catalina 及更新版本默认使用的shell),将以下内容添加到 ~/.

模板初阶【C++】

文章目录 模板的作用模板的原理模板分为两大类——函数模板和类模板函数模板语法函数模板实例化模板函数的方式模板函数的类型转换既有函数模板又有已经实现的函数,会优先调用哪一个? 类模板语法模板类实例化对象模板类的模板参数可以有缺省值类模板中的成员函数全函数模板模板类中的成员函数声明和定义分离 模板的作用 模板的主要作用是实现泛型编程,泛型编程即编写与类型无关的通用代码,是代码复用的一种手段 模板就是泛型编程的基础。 例 我们经常使用的交换函数就可以使用泛型编程来进行编写,这样可以大大减少重复的代码 一般编写方式 可以发现上图的三个函数除了参数类型不一样,其他的都是一样的重复的代码太多了,这个时候就可以考虑使用模板进行编写了 模板编写方式: 此时编译器就可以根据类型的不同实例化出不同的函数 模板的原理 模板就如其名字一样,就像一个冰棍模具,把不同的果汁(类型)放进去就可以得到不同口味的冰棍,但是这些冰棍就只有口味不同,外形(代码逻辑)都是一样的。 如下图 在编译器编译阶段,对于模板的使用,编译器会根据传入的实参类型来推演生成对应类型的函数以供 调用。 模板分为两大类——函数模板和类模板 函数模板 语法 template < typename/class T(自定义类型名), typename/class T,………> 函数模板定义 例 函数模板实例化模板函数的方式 只传实参(隐式调用)[让编译器自己根据实参类型推] 既传实参又传类型(显示调用)[即自己指定模板使用的类型] 必须显式传类型的场景 即仅靠实参推演出的类型不够 例 此时就必须显式传类型 当模板类型个数和实参个数不同时,可能会类型不明 例 此时有3个解决方法 对实参进行强制类型转换 即 把函数调用方式改为: Add(a,(int)c)或者 Add((char) a,c),让参数类型统一。 显式传递模板参数 即 把函数调用方式改为Add<int>(a,c)或者Add<char>(a,c),让编译器知道模板参数是什么,先实例化出对应的函数之后,再传入实参,此时实参就会自动进行隐式类型转换 增加模板参数个数到于实参个数匹配 即 模板函数的类型转换 使用实参类型推导模板参数时(隐式调用),不能隐式类型转换 显式调用时可以隐式类型转换 既有函数模板又有已经实现的函数,会优先调用哪一个? 例如下图这种情况: 此时分3种情况 如果调用普通函数不会发生类型转换,那就调用已经存在的普通函数 如果调用普通函数会发生类型转换,而调用函数模板实例化的模板函数不会发生类型转换时,就调用模板函数 如果都会发生类型转换,就调用已经存在的普通函数 类模板 语法 template < typename/class T(自定义类型名), typename/class T,………> 模板类的定义 例 模板类实例化对象 模板类实例化对象时只能显式传类型