Keepalived LVS群集 部署“LVS+KeepAlived高可用负载均衡集群”案例需求部署共享存储准备工作配置nfs服务 部署web节点(web1和web2配置基本相同,请结合实际配置)准备工作配置网络配置web服务内核配置 部署负载调度器准备工作配置KeepAlived服务配置负载策略配置内核参数 测试 部署“LVS+KeepAlived高可用负载均衡集群”案例 需求 备DR 服务器:10.190.33.50主DR 服务器:10.190.33.40Web 服务器1:10.190.33.20Web 服务器2:10.190.33.30VIP地址:10.190.33.200客户端:10.190.33.1(物理机)NFS服务器:10.190.33.10
部署共享存储 准备工作 hostnamectl set-hostname nfs-server systemctl disable firewalld.service --now vim /etc/selinux/config 将“SELINUX=enforcing”修改成“SELINUX=0” reboot 配置nfs服务 yum install -y rpcbind nfs mkdir /share/{wang,lei} -p echo '<h2>This is <h1>WANG</h1></h2>' > /share/wang/test.html echo '<h2>This is <h1>LEI</h1></h2>' > /share/lei/test.html vim /etc/exports /share/wang 10.190.33.0/24(ro) /share/lei 10.190.33.0/24(ro) systemctl enable rpcbind nfs --now showmount -e 部署web节点(web1和web2配置基本相同,请结合实际配置) 准备工作 hostnamectl set-hostname web1-server systemctl disable firewalld.service --now vim /etc/selinux/config 将“SELINUX=enforcing”修改成“SELINUX=0” reboot 配置网络 vim /etc/sysconfig/network-scripts/ifcfg-lo:0 systemctl restart network DEVICE=lo:0 ONBOOT=yes IPADDR=10.
找往期文章包括但不限于本期文章中不懂的知识点:
个人主页:我要学编程(ಥ_ಥ)-CSDN博客
所属专栏:数据结构(Java版)
目录
203. 移除链表元素
206. 反转链表
876. 链表的中间节点
面试题 02.02. 返回倒数第k个节点
快慢指针的原理分析 21. 合并两个有序链表
牛客网——链表的回文
牛客网——链表分割
160. 相交链表
141. 环形链表
142. 环形链表 II
单链表的刷题,点我
下面的这些面试题有一部分在上面这篇博文中,有兴趣可以看一看。
下列题目中出现的这个,是出题者想告诉我们这个链表的节点是由什么组成的。 203. 移除链表元素 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5] 示例 2:
输入:head = [], val = 1 输出:[] 示例 3:
输入:head = [7,7,7,7], val = 7 输出:[] 提示:
目录
第一部分
Hadoop是什么
官方解释:
个人总结
HDFS 是什么?
官方解释:
个人总结
yarn是什么?
官方解释:
个人总结
mapreduce,spark 是什么?
官方解释:
MapReduce
Spark
个人总结
MapReduce
Spark
spark 生态圈有哪些内容?
官方解释
个人总结
hbase 是什么?
官方解释
个人总结
hive 是什么?
官方解释
个人总结
eChart 是什么?
官方解释
个人总结
我们接触了哪些分布式计算框架?
官方解释
个人总结
实现 spark 编程的语言有哪些?
官方解释
个人总结
我们上课讲的是哪种编程语言?
个人总结
Hive 的执行需要计算引擎吗?
官方解释
个人总结
你知道有哪些计算引擎?
官方解释
个人总结
Spark RDD的一些考查
个人分析考察点
第二部分
实验环境准备
官方
个人分析考点
本地数据集上传到数据仓库Hive
官方
个人分析考察点
流程
Hive数据分析
官方
个人分析考点
流程
将数据从Hive导入到MySQL
Map接口和Collection接口是所有集合框架的父接口:
Collection接口的子接口包括:Set接口和List接口
Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等
List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
List接口及其实现 ArrayList
基于动态数组实现
允许快速随机访问元素
插入和删除操作可能需要移动其他元素,因此在中间位置插入和删除的时间复杂度为O(n)
非同步,不是线程安全的,可以使用使用Collections.synchronizedList(new ArrayList<>()) 创建一个同步的 ArrayList。
LinkedList 基于双向链表实现
允许快速插入删除元素
不能快速随机访问,访问元素的时间复杂度为O(n)
非同步,不是线程安全的。可以使用 Collections.synchronizedList(new LinkedList<>()) 创建一个同步的 LinkedList。
可以用做队列或双向队列
依赖于两个节点(一个头节点一个尾节点)
常用方法
添加
add(E e):在链表后添加一个元素; 通用方法 addFirst(E e):在链表头部插入一个元素; 特有方法 addLast(E e):在链表尾部添加一个元素; 特有方法
删除
removeFirst(E e):删除头,获取元素并删除; 特有方法 removeLast(E e):删除尾; 特有方法
查看
getFirst():获取第一个元素; 特有方法 getLast():获取最后一个元素; 特有方法
Stack 基于Vector实现,代表了后进先出()
是同步的,是线程安全的
push入栈、peek查看栈顶元素、pop出栈、empty是否为空、size()获取数目
Vector 基于动态数组实现,类似于ArrayList
同步的,是线程安全的
是需要线程安全的动态数组是使用,但是通常使用ArrayList和Collections.syschronizedList来代替
Set接口及其实现类 set其实一直在用map那一套
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { private transient HashMap<E,Object> map; private static final Object PRESENT = new Object(); public HashSet() { map = new HashMap<>(); } public boolean add(E e) { return map.
1.窗口函数之排序函数 RANK, DENSE_RANK, ROW_NUMBER
RANK函数 计算排序时,如果存在相同位次的记录,则会跳过之后的位次 有 3 条记录排在第 1 位时: 1 位、1 位、1 位、4 位…DENSE_RANK函数 同样是计算排序,即使存在相同位次的记录,也不会跳过之后的位次 有 3 条记录排在第 1 位时: 1 位、1 位、1 位、2 位ROW_NUMBER函数 赋予唯一的连续位次。
例)有 3 条记录排在第 1 位时: 1 位、2 位、3 位、4 位 语法
<窗口函数> OVER ([PARTITION BY <列清单>] ORDER BY <排序用列清单>)
根据分数对学生从高到低排名,不对科目进行分组,成绩相同则排名相同并且位次连续 SELECT student_name, score, DENSE_RANK() OVER(ORDER BY score DESC) AS 'rank' FROM grade; 根据分数对同科目的学生从高到低排名,成绩相同,排名不相同 SELECT student_name, score, ROW_NUMBER() OVER(PARTITION BY course_name ORDER BY score DESC) AS 'rank' FROM grade; 窗口函数使用场景 1.
专栏引入 哈喽大家好,我是野生的编程萌新,首先感谢大家的观看。数据结构的学习者大多有这样的想法:数据结构很重要,一定要学好,但数据结构比较抽象,有些算法理解起来很困难,学的很累。我想让大家知道的是:数据结构非常有趣,很多算法是智慧的结晶,我希望大家在学习数据结构的过程是一种愉悦的心情感受。因此我开创了《数据结构》专栏,在这里我将把数据结构内容以有趣易懂的方式展现给大家。
1.二叉树的链式存储结构 前面我们说过顺序存储结构一般只适用于完全二叉树,既然顺序存储适应性不强,我们既要考虑链式存储结构了。二叉树每个节点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法 ,我们称这样的链表为二叉链表。节点结构图如下所示:
其中,data是数据域,leftchild和rightchild都是指针域,分别存放指向左孩子和右孩子的指针,下面是二叉链表的节点结构定义代码:
typedef struct BinaryTreeNode { TDataType data; struct TreeNode* leftchild; struct TreeNode* rightchild; }BTNode; 结构示意图如下:
就如同我们在树的存储结构中讨论的一样,如果有需要,还可以增加一个指针指向其双亲的指针域,那样就称之为三叉链表,后续在红黑树时会提到,这里就不细讲了。 2.二叉树的遍历 二叉树的遍历是指从根节点出发,按照某种次序依次访问二叉树中的所有节点,使得每一个节点被访问一次且仅被访问一次。这里有两个关键词:访问和次序。访问其实是根据实际需要来确定具体做什么,比如:对某个节点进行相关计算、输出打印等。二叉树的遍历次序不同于线性结构,最多也就是从头到尾、循环、双向等简单的遍历方式。树的节点之间不存在唯一的前驱和后继关系,在访问一个节点后,下一个访问的节点面临着不同的选择。就像我们高考填报志愿要面临着去哪个城市、哪所大学、具体专业等选择,由于选择的方式不同,遍历的次序就完全不同了。
二叉树的遍历方式可以有很多种,如果我们限制了从左到右的习惯方式,那么主要就分为四种:前序遍历、中序遍历、后序遍历、层序遍历。
2.1前序遍历 二叉树的前序遍历规则是:若二叉树为空,则空操作返回,否则先访问根节点,然后前序遍历左子树,再前序遍历右子树。即按照“根节点-左子树-右子树”的顺序遍历二叉树。像下面这张图中的二叉树,遍历顺序是ABDECFG:
二叉树的定义是用递归的方式,所以,实现遍历也可以采用递归,而且极其简洁明了,我们先来看看二叉树的前序遍历,具体代码如下:
void PreOrderTraverse(BiTree T) { if(T==null) return; printf("%c",T->data); PreOrderTraverse(T->lchild); preOrderTraverse(T->rchild); } 假设我们有如下图这样的一棵二叉树T,这棵树已经用二叉链表结构存储在内存当中:
当我们调用PreOrderTraverse(T)函数时,我们来看看程序是怎么运行的:
(1)当调用PreOrderTraverse(T)时,根节点不为NULL,所以执行printf,打印字母A,就像下面这样:
(2)接着我们调用PreOrderTraverse(T->lchild)函数,访问根节点A的左孩子,不为NULL,执行printf打印字母B,如下图所示:
(3)此时再次递归调用PreOrderTraverse(T->lchild)函数,来访问B节点的左孩子,执行printf函数打印字母D,如下图所示:
(4)再次递归调用PreOrderTraverse(T->rchild),访问D节点的左孩子,此时因为D节点没有左孩子,所以T=NULL,返回此函数,此时递归调用PreOrderTraverse(T->rchild),访问D节点的右孩子,执行printf打印H,如下图所示:
(5) 再次递归调用PreOrderTraverse(T->lchild),访问H节点的左孩子,H节点没有左孩子,返回,调用PreOrderTraverse(T->rchild),访问H节点的右孩子,也是NULL,返回。于是,此函数执行完毕,返回到上一级递归的函数(即打印D节点的函数),也执行完毕,返回打印D节点时的函数,调用PreOrderTraverse(T->rchild),找到E节点,打印字母E,如下图所示:
(6)由于节点E没有左右孩子,返回打印B节点的递归函数,递归执行完毕,返回到最初的PreOrderTraverse,调用PreOrderTraverse(T->rchild),访问A节点的右孩子,如图所示:
(7)之后类似前面的递归调用,一依次打印F、I、G、J,这里步骤就省略喽。
综上所述,前序遍历这棵二叉树的节点的顺序是ABDHECFIGJ。 2.2中序遍历 规则是若树为空,则空操作返回,否则从根节点开始(注意不是先访问根节点),中序遍历是遍历根节点的左子树,然后是访问根节点,最后中序遍历右子树,即按照“左子树-根节点-右子树”的顺序遍历二叉树。如下图所示的二叉树遍历的顺序为DBEAFCG:
二叉树的中序遍历如何实现呢?别以为很复杂,它和前序遍历其实就是代码顺序上的差异:
void InOrderPraverse(BiTree T) { if(T==NULL) return; InOrderPraverse(T->lchild); printf("%c",T->data); InOrderPraverse(T->rchild); } 换句话说,它等于把调用左孩子的递归函数提前了,就这么简单,我们来看看调用InOrderPraverse(T)函数时,程序是如何运行的呢?
(1)调用PreOrderTraverse(T),T的根节点不为NULL,于是调用PreOrderTraverse(T->lchild),访问B节点,当前指针仍不为NULL,继续调用PreOrderTraverse(T->lchild),访问节点D,继续调用PreOrderTraverse(T->lchild),访问D节点的左孩子,发现当前指针为NULL,于是返回,打印当前节点D,如下图所示:
(2)然后调用PreOrderTraverse(T->rchild),访问节点D的右孩子H,因为H也没有左孩子,所i打印H,如下图所示:
(3) 因为H节点没有右孩子,所以返回,打印节点D函数执行完毕,返回打印字母B,如下图所示:
(4)调用PreOrderTraverse(T->rchild),访问B节点的右孩子,因为E节点没有左孩子,所以打印字母E,如下图所示:
(5)E节点没有右孩子,返回,节点B的递归函数执行完毕,返回到我们最初调用InOrderPraverse的地方,打印字母A,如下图所示:
(6)再调用PreOrderTraverse(T->rchild),访问A节点的右孩子C,再递归访问C节点的左孩子F,接着访问节点F的左孩子I,因为I没有左孩子,打印I,之后分别打印F、C、G、J。这里具体步骤也就省略了。
阿里巴巴通义千问团队发布了Qwen2系列开源模型,该系列模型包括5个尺寸的预训练和指令微调模型:Qwen2-0.5B、Qwen2-1.5B、Qwen2-7B、Qwen2-57B-A14B以及Qwen2-72B。对比当前最优的开源模型,Qwen2-72B在包括自然语言理解、知识、代码、数学及多语言等多项能力上均显著超越当前领先的Llama3-70B等大模型。
老牛同学今天部署和体验Qwen2-7B-Instruct指令微调的中等尺寸模型,相比近期推出同等规模的开源最好的Llama3-8B、GLM4-9B等模型,Qwen2-7B-Instruct依然能在多个评测上取得显著的优势,尤其是代码及中文理解上。
特别注意: 虽然Qwen2开源了,但仍然需要遵循其模型许可,除Qwen2-72B依旧使用此前的Qianwen License外,其余系列版本模型,包括Qwen2-0.5B、Qwen2-1.5B、Qwen2-7B以及Qwen2-57B-A14B等在内,均采用Apache 2.0许可协议。
下载Qwen2-7B-instruct模型文件 为了简化模型的部署过程,我们直接下载GGUF文件。关于GGUF文件介绍,请详见部署Llama3-8B大模型的文章:玩转AI,笔记本电脑安装属于自己的Llama 3 8B大模型和对话客户端
打开Qwen2-7B-Instruct-GGUF模型文件列表(https://modelscope.cn/models/qwen/Qwen2-7B-Instruct-GGUF/files),我们选择qwen2-7b-instruct-q5_k_m.gguf并下载:
我们可以根据自己需要,选择下载其它版本的模型文件!
启动Qwen2-7B-Instruct大模型 GGUF模型量化文件下载完成后,我们就可以来运行Qwen2-7B大模型了。
在启动Qwen2-7B大模型之前,我们首先需要安装Python依赖包列表:
pip install llama-cpp-python pip install openai pip install uvicorn pip install starlette pip install fastapi pip install sse_starlette pip install starlette_context pip install pydantic_settings 然后打开一个Terminal终端窗口,切换到GGUF模型文件目录,启动Qwen2-7B大模型(./qwen2-7b-instruct-q5_k_m.gguf即为上一步下载的模型文件路径):
# 启动Qwen2大模型 # n_ctx=20480代表单次回话最大20480个Token数量 python -m llama_cpp.server \ --host 0.0.0.0 \ --model ./qwen2-7b-instruct-q5_k_m.gguf \ --n_ctx 20480 Qwen2-7B-instruct 命令行对话客户端 CLI命令行的客户端,可以参考之前LLama3-8B大模型的文章:https://mp.weixin.qq.com/s/MekCUJDhKzuUnoykkGoH2g
# client.py from openai import OpenAI # 注意服务端端口,因为是本地,所以不需要api_key client = OpenAI(base_url="
文章目录 🚀一.运算符🌈1. 算术运算符🌈2. 身份运算符🌈3. 成员运算符⭐4. 增量运算符⭐5. 比较运算符⭐6. 逻辑运算符 🚀二.可变与不可变🚀三.字符串转义🚀四.编码与解码💥1. 基础使用 🚀五.进制转化💥1.python进制转化 🚀六.深浅拷贝(复制)❤️1. 浅拷贝❤️2. 深拷贝 🚀七.运算升级🚀八.常用方法🚀九.操作扩展 🚀一.运算符 🌈1. 算术运算符 下面以a=10 ,b=20为例进行计算
运算符描述实例+加两个对象相加 a + b 输出结果 30-减得到负数或是一个数减去另一个数 a - b 输出结果 -10*乘两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200/除x除以y b / a 输出结果 2//向下取整返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0%取模(余)返回除法的余数 b % a 输出结果 0**幂返回x的y次幂 a**b 为10的20次方, 输出结果 100000000000000000000 🌈2. 身份运算符 身份运算符 运算符描述详解is同一性运算符变量ID是否相同,ID即变量的唯一标识,变量值可能相同但ID不一定相同is not非同一性判断两个变量的引用是否来之不同对象 使用is注意python对于小整数使用对象池存贮问题(交互式模式或者说命令行模式) """ 1.举个例子,在python命令行模式下:为什么同样值a,b与c,d的结果却不一样呢? """ >>> a = 1000 >>> b = 1000 >>> a is b False >>> c = 10 >>> d = 10 >>> c is d True # 注意,因为python对小整数在内存中直接创建了一份,不会回收,所有创建的小整数变量直接从对象池中引用即可。 # 但是注意Python仅仅对比较小的整数对象进行缓存(范围为范围[-5, 256])缓存起来,而并非是所有整数对象。 # 也就说只有在这个[-5,256]范围内创建的变量值使用is比较时候才会成立。 而保存为文件执行,结果是不一样的,这是因为解释器做了一部分优化。即使整数超过256,使用is也是成立的。 使用is注意python关于字符串的intern机制存储 # 注意: python中创建两个内容一样的变量时(变量名不一样), # 一般都会在内存中分配两个内存地址(id地址)分别给这两个变量。 # 即两个变量的内容虽然一样,但是变量的引用地址不一样。 # 所以两个变量使用==比较成立,但是使用 is比较不成立。 # 但是在python中有两个意外情况: # 1.
🥰🥰🥰来都来了,不妨点个关注叭!
👉博客主页:欢迎各位大佬!👈
文章目录 1. 操作系统2. 进程2.1 进程是什么2.2 进程管理2.3 进程调度2.3 内存管理2.4 进程间通信 3. 线程3.1 线程是什么3.2 多线程编程3.3 线程与进程联系与区别 1. 操作系统 【概念】是一个软件,是一组做计算机资源管理的软件统称,非常复杂,所以操作系统本身是一个很大的话题(这里简单了解,引入进程概念)
【常见的操作系统】
【基本功能】
1)防止硬件被时空的应用程序滥用
2)向应用程序提供简单一致的机制来控制复杂低级硬件设备
【对上】要给软件提供稳定的运行环境
【对下】要管理好各种硬件设备
操作系统的功能非常多,其中一个与我们密切相关的功能模块—>进程管理
接下来让我们一起来看看,进程是什么吧~~~
2. 进程 2.1 进程是什么 【进程】也称作任务,一个运行起来的程序,就是进程~
这个.exe是一个可执行文件,即程序,当我们双击这个exe,这个程序微信就运行起来,在系统中形成一个进程
即进程是操作系统对一个正在运行的程序的一种抽象,可以把进程看做程序的一次运行过程
【基本单位】进程是操作系统进行资源分配的基本单位
(此处涉及到的资源包括不限于内存,硬盘,CPU等等)
在任务管理器中,我们可以看到电脑的进程,打开任务管理器的快捷键为Ctrl+Alt+Del,如图:
通过任务管理器,我们能看到系统中有如此多的进程都在跑着!那么进程有如此之多,如何去管理呢~
2.2 进程管理 所谓进程管理,即进程多了才需要管理,分为以下两步:
1)描述一个进程:使用结构体/类,表示一个进程的信息
2)组织这些进程:使用一定的数据结构,把这些结构体/对象放到一起
举一个生活中常见的栗子叭~
一个大型超市,有特别多的商品,超市需要管理这些商品,建立一个商品信息管理系统,需要做:
1)明确每个商品的相关信息(价格、生产日期等)
2)通过一定的数据结构将这些商品信息都组织起来(如通过表格等)
2.3 进程调度 【进程调度概念】操作系统对CPU资源的分配,采用时间模式,不同的进程在不同的时间段去使用 CPU 资源即为进程调度~
先来了解进程的基本知识叭~
在Java中,我们通过类/对象描述这个特征,即每一个PCB对象代表一个在运行的程序即进程
进程类—> PCB(process control block)
class PCB { //属性1 pid //属性2 内存指针 //属性3 文件描述表 //属性4 进程调度信息 //.
找往期文章包括但不限于本期文章中不懂的知识点:
个人主页:我要学编程(ಥ_ಥ)-CSDN博客
所属专栏:数据结构(Java版)
目录
手动实现单链表的源码
手动实现双链表的源码
分析 LinkedList 的源码 LinkedList的使用 常用方法 ArrayList和LinkedList的区别
单链表的学习,点我
上面这篇博文是关于链表的基础知识、链表的分类以及单链表的实现。都详细的进行了说明。
手动实现单链表的源码 下面是Java版的链表源码: // 无头单向非循环链表实现 public class SingleLinkedList { // 链表是有一个一个的节点组成,因此得先创建节点 // 链表的节点由两部分组成:数值域与地址域 // 既然有多个部分,那么就可以写在类中 // 又因为节点是在单链表中(单链表中包含一个又一个的节点) // 因此节点就可以成为单链表的内部类 // 静态内部类可以只通过类名来访问,方便 public static class listNode { public int val; // 存放数值 // 是一个引用指向下一个节点的地址 public listNode next; // 指向下一个节点的地址 public listNode(int val) { // 新创建的节点的next应该为null,因为next为字段。因此其默认值为null,无需修改 this.val = val; } } public listNode head; // 头节点 // 头插法 public void addFirst(int data){ listNode newNode = new listNode(data); // 先判断这个链表是否有节点 if (head == null) { //那么新增的这个节点就是头节点 head = newNode; }else { // 把新节点的next指向head,并且把head指向新节点 newNode.
#include <iostream> #include <iomanip> using namespace std; char b[110][110]; int n; int cntt = 0; int x[110],y[110]; int di[] = {0,1,0,-1}; int dj[] = {1,0,-1,0}; int cnt = 0; void aaa(int,int); int main() { cin>>n; for(int i = 0;i<n;i++) { for(int j = 0;j<n;j++) { b[i][j] = '.'; } } aaa(0,0); return 0; } void aaa(int i,int j) { b[i][j] = '#'; x[cnt] = i; y[cnt] = j; cnt++; if(i==n-1&&j==n-1) { cntt++; cout<<cntt<<"
引言 鉴于网上很少有关于IDEA开发servlet项目的教程(24版idea,并且servlet技术十分复古,很少有人用到,能够理解,该文章旨在为在校的学生提供一个参考,项目技术简单)本人在此总结从头开始到项目落地的教程。
IDEA配置 由于servlet技术过于老旧,在24版或者比较新的版本中是无法直接创建一个web项目的,于是我们需要做好前期的配置工作
添加框架支持:
我们打开idea创建一个java项目,双击键盘shift键,弹出搜索框,如下:
直接输入add,可以发现有:
点击添加框架支持,选择web applicat:
确定后,我们再来配置路径
配置路径
我们先在web目录下创建两个目录:classes和lib
然后点击右上角四条横线位置:
选择项目结构(projec structure)
进入后我们选择modules-paths
在下方配置我们的output path:
分别选择我们刚刚创建的web下的两个新目录,然后去到依赖(dependencies),使用servlet技术我们需要导入servlet1的api:
点击+号,选择第一个导入jar包,选择你所下载好的tomcat文件,进入lib目录:
选择servlet-api:
然后再点击+号,选择第二项library:
导入我们的服务器:
两个打勾后点击ok,正常情况下你会发现web目录下你所创建的两个新的目录变了颜色:
到这一步我们的项目环境以及搭建好了,但是当创建文件时右键会发现没有servlet这个选项,这是因为该技术以及过于老旧,idea没有将它放在默认的文件创建中,这时我们需要去到右上角设置:
editor中选择file and code templates,在other中选择web中的java code templates,第一个和第二个的servlet模板区别在与servlet版本的区别,在4.0前,servlet存在于javax中,4.0后的版本甲骨文创造了一个新的类Jakarta,读者可以根据自己的servlet版本来选择:
选择好后复制模板代码,来到files中,点击左上角+号,创建一个名为Servlet名的模板,将复制的模板代码粘贴到框中
点击apply,这样,我们就可以在右键时创建servlet的文件了:
创建时会出现这个,也就是我上面所说的版本问题,javax或者Jakarta
3.Tomcat配置
回到我们创建的项目后,点击右上角:
会发现我们目前还没有服务器,我们点击edit configuration:
点击add new,选择tomcat server(注意不是tom ee server):
我们创建一个本地服务器,选择local:
下面的warning直接点击fix即可,然后apply-ok
如果你做到了这里,恭喜你,你已经完成我们框架的搭建,接下来根据你的项目需求完成代码运行即可。
提醒 值得注意的是,由于tomcat需要与servlet版本搭配,不然项目是跑不出来的,这里是官网的版本搭配链接:Apache Tomcat® - Which Version Do I Want?
可以发现servlet4.0最低版本的tomcat是9.0.x,读者这方面需要注意下。
使用关于歌手李健的一些问答,进行对比。整体感觉ChatGPT思维更清晰,逻辑更严谨,总结概括能力更强。
ChatGPT kimi [
{
“role”: “system”,
“content”: “你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。”
},
{
“role”: “user”,
“content”: “Kimi,水木年华的成员都有谁啊?”
},
{
“role”: “assistant”,
“content”: “水木年华是一支中国男子音乐组合,成立于2001年。最初由卢庚戌和李健组成,后来成员有所变动。以下是一些主要成员:\n\n1. 卢庚戌:水木年华的创始人之一,担任主唱和吉他手。\n2. 李健:同样是水木年华的创始人之一,也是主唱,后来离开了组合,发展个人事业。\n3. 缪杰:在李健离开后加入,成为新的主唱之一。\n4. 姚勇:后来加入的成员,担任吉他手。\n\n水木年华以其清新的校园民谣风格和深入人心的歌词而受到广泛欢迎。”
},
{
“role”: “user”,
“content”: “李健离开水木年华是哪一年啊?”
},
{
“role”: “assistant”,
“content”: “李健离开水木年华是在2002年。离开后,他开始了个人音乐生涯,并取得了巨大的成功,成为了中国著名的歌手和音乐制作人。”
},
{
“role”: “user”,
“content”: “李健为什么要离开水木年华呢?”
},
{
“role”: “assistant”,
“content”: “李健离开水木年华的具体原因并没有公开详细说明,但通常艺人离开团队或组合可能是由于个人职业规划、艺术方向、创作理念或个人生活选择等多方面的原因。李健在离开水木年华后,发展了自己的音乐事业,以其独特的音乐风格和深情的演唱获得了广泛的认可和喜爱。\n\n在艺术和娱乐行业中,艺人的职业发展道路往往是多变的,他们可能会根据自己的艺术追求和市场需求做出不同的选择。李健的离开和个人发展可以看作是他音乐生涯中的一个新起点,而他的成功也证明了他的选择是符合自己艺术追求的。”
},
{
“role”: “user”,
“content”: “李健离开水木年华组合之后,在音乐上都有哪些成果呢?”
},
{
“role”: “assistant”,
“content”: “李健离开水木年华后,他的音乐事业取得了显著的成就和广泛的认可。以下是一些他的音乐成果:\n\n1. 个人专辑:李健发行了多张个人专辑,其中包括《似水流年》、《为你而来》、《音乐傲骨》、《依然》等,这些专辑中的歌曲深受听众喜爱。\n\n2. 音乐风格:李健以其独特的音乐风格和深情的演唱著称,他的歌曲通常具有浓厚的文艺气息和深刻的情感表达。\n\n3. 音乐奖项:他的音乐作品获得了多项音乐大奖,包括中国音乐金钟奖、华语音乐传媒大奖等。\n\n4.
文章目录 一. 开始微调1. 选择合适的基础模型2. 微调和少样本学习2.1. 对比微调和少样本学习2.2. 微调需要的数据量 二. 使用OpenAI API进行微调1. 数据生成1.1. JSONL的数据格式1.2. 数据生成工具1.3. 数据文件的细节注意 2. 上传数据来训练模型3. 创建微调模型4. 列出微调作业5. 取消微调作业 二. 微调的应用1. 法律文本分析2. 自动代码审查-类Copilot3. 财务文档摘要4. 技术文档翻译5. 为专业领域生成内容 三. 微调的成本 OpenAI提供了许多可直接使用的GPT模型。尽管这些模型在各种任务上表现出色,但针对特定任务或上下文对这些模型进行微调,可以进一步提高它们的性能。
一. 开始微调 假设你想为公司创建一个电子邮件自动回复生成器。由于你的公司所在的行业使用专有词汇,因此你希望生成器给出的电子邮件回复保持一定的写作风格。要做到这一点,有两种策略:要么使用之前介绍的提示工程技巧来强制模型输出你想要的文本,要么对现有模型进行微调。
本文对微调进行讨论。
微调的基本逻辑
收集大量数据:对于这个例子,你需要收集大量电子邮件,其中包含关于特定业务领域的数据、客户咨询及针对这些咨询的回复。然后,你可以使用这些数据微调现有模型,以使模型学习公司所用的语言模式和词汇。微调后的新模型:微调后的模型本质上是基于OpenAI提供的原始模型构建的新模型,其中模型的内部权重被调整,以适应特定问题,从而能够在相关任务上提高准确性。 通过对现有模型进行微调,你可以创建一个专门针对特定业务所用语言模式和词汇的电子邮件自动回复生成器。
下图展示了微调过程,也就是使用特定领域的数据集来更新现有GPT模型的内部权重。微调的目标是使新模型能够在特定领域中做出比原始GPT模型更好的预测。
需要注意的是:新模型仍然在OpenAI服务器上
即使你使用自己的数据对LLM进行了微调,新模型也仍然保存在OpenAI的服务器上。你需要通过OpenAI API与新模型进行交互,而不是在本地使用它。
1. 选择合适的基础模型 在微调时,必须使用基础模型,而不能使用InstructGPT系列中的模型。
目前,微调仅适用于davinci、curie、babbage和ada这几个基础模型。这些模型都在准确性和所需资源之间做出了权衡。
开发人员可以为应用程序选择最合适的模型:
较小的模型(ada和babbage)可能在简单任务或资源有限的应用程序中更快且更具成本效益较大的模型(curie和davinci)则提供了更强的语言处理和生成能力,从而适用于需要更高准确性的复杂任务。 微调后的专有能力
上述模型不属于InstructGPT系列,它们没有经过RLHF阶段。通过微调这些基础模型,比如根据自定义数据集调整它们的内部权重,你可以针对特定的任务或领域定制模型。虽然没有InstructGPT系列的处理能力和推理能力,但是它们提供了强大的基础,让你可以利用其预训练的处理能力和生成能力来构建专门的应用程序。 2. 微调和少样本学习 2.1. 对比微调和少样本学习 模型是否进行了更新
微调是指针对特定任务在一组数据上重新训练现有模型,以提高模型的性能并使其回答更准确。在微调过程中,模型的内部参数得到更新。少样本学习则是通过提示词向模型提供有限数量的好例子,以指导模型根据这些例子给出目标结果。在少样本学习过程中,模型的内部参数不会被修改。 都可以用来增强GPT模型
微调可以帮助我们得到高度专业化的模型,更准确地为特定任务提供与上下文相关的结果。这使得微调非常适合有大量数据可用的场景。这种定制化确保模型生成的内容更符合目标领域的特定语言模式、词汇和语气。少样本学习是一种更灵活的方法,其数据使用率也更高,因为它不需要重新训练模型。当只有有限的示例可用或需要快速适应不同任务时,这种技巧非常有益。 2.2. 微调需要的数据量 微调通常需要用到大量数据。可用示例的缺乏往往限制了我们使用这种技巧。
简单任务:为了了解微调所需的数据量,可以假设对于相对简单的任务或仅需稍微调整的模型,通过几百个提示词示例才能获得相应的目标结果。当预训练的GPT模型在任务上表现良好但需要微调以更好地与目标领域对齐时,这种方法是有效的。复杂任务:对于更复杂的任务或需要更多定制化的应用场景,模型可能需要使用成千上万个示例进行训练。前述的电子邮件自动回复生成器正是这样一个应用场景。专业性强的任务:针对非常专业的任务微调模型,可能需要数十万甚至数百万个示例。这种微调规模可以显著地提高模型的性能,并使模型更好地适应特定领域。 ing
迁移学习是指将从一个领域学到的知识应用于不同但相关的领域。正因为如此,你有时可能会听到人们在谈论微调时提到迁移学习。
二. 使用OpenAI API进行微调 本节使用OpenAI API来微调LLM。我们将学习如何准备数据、上传数据,并使用OpenAI API创建一个经过微调的模型。
1. 数据生成 1.
背包问题其实有很多种,01背包是最基础也是最经典的,软工计科学生一定要掌握的。
01背包问题 代码随想录
视频讲解:带你学透0-1背包问题!| 关于背包问题,你不清楚的地方,这里都讲了!| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili
思路 直接上动态规划五部曲
1、dp数组及其下标的含义
对于背包问题,有一种写法, 是使用二维数组,即dp[i][j] 表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
2.确定递推公式
再回顾一下dp[i][j]的含义:从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少。
那么可以有两个方向推出来dp[i][j],
不放物品i:由dp[i - 1][j]推出,即背包容量为j,里面不放物品i的最大价值,此时dp[i][j]就是dp[i - 1][j]。(其实就是当物品i的重量大于背包j的重量时,物品i无法放进背包中,所以背包内的价值依然和前面相同。)放物品i:由dp[i - 1][j - weight[i]]推出,dp[i - 1][j - weight[i]] 为背包容量为j - weight[i]的时候不放物品i的最大价值,那么dp[i - 1][j - weight[i]] + value[i] (物品i的价值),就是背包放物品i得到的最大价值 所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
3.初始化
首先从dp[i][j]的定义出发,如果背包容量j为0的话,即dp[i][0],无论是选取哪些物品,背包价值总和一定为0。
再看其他情况。
状态转移方程 dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出i 是由 i-1 推导出来,那么i为0的时候就一定要初始化。
PyTorch, TensorFlow 和 JAX 功能对比简介 PyTorch、TensorFlow 和 JAX 是当前最流行的深度学习框架。它们各自具有独特的特性和优势,适合不同的应用场景和开发者需求。下面是对这三个框架的功能对比。
1. 基本概念和特性 PyTorch:
动态计算图(Dynamic Computation Graph):PyTorch 采用动态计算图,提供了更直观和灵活的调试体验。自动微分(Autograd):内置自动微分功能,方便进行反向传播和梯度计算。广泛的社区支持:拥有活跃的社区和丰富的第三方库,如 torchvision(计算机视觉)、torchaudio(音频处理)等。易于使用:API 设计直观,类似于 Python 的 NumPy,易于上手。 TensorFlow:
静态计算图(Static Computation Graph):最初采用静态计算图(Define-and-Run),现在也支持动态计算图(Eager Execution),结合了静态图和动态图的优势。自动微分:同样支持自动微分功能。丰富的生态系统:提供丰富的工具和库,如 TensorFlow Lite(移动设备)、TensorFlow.js(JavaScript)、TensorFlow Extended(生产环境)。生产级部署:提供了全面的部署工具和优化选项,适合大规模生产环境。 JAX:
与 NumPy 兼容:JAX 的 API 与 NumPy 非常相似,方便 NumPy 用户快速上手。自动微分:内置强大的自动微分功能,支持标量、矢量、矩阵和更高维度的微分操作。JIT 编译:使用 Just-In-Time 编译(JIT),通过 XLA 编译器优化计算性能。并行计算:提供 vmap 和 pmap 函数,方便向量化和并行计算。 2. 计算图 PyTorch:动态计算图,适合动态变化的网络结构,调试友好。TensorFlow:默认静态计算图,通过 Eager Execution 支持动态计算图,兼具静态图的优化性能和动态图的灵活性。JAX:通过函数转换和 JIT 编译生成优化的计算图,灵活且高效。 3. 自动微分 PyTorch:通过 Autograd 实现自动微分,使用简单直接。TensorFlow:通过 GradientTape 实现自动微分,支持复杂的梯度计算。JAX:内置自动微分功能,支持多种微分操作(如梯度、雅可比矩阵、海森矩阵)。 4. 硬件加速 PyTorch:原生支持 GPU,加上与 CUDA 的深度集成,实现高效计算。近期也支持 Apple Silicon。TensorFlow:广泛支持多种硬件(如 GPU、TPU),优化工具和库丰富。JAX:同样支持 GPU 和 TPU,通过 XLA 编译器实现高性能计算。 5.
Elasticsearch 是目前最常用的全文搜索引擎。它可以快速地存储、搜索和分析海量数据,广泛应用于维基百科、Stack Overflow、Github 等网站。
Elasticsearch 的底层是开源库 Lucene。直接使用 Lucene 需要写大量代码,而 Elasticsearch 对其进行了封装,提供了 REST API,使其开箱即用。
本文将详细讲解如何使用最新版本的 Elasticsearch 8.14.0 搭建自己的全文搜索引擎。
一、安装 Elasticsearch 需要 Java 环境。首先,确保你的机器上安装了 Java。如果没有,请先安装 Java,并正确设置环境变量 JAVA_HOME。
1. 下载和安装 Elasticsearch 可以从 Elasticsearch 的官方网站下载最新版本的 Elasticsearch:
$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.14.0-linux-x86_64.tar.gz $ tar -xzf elasticsearch-8.14.0-linux-x86_64.tar.gz $ cd elasticsearch-8.14.0/ 2. 启动 Elasticsearch 进入解压后的目录,运行以下命令启动 Elasticsearch:
$ ./bin/elasticsearch 如果遇到错误 "max virtual memory areas vm.max_map_count [65530] is too low",请运行以下命令解决:
$ sudo sysctl -w vm.max_map_count=262144 正常启动后,Elasticsearch 会在默认的 9200 端口运行。打开另一个命令行窗口,请求该端口以验证安装:
$ curl -k --user elastic 'https://localhost:9200' 你应该会看到类似以下的 JSON 响应,包含节点、集群、版本等信息:
今日课堂练习:vector构造函数
#include <iostream> #include <vector> using namespace std; void printVector(vector<int> &v) { vector<int>::iterator iter; for(iter=v.begin(); iter != v.end(); iter++) { cout << *iter << " "; } cout << endl; } int main() { vector<int> v; v.push_back(10); v.push_back(20); v.push_back(30); v.push_back(40); v.push_back(50); printVector(v); vector<int> v2 = v; printVector(v2); vector<int> v3(v2.begin()+2, v2.end()); printVector(v3); return 0; }
加载数据后的套路
df.head() df.info() df.describe() 选择部分数据
df[[要选中的列名的列表]] df.loc[,] df.iloc[,] df.query() 增加
df[新列名] = [新值] df.insert(loc , column,value =) 删除
df.drop() df.drop_duplicates() axis =0 可以改成1
inplace
修改数据
df.iloc[0,0] = 10 def func(x): return x s.apply(func) # 自定义处理,当修改的逻辑比较复杂的时候 df.apply(func ,axis = ) df.replace(to_replace = ,value=) 修改表结构
index
df.set_index() # 把df中一列数据变成行索引 df.reset_index() # 重置索引, 当前的索引会变成数据中的一列, 会添加一个从0开始计数的整数索引 df.rename(index = {},columns={}) df.columns = [] df.index = [] df.replace/df.rename 共同的特点, 老的值没找到, 不会报错, 正常执行, 不会改值
df.insert 是修改数据的API中, 没有inplace 参数的一个 , 直接在原来数据上进行修改
点击返回目录-> 基于C#开发web网页管理系统模板流程-总集篇-CSDN博客
前言,首先介绍一下本项目将要实现的功能 (一)登录界面 实现一个不算特别美观的登录窗口,当然这一步跟开发者本身的设计美学相关,像蒟蒻博主就没啥艺术细胞,勉强能用能看就行……
(二)管理系统主界面 实现一个不算特别美观的管理系统主界面
(三)页面链接 通过C#脚本实现登录界面输入正确密码后,能够跳转到管理系统主界面,按下主界面的【退出】按钮后,又回到登录界面
这里所提到的正确密码由本地数据库表中记录决定,本篇也将详细介绍数据库的连接操作
一,资源准备 (一)navicat及数据库 查看原文链接获取安装包以及安装教程
原文链接->Navicat安装配置(注册码)连接MySQL-CSDN博客
navicat连接MySQL后,根据你的管理系统创建一个本地数据库,可以使用sql文件或mdb文件等快速导入表和记录,博主提供本系列做演示用的一个仓库管理系统数据库,使用mdb文件导入,需要者点击链接下载->ckgl.mdb_免费高速下载|百度网盘-分享无限制 (baidu.com)
下图是mdb导入方式:
①创建数据库
②使用mdb文件导入表
③成功导入
双击表可查看记录
(二)VS2019/VS2022 理论上用VS2019~VS2022的版本都能实现,因为博主已经把很多坑踩完了,所以按照本篇的流程走,基本不会出错!本篇以VS2022作演示!
(1)开发包体介绍 开发包体是在开发过程中给开发者提供的大量框架、模板,能够大大提高开发效率!
在安装VS2019或VS2022后,Visual Studio Installer会同步安装,它是用来下载开发包体用的,怎么找到它?在【开始菜单】中很容易找到的!
(2)VS2019安装时需要选择以下开发包体 (3)VS2022安装时需要选择以下开发包体 (三)mysql接口程序及相关文件 (1)mysql配置 博主仅提供5.7版本的mysql直装(链接中有ppt直装教程),需要其它直装版本的话自行去官网获取(官网搜mysql)->百度网盘 请输入提取码
当然,我更建议你使用phpstudy一键完成安装,请看本篇->第二篇:MySQL安装与配置(基于小皮面板(phpstudy))_配置小皮面板-CSDN博客
(注:两种方式本质都是安装mysql,只不过第二种方式更加贴切电脑小白,但需要安装phpstudy这个第三方软件,你只要选择其中一种方式安装即可)
测试:【win+R】打开运行窗口->输入【cmd】打开命令行窗口->输入【mysql -u root -p】->输入你的mysql数据库密码,能够出现【mysql>】的提示符证明测试成功,如下图
此时你还需要确认自己的mysql版本,在上一步测试的基础上,继续输入sql查询语句【select version();】,例如博主这里的是5.n版本(后面的.7.17不必关心),此时需要你记住这个版本号
(2)odbc接口程序 odbc接口程序用于连接数据库,你需要下载与自己版本号相对应的接口程序
如果你跟我一样是5.n版本的mysql,我在这个链接中直接提供给你接口程序供下载(当然你也可以自己去下面我提供的官网链接下载)->百度网盘 请输入提取码
注意,选择需要的位数下载,(一个32位、一个64位,建议用64位,博客中全程使用64位演示)并双击运行安装
安装过程中只有下图这一个处需要做出选择,其它一律保持默认点击下一步
如果你跟我的版本不一样是其它版本的mysql,需要你自行去mysql官方找到对应版本并下载安装,也是请注意,(当然如果mysql版本过新可能直接抛弃了32位,这时你只能下载64位的)
mysql-odbc官网->MySQL :: Download MySQL Connector/ODBC (Archived Versions)
安装好后,开始菜单搜索odbc,打开ODBC数据源(64位),在这一步,如果你下载的是32位的odbc,则选择ODBC Data Sources(32-bit),后续步骤相同
点击【添加】->找到刚下载的对应自己mysql版本号的odbc接口程序,按图片输入相关信息,点【Test】测试连接成功后点OK创建连接
如果你用的是8.几版本的odbc,创建数据源时,最好使用如下图红框所示的ANSI Driver
(3)三张图片 准备三张图片供开发,这一步的要求是最轻松的了,这三张图片起到的作用就是本篇【前言】部分展示的管理系统主界面的背景图
二,创建项目 (一)配置新项目 打开vs2022,点击右下角【创建新项目】
上方搜索框中输入asp,注意此处选择第二个下方带有C#标识的模板(这一步极容易选错,请仔细对照下图确认选择正确!),点击下一步
项目名称建议设置为和本地的数据库同名,位置选择一个合适的位置方便自己能找到(建议新手直接放桌面,本篇演示直接放桌面了),点击创建