一、设计框架 1.在建立了一组需求之后,设计即将开始,建议采取自上面下的方式,首先把重点放在大的方面,生成低保真且不包含具体细节的方案,一般通过写剧本来确定交互设计模式与逻辑。
2.设计框架:
先站在一个高层次上关注用户界面和相关行为的整体结构。
3.步骤:
(1)定义产品外形、交互姿势和输入方法。
(2)定义功能和数据元素:
数据元素通常是交互产品中的基本主体,如相片、电子邮件、订单。
功能元素指对数据元素的操作及其在界面上的表达,包括操纵数据元素的工具。
(3)确定功能组和层级:
元素分组的目的是更好地在任务中和任务间来帮助促进任务角色的操作流程 。
(4)勾画大致的设计框架(这里这个图其实就可以认为是低保真了)
(5)构建关键线路场景剧本
关键路线就是:人物模型 + 场景 + 数据 + 功能元素
这一部分是通过文本的形式,其实就是编的小故事,描述了人物角色如何同产品交互,必须在细节上严谨地描述每个主要交互的精确行为,以任务为依托,使得最初设定的人物模型对交互架构产生反复、充分的使用,并最终通过磨合,发现不合理的设计。
(6)通过验证性的场景剧本来检查设计
4.不同阶段的场景剧本:
(1)情境场景剧本:设计开始之前,以某个用户角色的视角写的,专注于人类活动、感知和愿望。
(2)关键线路场景剧本:设计框架,专注于关键的用户交互,专注于某个用户角色是如何使用产品完成他们的目标。
(3)验证场景剧本:测试设计方案,对可能的解决方案使用大量的’如果…,会…“的问题。
二、简化设计的策略 1.删除
(1)最明显的简化设计方法
(2)好处:删除杂乱的特性,让设计师专注于把有限的重要问题解决好,有助于用户心无旁骛地完成自己的目标
(3)避免错删,删除不重要的功能,同时不能盲从用户增加功能。
2.组织
(1)按照有意义的标准对界面组件进行分组。
(2)相比较删除策略,组织不需要太大的投入
(3)是最快捷的简化设计方式。
(4)提到组织,首先想到的就是分块。唯一可以肯定的是,分块越少,选择越少,用户的负担就越轻。
3.隐藏
(1)最不重要的组件和信息以某种方式隐藏起来,避免分散用户的注意力。
(2)隐藏是一种低成本的简化方案
(3)用户不会因不常用的功能分散注意力,可作为删除不必要功能的开始。
(4)尽可能彻底隐藏所有需要隐藏的功能,只在合适的时机和位置上显示相应的功能。
(5)渐进展示,适时出现都是一种不错的隐藏策略。
(6)让功能易于发现
三、设计中的折中 1.个性化和配置
(1)人们喜欢改变周围的事物,使之适合自己
(2)必须简单易用
(3)必须容易撤销
2.本地化和国际化
(1)改变语言只是国际化中最简单的部分。
(2)改变版面和排列方式
3.审美学与实用性
(1)如为确保文本的可读性,文本的背景采用较低的对比度
(2)组件之间的空白非常重要
(3)组件的对齐会影响界面的可理解性和易用性
(4)组件大小是用来传递含义和在可视功能部件中建立联系或者区分的另一种视觉尺寸。
四、软件设计的细节 1.设计体贴的软件
(1)具有常识
(2)尽责
(3)自信
(4)不问过多问题
(5)知道什么时候调整规则
(6)承担责任
2.加快系统的响应时间
3.减轻用户的记忆负担
4.减少用户的等待感
(1)以某种形式的反馈让用户了解操作进行的进度和状态。
有时您无法解锁手机,因为您忘记了密码或设备停止响应解锁图案。不要惊慌。我们在这里为您列出了最好的 Android 解锁工具。只需选择一个您喜欢的。
为了保护重要数据,许多手机用户倾向于使用图案锁、密码、指纹甚至面部识别来锁定设备。但有时,他们无法解锁手机,因为他们忘记了复杂的密码、多次输入错误的锁定图案或手机受到恶意代码的攻击等。
那么,是否可以解锁已锁定的 Android?当然可以。解锁 Android 手机的一个好方法是使用专业的 Android 解锁工具软件来移除锁定屏幕。因此,在本文中,我们将向您介绍最好的 Android 解锁工具以及其优缺点。请继续阅读。
1. 奇客Android 解锁工具 最推荐的手机解锁软件是奇客Android 解锁工具。它能够在不输入密码的情况下解除 Android 手机的屏幕锁。无论您使用 PIN、密码、图案、指纹 ID 还是面部识别,您都可以使用 奇客Android 解锁工具 解锁手机。因此,您可以在几分钟内再次完全访问锁定的设备。
主要特征: 它支持您解锁忘记的图案锁、密码、PIN、指纹ID、面部识别等。 支持 20,000 多种型号的 Android 手机和平板电脑,包括三星、LG、华为、谷歌、HTC 等。无需root。保证您的隐私和设备100%安全。DroidKit 让复杂的解锁过程变得简单,每个人都能轻松完成。无需任何技术知识。解锁后,奇客Android 解锁工具还可以帮助您恢复有或没有备份的数据、修复常见的系统问题、绕过 FRP 锁、从 Google 帐户中提取数据等等。 使用奇客Android 解锁工具解锁Android手机: 步骤 1. 下载奇客Android 解锁工具并在您的电脑上运行它。通过 USB 数据线将您的 Android 手机连接到电脑。在界面上,选择 “解锁屏幕”。
安卓手机解锁-奇客软件轻松解锁安卓设备的数字密码、指纹密码、人脸识别锁。不限型号,无需密码,没有使用门槛。https://www.geekersoft.cn/geekersoft-unlockgo-android.html
步骤2. 阅读说明并单击 “开始” 按钮。当您看到以下界面时,单击“ 立即删除” 按钮。
步骤3.选择您的设备品牌。奇客Android 解锁工具将根据您的手机品牌准确解锁您的手机。然后您需要按照屏幕上的说明删除屏幕密码。
步骤4. 完成上述步骤后,奇客Android 解锁工具将开始移除屏幕锁。等待一分钟,屏幕将解锁。
2. Android解锁工具 很多人在谈论手机解锁软件时都会想到 Android Unlock Tool。也许您忘记了设置的密码,或者刚刚收到一部二手 Android 手机而不知道锁屏密码。不用担心,Android Unlock 可让您在几分钟内解锁。Android 上的图案、PIN、密码和指纹锁屏都可以绕过,您可以毫无障碍地使用手机。
快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C++》 远方有一堆篝火,在为久候之人燃烧! 文章目录 引言一、栈的概念二、栈的模拟实现2.1 定义2.2 初始化2.3 销毁2.4 压栈2.5 判空2.6 出栈2.7 获取栈顶元素2.8 获取栈的元素个数2.9 元素访问 三、栈的应用场景 引言 数据结构世界——栈(Stack)
一、栈的概念 栈,是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
二、栈的模拟实现 栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。
2.1 定义 typedef int STDataType; typedef struct Stack { STDataType* a; int top; int capacity; }ST; 当前元素个数用栈顶top来表示,是栈独有的表示方法 2.2 初始化 void STInit(ST* pst) { assert(pst); pst->a = NULL; pst->top = 0;//top指向栈顶元素的下一个位置 pst->capacity = 0; } 栈的初始化,top可以为0或-1,top为0,则指向栈顶元素的下一个位置,top为-1,则指向栈顶元素的位置这里选用top为0,因为后面写的适合方便理解 2.3 销毁 void STDestroy(ST* pst) { assert(pst); free(pst->a); pst->top = pst->capacity = 0; } 栈的销毁和顺序表一样,直接释放数组空间,将top和capacity置为0 2.
文章目录 前言一、如何才能学会Rust?二、Rust学习路线图第一阶段:Rust基础学习第二阶段:Rust核心特性学习第三阶段:Rust高级特性和应用第四阶段:项目实践第五阶段:持续学习与探索 三、Rust游戏开发赠书方式 前言 Rust 生态飞速发展,展现出了勃勃生机。与一年以前相比,现在的 Rust 生态是足以满足开发的所有需求,无论你是Web开发者,物联网开发者,或者是操作系统开发者,又或者是游戏开发者,在Rust中总能找到你所需要的资源,无论是朋友,还是书籍影像制品,都会让你得到快速的提升,从而达到你的目的。
一、如何才能学会Rust? Rust 难学,这已经不是一天两天的事情了,这已经是众所周知的事情。经过我的调研,在学习 Rust 过程中,存在的难点主要是以下几点:
语法怪,与传统编程语言存在较大差异,导致如果有编程语言基础的人学习会造成巨大困难。所有权和借用检查难以理解,作为 Rust 的核心特性之一,它是保证内存安全的重要所在,可以避免数据竞争和野指针问题。生命周期标注,意味着在编写代码时就必须关注引用的生命周期,对于学习者来说是个头疼的问题。代码乱,由于Rust抛弃了传统编程语言思维,这就导致代码看起来跟C语言一样,一些代码看起来莫名其妙的。 如果你现在正因为这些在考虑是否要继续学习下去,我希望你也能同时看到 Rust 好的一面。Rust 目前正在快速的改变这个世界,它所带来的收益是相当可观的,即使是微软或者 Linux 都在改用 Rust,而且现在 Rust 也存在很多高薪工作,如果你想要谋生也是一个绝佳的选择。
幸运的是,社区的各路大神都在为方便学习 Rust 努力奋斗,有的人在翻译文档,有的人在录制视频,最终都是一个目的,帮助你学会 Rust。我也会分享大量学习 Rust 资料到我的博客,或者你可以与我联系,一起学习,一起成长。
二、Rust学习路线图 关于学习 Rust,已经有很多专家努力帮助大家轻松掌握该语言。如上图就是最新发布的 Rust 学习路线图,该路线图我会在后面的文章中详细讲解,这里简单介绍一下学习 Rust 的几个阶段:
第一阶段:Rust基础学习 1. 熟悉编程基础
如果你没有编程基础,建议先学习一门简单的编程语言(如Python),以便理解基本的编程概念,如变量、数据类型、控制流语句等。 2. Rust基础教程
安装Rust工具链(rustup, cargo等),并阅读Rust官方文档,特别是入门指南。完成官方文档中的练习,并使用exercism.io或Rustlings练习题来加强理解。 第二阶段:Rust核心特性学习 1. 数据结构
学习Rust中的基本数据结构,如枚举(Enums)、结构体(Structs)、元组(Tuples)。举例:定义一个结构体表示一个矩形,包含长和宽两个字段,并实现一个方法来计算面积。 2. 特质(Traits)和泛型(Generics)
理解特质如何定义类型的行为,并使用泛型编写与类型无关的代码。举例:实现一个可打印(Printable)特质,允许不同类型的对象都能打印自身信息;使用泛型编写一个能够处理不同类型列表的函数。 3. 所有权(Ownership)和借用(Borrowing)
深入理解Rust的所有权系统和借用检查机制,这是Rust内存安全性的基础。举例:编写一个函数,该函数接受一个字符串的引用作为参数,并在函数内部进行字符串的拼接和返回(注意处理借用和所有权的转换)。 第三阶段:Rust高级特性和应用 1. 并发编程
学习Rust的并发编程模型,包括线程(Threads)、异步(Async/Await)等。举例:使用Rust的线程库编写一个简单的多线程程序,或者使用async/await编写一个异步HTTP客户端。 2. 系统编程
学习Rust在系统编程中的应用,如文件操作、网络编程等。举例:使用Rust的标准库编写一个文件读写程序,或者使用Rust的网络库编写一个简单的TCP服务器。 3. 生态系统探索
探索Rust的生态系统,了解常用的第三方库和工具,并尝试在项目中应用它们。举例:使用Cargo工具来管理项目依赖,并使用Serde库进行JSON序列化和反序列化。 第四阶段:项目实践 1. 基础项目
Unity中的粒子系统(Particle System)是一个强大的组件,用于创建和控制大量粒子的渲染和行为。粒子系统常用于模拟各种视觉效果,如火焰、烟雾、雨滴、雪花、魔法效果等。
粒子系统的概念: 粒子系统由以下关键概念组成:
粒子:系统的最小单元,可以具有位置、速度、颜色、大小等属性。发射器:粒子生成的源头,控制粒子的发射速率、发射形状和方向。生命周期:粒子从生成到消失的时间。初始参数:粒子生成时的初始状态,如初始速度、初始大小、初始颜色等。力和场:影响粒子运动的因素,如重力、风力、漩涡力等。渲染器:决定粒子如何在场景中显示,可以是简单的点、图片或复杂的网格。 粒子系统的用法: 创建视觉效果:使用粒子系统来创建复杂的视觉效果。动态效果:根据游戏逻辑动态控制粒子系统的属性,如发射速率、颜色等。性能优化:粒子系统可以高效渲染大量粒子,但需要合理配置以避免性能问题。 代码示例: 以下是一个Unity C#脚本示例,展示了如何通过代码控制粒子系统的发射:
using UnityEngine; public class ParticleController : MonoBehaviour { public ParticleSystem particleSystem; // 引用粒子系统组件 void Update() { // 根据玩家输入控制粒子系统的发射 if (Input.GetKeyDown(KeyCode.Space)) { // 激活粒子系统的发射 particleSystem.Play(); } else if (Input.GetKeyUp(KeyCode.Space)) { // 停止粒子系统的发射 particleSystem.Stop(); } } void ChangeParticleColor(Color newColor) { // 更改粒子系统渲染器中粒子的颜色 ParticleSystem.Particle[] particles = new ParticleSystem.Particle[particleSystem.main.maxParticles]; int count = particleSystem.GetParticles(particles); for (int i = 0; i < count; i++) { particles[i].
事务二 1.数据库并发的场景2.读-写2.1 3个记录隐藏字段2.2 undo日志2.3 模拟 MVCC2.4 Read View2.5 RR 与 RC的本质区别 3.读-读4.写-写 点赞👍👍收藏🌟🌟关注💖💖
你的支持是对我最大的鼓励,我们一起努力吧!😃😃
关于事务的所有知识上篇博客我们都说过了,今天这篇博客主要是为了解密,RC和RR隔离级别,它怎么做到一个事务提交了,其他事务还看不到。数据不是只有一份吗,他改了我怎么看不到,这个原理是怎么样的?
之前说的隔离性和隔离级别的话题,前提是多事务进行并发运行,所以我们应该想明白的是一个数据库在被并发访问时它的场景有那些,因为只有知道场景才能针对不同场景提供不同方案。
1.数据库并发的场景 数据库并发的场景有三种:
读-读 :不存在任何问题,也不需要并发控制,因为没有人去修改读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读写-写 :数据库只会被人写,事务都是写事务,一定通过加锁来保证数据安全。否则有线程安全问题,事务不是有回滚吗,有可能一个事务在更新另一个事务回滚了彼此交叉运行,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失(后面补充), 2.读-写 就像之前做的实验,读到的数据和写的数据是不一样的,其实这已经证明读写的数据不是同一份。后面再说。在读写并发实现很好的隔离性采用的核心技术之一多版本并发控制。
多版本并发控制( MVCC ) 是一种用来解决 读-写冲突 的无锁并发控制
历史上在说事务的时候一直强调事务是原子的,但是事务在执行一定是有执行中,mysql为了解决执行中对应的并发问题,也一定要让事务在执行的时候有先有后,保证事务那些数据能看到那些数据看不到,所以它一定要判定事务的先后问题!事务在怎么同时到来一定有先有后。那问题是怎么区分事务的先后问题?
mysql为事务分配单向增长的事务ID,事务与事务ID是一对一的关系。事务ID越小代表来的越早,ID越大代表来的越晚,所以可以通过ID来判定事务的先后顺序。为每个修改保存一个版本,版本与事务ID关联,读操作只读该事务开始前的数据库的快照。 所以 MVCC 可以为数据库解决以下问题
在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题 每个事务都要有自己的事务ID,可以根据事务ID的大小,来决定事务到来的先后顺序。
一个事务可以交给mysql运行,两个十个都可以由多个客户端并发的交给mysql,也就是说mysqld可能会面临同时处理多个事务的情况, 事务在使用mysql的人看来它是原子的,但在mysql内部它一定要有个执行的过程,所以它的执行过程就证明mysql中事务也有自己的生命周期,事务要被创建,要被放到某个等待队列里,要被执行,执行出错要被回滚,执行完毕事务要被消除,这些都指向一点mysqld要对多个事务进行管理,先描述,在组织! 换句话说事务在我看来,mysqld中一定是对应的一个或者一套结构体对象/类对象,事务也要有自己的结构体那每个事务都要有自己的事务ID是不是就好理解了。来一个事务就new一个事务对象,对事务的管理就变成了对某种数据结构的增删查改。
有了这个概念,我们再来谈事务隔离级别具体的解决方案MVCC。不过在谈MVCC之前我们要先知道三个前提知识:
3个记录隐藏字段undo 日志Read View 2.1 3个记录隐藏字段 其实我们在建表的时候指明有多少列,你以为有4列、5列等等,可实际上mysql都要默认给添加上3个隐藏字段。
DB_TRX_ID :6 byte,最近修改( 修改/插入 )事务ID,记录这条记录/最后一次修改该记录的事务ID。 比如说未来在表中插入任何数据,插入的这条记录是那个事务插入的,事务ID是谁,要把事务ID放在表中。无论是手动启动事务还是单SQL由系统默认封装的事务,最终在数据库中所以操作的SQL必须以事务的方式让mysql统一执行。每一个事务都有ID,所以所有表的操作都要和事务ID关联起来保存到表里。
DB_ROLL_PTR : 7 byte,回滚指针,指向这条记录的上一个版本(简单理解成,指向历史版本就行,这些数据一般在 undo log 中) 实际上你对表中某一行记录做修改,mysql在特定的隔离级别下,不是让直接去改表中的数据,它会把你要改的这条记录先保存一份,让你改最新表中的数据,这样的话就可以在改之后也可以知道历史的数据是什么,这种策略特别想像 写时拷贝。增加、修改、删除都是要先把数据保存一份,然后改最新的数据。然后最新记录要能找到它历史的最新信息,所以有了这个 回滚指针。指向被修改之前的上一个版本。
DB_ROW_ID : 6 byte,隐含的自增ID(隐藏主键),如果数据表没有主键, InnoDB 会自动以DB_ROW_ID 产生一个聚簇索引补充:实际还有一个删除flag隐藏字段, 记录当前记录的状态,是被更新过还是被删除了。一般删除并不是把这条记录真的删除了,只是把flag变了。我们建立的表结构是在聚簇索引的叶子节点中以page方式存在,它是内存级的。所以删除的时候我们并不需要把数据情况还要做各自表结构的移动那太麻烦了。所以我只需要把它清掉就可以,清掉之后只需要最终维持page是脏的或者干净的,后面刷盘的时候在把数据排列到磁盘中。下次在不就连续了嘛。 建一个学生表
1.淘宝商品页 代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>鲜花 淘宝搜索</title> <style> *{ margin: 0px; } body{ height: 4000px; } .main-body{ background-color: #e3e3e8bf; } .content{ background-color: #f5f5f5; color: #6C6C6C; } .content > span{ width: 80px; height: 35px; padding-left: 8px; font-size: 13px; } .content > :nth-child(1), .content > :nth-child(7){ margin-left:120px ; } .body{ margin: auto; width: 1158px; height: 97px; } .taobao > img{ margin-top: 25px; padding-left: 50px; } .
文章目录 每日一句正能量前言背景介绍能力分析通用大模型的能力:垂直大模型的能力:差异与互补性分析: 难点探究1. 算力挑战2. 数据挑战3. 算法挑战4. 泛化能力5. 可解释性和透明度6. 伦理和偏见问题7. 成本效益 后记 每日一句正能量 昨天已逝,明日是谜,面对今朝,尽力而为!
前言 在人工智能的快速发展浪潮中,AI大模型作为这一领域的明珠,正以其强大的数据处理能力和智能决策能力,引领着技术革新的潮流。随着技术的不断成熟和应用场景的不断拓展,AI大模型的战场开始呈现出分化的趋势。其中,通用大模型以其广泛的适用性和灵活性,赢得了众多关注和应用;而垂直大模型则以其在特定领域的深度优化和专业性能,展现出独特的优势。
通用大模型,顾名思义,是指那些设计之初就考虑到广泛适用性,能够处理多种任务和场景的AI模型。它们通常具有较大的参数量和强大的泛化能力,可以在多个领域和任务中发挥作用,如自然语言处理、图像识别、游戏等。然而,正是这种泛化性,也可能导致其在特定领域的专业性不足。
与此同时,垂直大模型则专注于特定行业或领域,通过对特定数据和问题的深入学习,实现更精准、更高效的解决方案。这类模型往往在特定领域内具有更高的性能和更深入的理解,但同时也受限于其应用范围的局限性。
那么,在这场AI大模型的较量中,哪一方更具优势?是通用大模型的广泛适用性更能满足多样化的需求,还是垂直大模型的专业性能更能解决特定领域的问题?本文将从多个角度探讨这一问题,分析两种模型的优势和局限,以及它们在不同应用场景下的表现和潜力。
通过对通用大模型和垂直大模型的深入分析,我们将探讨它们在实际应用中的适用性、效率、成本和未来发展的可能性。我们也将讨论如何根据具体需求和场景,选择合适的AI大模型,以及如何结合两者的优势,实现更优的智能解决方案。让我们一同走进AI大模型的世界,探索它们在智能科技领域的无限可能。
背景介绍 在人工智能技术的飞速发展中,AI大模型已经成为推动行业进步的关键力量。这些模型通过海量数据训练,学习到了丰富的特征和模式,从而在各种复杂任务中展现出卓越的性能。目前,AI大模型主要分为两大类:通用大模型和垂直大模型,它们各自在不同的领域和应用场景中发挥着重要作用。
通用大模型的发展情况:
通用大模型,如Google的BERT、OpenAI的GPT系列,以及Meta的DALL-E等,以其广泛的适用性和强大的泛化能力而闻名。这些模型通常在大规模的通用数据集上进行训练,能够处理多种语言理解、图像生成、文本到图像的转换等任务。由于其灵活性和广泛的应用前景,通用大模型受到了业界的广泛关注,并在学术界和工业界都取得了显著的成果。
垂直大模型的发展情况:
与通用大模型相对的是垂直大模型,它们专注于特定行业或领域,如医疗、金融、法律等。这些模型在特定领域的数据上进行训练,以实现更精准的预测和决策支持。垂直大模型的优势在于它们能够深入理解特定领域的专业知识和术语,提供更加定制化的服务。随着行业对AI技术需求的不断细化,垂直大模型在特定领域内的应用也越来越受到重视。
哪一路径在具体实践中更为火热:
在具体实践中,通用大模型和垂直大模型各有其火热之处。通用大模型由于其广泛的适用性,吸引了大量的研究和投资,特别是在自然语言处理、计算机视觉等领域。它们为多种应用提供了基础性的技术支持,推动了技术的普适性发展。
而垂直大模型则在特定行业内展现出强大的竞争力。随着行业对AI技术专业化需求的增加,垂直大模型能够提供更加精准和高效的解决方案,特别是在需要处理大量领域特定数据的场合。例如,在医疗影像分析、金融风险评估等领域,垂直大模型已经成为不可或缺的工具。
总体来看,通用大模型和垂直大模型各有优势,它们在不同的应用场景和需求下发挥着不同的作用。随着技术的不断进步和市场需求的不断变化,两者之间的界限也可能逐渐模糊,未来可能会出现更多结合通用性和垂直性特点的混合型模型,以满足更多样化的AI应用需求。
能力分析 在人工智能领域,通用大模型和垂直大模型代表了两种不同的技术发展路径,它们各自具有独特的能力和优势。深入分析这两种模型的能力差异及其互补性,有助于我们更好地理解它们在实际应用中的潜力和局限。
通用大模型的能力: 广泛的适用性:通用大模型经过大量多样化数据的训练,能够适应多种不同的任务和场景,如语言翻译、情感分析、图像识别等。
强大的泛化能力:由于训练数据的多样性,通用大模型在面对未见过的数据或任务时,通常能够表现出较好的泛化能力。
技术引领性:通用大模型往往是技术发展的前沿,推动了深度学习、自然语言处理等领域的理论创新和应用突破。
灵活性:通用大模型可以较容易地调整和优化,以适应新的任务或数据集,提供了较高的灵活性。
垂直大模型的能力: 领域专业性:垂直大模型专注于特定领域,如医疗、金融等,它们在这些领域内拥有更深入的知识和理解。
高精度:在特定领域内,垂直大模型由于专注于处理特定类型的数据和问题,因此往往能够提供更高精度的预测和决策。
定制化服务:针对特定行业的痛点和需求,垂直大模型能够提供更加定制化的解决方案,满足特定用户群体的需求。
合规性和安全性:在对数据隐私和安全性要求较高的领域,如金融和医疗,垂直大模型可以更好地符合行业规范和标准。
差异与互补性分析: 差异性:通用大模型的优势在于其广泛的适用性和泛化能力,而垂直大模型则在特定领域内提供更专业的服务和更高的精度。
互补性:在实际应用中,通用大模型可以作为基础技术平台,提供通用的智能服务,而垂直大模型则可以在此基础上进行二次开发,以满足特定行业的需求。例如,一个通用的语言模型可以被进一步训练,以适应法律领域的专业术语和文本风格。
集成应用:在某些情况下,可以将通用大模型和垂直大模型结合起来使用,以发挥各自的优势。例如,在处理医疗影像时,可以使用通用大模型进行初步的图像识别,然后使用垂直大模型进行更精细的诊断。
技术发展:随着技术的进步,通用大模型和垂直大模型之间的界限可能会变得模糊。未来的模型可能会在保持一定泛化能力的同时,也具备处理特定领域任务的能力。
总结来说,通用大模型和垂直大模型各有所长,在不同的应用场景中发挥着不同的作用。理解它们的能力差异和互补性,有助于我们更有效地利用这些强大的工具,推动人工智能技术的发展和应用。
难点探究 大模型在人工智能领域的应用虽然展现出巨大潜力,但同时也面临着一系列挑战,尤其是在算力、数据和算法这三大核心要素上。以下是对这些难点的探究和可能的解决策略:
1. 算力挑战 问题:大模型通常需要大量的计算资源来进行训练和推理,这对算力提出了很高的要求。
解决策略:
分布式计算:利用分布式系统和云计算资源,将计算任务分散到多个节点上并行处理。专用硬件:使用GPU、TPU等专为深度学习设计的硬件加速模型训练和推理过程。模型优化:通过模型剪枝、量化等技术减少模型的计算复杂度,降低对算力的需求。 2. 数据挑战 问题:高质量的数据是训练大模型的关键,但获取、清洗和标注大量数据既耗时又昂贵。
解决策略:
数据增强:使用数据增强技术生成更多的训练样本,减少对原始数据的依赖。自动化标注:利用已有模型辅助自动化数据标注过程,提高效率。合成数据:在一些领域,如自动驾驶,可以使用模拟环境生成合成数据。 3. 算法挑战 问题:随着模型规模的增大,算法的设计和优化变得更加复杂。
解决策略:
正则化技术:应用Dropout、权重衰减等正则化方法防止模型过拟合。优化算法:研究和应用更高效的优化算法,如Adam、LAMB等,以加快收敛速度。模型架构:设计更高效的模型架构,如Transformer、BERT等,以提高模型的性能和泛化能力。 4. 泛化能力 问题:大模型在特定数据集上表现出色,但在新的或不同的数据上可能泛化能力不足。
解决策略:
多任务学习:通过多任务学习让模型在多个相关任务上进行训练,提高其泛化能力。持续学习:不断更新模型以包含新的数据和趋势,保持其时效性和准确性。 5.
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 015 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进一步完善自己对整个 Java 技术体系来充实自己的技术栈的同学。与此同时,本专栏的所有文章,也都会准备充足的代码示例和完善的知识点梳理,因此也十分适合零基础的小白和要准备工作面试的同学学习。当然,我也会在必要的时候进行相关技术深度的技术解读,相信即使是拥有多年 Java 开发经验的从业者和大佬们也会有所收获并找到乐趣。
–
Java 集合框架(Java Collections Framework)是 Java 标准库中的一个核心组件,它提供了一套用于处理数据集合的接口和类。作为其中的重要成员,Vector 和 Stack 在特定场景中扮演着关键角色。Vector 是一种同步的动态数组,实现了 List 接口,适用于需要线程安全的场景;而 Stack 是 Vector 的子类,提供了后进先出(LIFO)的数据结构操作。本文将对 Vector 和 Stack 进行全面的介绍,探讨它们的使用方法、工作原理以及源码实现,以帮助开发者深入理解和高效使用这些集合类。同时,通过源码解析,我们将揭示其内部机制,为优化和定制提供有力支持。
文章目录 1、 Vector 与 Stack1.1、Vector 概述1.2、Stack 概述 2、Vector 的具体实现原理2.1、Vector 底层的数据结构2.2、Vector 的扩容2.3、Vector 对线程安全的实现 3、Stack 的具体实现原理4、Vector 与 Stack 的过时原因与替代类4.1、不推荐使用 Vector 来实现线程安全的原因4.2、Stack 过时的原因 1、 Vector 与 Stack 写在前面:在开始介绍 Vector 与 Stack 之前,我们首先应该了解的是 Vector 与 Stack 这两个类在如今的 Java 版本中都早已过时,在 Java 出于对向后兼容性的考虑,才没有删除。但是我们不会因此认为 Vector 与 Stack 的实现是没有必要了解了,因为二者依旧会偶尔出现在面试问题当中。
在ASP.NET Core中,路由是核心功能之一,用于将HTTP请求映射到相应的控制器操作。虽然“路由驱动设计模式”是一个我刚杜撰出来的设计模式名称,但我们可以基于ASP.NET Core的路由特性,构建一种以路由为中心的设计模式。
以下是一个基于ASP.NET Core的“路由驱动设计模式”的构想:
模式名称:基于特性的动态路由映射模式(Attribute-Based Dynamic Routing Pattern)-ADRP
核心概念:
路由特性(Routing Attributes):使用ASP.NET Core内置的路由特性(如HttpGet, HttpPost, HttpPut, HttpDelete等)来显式定义每个控制器操作的路由。
动态路由构建:在启动时,通过反射动态扫描控制器和操作上的路由特性,构建完整的路由表。这样可以根据业务需求灵活地添加、修改或删除路由,而无需修改大量的配置代码。
路由约束:利用路由约束来进一步细化路由匹配规则,确保请求被正确映射到相应的操作。
中间件集成:结合ASP.NET Core的中间件特性,可以在路由处理过程中添加自定义逻辑,如身份验证、授权、日志记录等。
实现步骤:
定义控制器和操作:在控制器类上使用路由特性来定义每个操作的路由。例如:
[ApiController] [Route("[controller]")] public class UsersController : ControllerBase { [HttpGet("{id}")] public IActionResult GetUser(int id) { // ... } [HttpPost] public IActionResult CreateUser([FromBody] User user) { // ... } } 动态构建路由表:在应用程序启动时,使用反射扫描所有的控制器类,并读取其上的路由特性。根据这些信息,动态构建路由表,并将其注册到ASP.NET Core的路由系统中。
配置中间件:根据需要,在路由处理过程中添加必要的中间件。例如,可以添加一个身份验证中间件来验证用户的身份,或者添加一个日志记录中间件来记录每个请求的信息。
处理请求:当HTTP请求到达时,ASP.NET Core的路由系统将根据动态构建的路由表将请求映射到相应的控制器操作。在操作过程中,可以进一步利用路由数据和模型绑定等功能来处理请求参数和返回结果。
优点:
灵活性:通过动态构建路由表,可以轻松地添加、修改或删除路由,而无需修改大量的配置代码。这有助于快速响应业务需求的变化。
可读性:使用路由特性可以明确地看到每个操作的路由信息,提高了代码的可读性和可维护性。
可扩展性:结合中间件特性,可以在路由处理过程中添加自定义逻辑,以满足特定的业务需求。
提示:这个“路由驱动设计模式”是基于ASP.NET Core的现有功能和特性在我如厕的时候颅内构建的,并不是现有的或官方的设计模式。它只是为了提供一种以路由为中心的开发方式,以适应快速变化的Web应用程序需求。
目录 1.图的遍历1.广度优先遍历2.深度优先遍历 2.最小生成树1.Kruskal算法2.Prim算法 1.图的遍历 给定一个图G和其中任意一个顶点 v 0 v_0 v0,从 v 0 v_0 v0出发,沿着图中各边访问图中的所有顶点,且每个顶 点仅被遍历一次 “遍历”:对结点进行某种操作的意思 1.广度优先遍历 **例如:**现在要找东西,假设有三个抽屉,东西在哪个抽屉不清楚,现在要将其找到,广度优先遍历的做法是:
先将三个抽屉打开,在最外层找一遍将每个抽屉中红色的盒子打开,再找一遍将红色盒子中绿色盒子打开,再找一遍直到找完所有的盒子 注意:每个盒子只能找一次,不能重复找
思考:如何防止节点被重复遍历?
增加一个数组,用于标记是否入过队列,这样可以防止重复遍历 void BFS(const V& src) { size_t srci = GetVertexIndex(src); queue<int> q; vector<bool> visited(_vertexs.size(), false); // 标记数组 q.push(srci); visited[srci] = true; int levelSize = 1; // 控制每层出的数量 while (!q.empty()) { // 一层一层出 for (size_t i = 0; i < levelSize; i++) { int front = q.front(); q.pop(); cout << front << "
1. 前言 如果你让我给别人推荐一款 Mac 下的终端,那我会毫不犹豫的推荐 iterm2,因为它足够经典,足够好用。
当然优秀的终端有很多,比如:alacritty、kitty 等,大家感兴趣的可以尝试一下。
我们今天主要讲解 iterm2 的安装、配置和美化。
2. 安装 iterm2 brew install --cask iterm2 3. 配置美化 iterm2 Command + 空格输入 iterm,默认长这样。
Command + .打开 iterm2 的设置窗口。
3.1 配置主题 选择 Minimal
3.2 安装字体 安装 Jetbrains Mono Font,参考地址:https://github.com/JetBrains/JetBrainsMono
想要通过 brew 安装字体需要先添加它的专门用于管理字体的软件源 cask-fonts
brew tap homebrew/cask-fonts 还记得我在【Mac 从 0 到 1 保姆级配置教程 01】- 安装无敌的 brew
最后介绍 tap 的作用嘛,这里就用到了,不清楚的同学可以再复习一下。
运行之后发现这个 tap 已经被删除了…
我去它的 GitHub 看了一下这个仓库在一个月前归档了,并且说已经迁移到 cask 默认仓库里了。
所以我们直接 --cask 安装字体即可。
1、微服务架构 微服务架构是一种设计复杂应用程序的方法,它提倡将单一应用程序开发为一组小型、独立的服务,每个服务运行在其自己的进程中,并通过轻量级通信(通常是HTTP协议)进行交互。每个服务都是围绕业务功能构建的,能够独立部署、扩展和维护。
上述说常用的服务间通信的协议是HTTP协议,但是目前很多公司里也会使用Dubbo作为RPC调用框架。
HTTP协议是存在于ISO模型中的应用层,应用层实现具体的应用功能,为应用程序提供服务。
Dubbo则是基于TCP协议的RPC架构,而TCP协议处于ISO模型的传输层,传输层只是建立、管理和维护端到端的连接。
所以在请求的过程中,TCP协议会比HTTP协议封装更少的内容,速度也比HTTP会快一些。
微服务核心特点:
模块化:微服务架构强调高内聚低耦合,每个服务专注于执行单一业务功能,这使得系统更易于理解和维护。独立部署:每个微服务都可以独立于其他服务进行构建、测试、部署和扩展,减少了部署时的相互影响。技术栈灵活:不同的微服务可以根据具体需求选择最适合的技术栈,不必受限于整个系统的统一技术选择。弹性伸缩:微服务架构允许按需扩展特定的服务实例,以应对高负载情况,而无需扩展整个应用程序。故障隔离:如果某个微服务出现故障,不会立即影响整个系统,因为其他服务仍然可以正常运行。持续交付:由于微服务的独立性和自动化测试,团队可以更频繁地进行代码提交和部署,加速产品迭代速度。数据管理:每个微服务通常拥有自己的数据库,遵循“数据所有权”原则,避免了全局数据模式的复杂性。 1.1、Dubbo在微服务架构中的角色 Dubbo在微服务架构中不仅提供了高效的服务间通信机制,还通过其全面的服务治理能力,极大地降低了构建、管理和维护复杂微服务架构的难度
服务治理:Dubbo是一个高性能、轻量级的开源服务框架,它提供了全面的服务治理解决方案,包括服务注册、服务发现、负载均衡、容错、限流、动态配置等功能,帮助构建稳定可靠的微服务架构。RPC通信:Dubbo采用高性能的RPC(Remote Procedure Call)通信机制,允许服务消费者远程调用服务提供者的接口,就像调用本地方法一样简单,极大地简化了分布式系统间的交互。服务注册与发现:Dubbo支持多种注册中心,如Zookeeper、Nacos、Consul等,用于服务的自动注册与发现,使得服务提供者和消费者之间能够动态地找到彼此,而无需硬编码服务地址。智能路由:Dubbo提供了丰富的路由策略,如随机、轮询、最少活跃数、一致性哈希等,可以根据不同的场景和需求,智能地选择服务实例进行调用,提高服务调用效率和系统的整体性能。容错与重试:Dubbo内置了多种容错策略,如失败重试、失败回调、降级、熔断等,能够在服务不可用或网络异常时,提供优雅的降级方案,保证系统的稳定性和用户体验。监控与统计:Dubbo集成了强大的监控统计功能,可以实时监控服务调用的延迟、吞吐量、异常率等关键指标,帮助开发者快速定位和解决问题。灵活的配置管理:Dubbo支持动态配置更新,可以在不重启服务的情况下调整服务参数,提高了运维的灵活性和效率。 1.2、Zookeeper和Nacos作为服务注册与发现中心的作用。 (1)Zookeeper
Zookeeper主要用于协调分布式应用,提供了一套完整的分布式协调服务解决方案。它能够为分布式应用提供命名服务、配置管理、集群管理、分布式锁、队列管理等服务。
在微服务架构中,Zookeeper可以作为一个服务注册中心,各个微服务启动后会向Zookeeper注册自己的信息(如IP地址、端口号等),而其他需要调用这些服务的应用则可以从Zookeeper上查询到服务的信息,实现服务的自动发现。
Zookeeper的核心是其数据模型和Watcher机制,通过维护一个层次化的命名空间来存储数据,并且提供了实时的数据变更通知机制。但是,Zookeeper的性能并不适合高并发场景,且其API相对复杂,需要一定的学习成本。
(2)Nacos
Nacos是阿里巴巴开源的一款易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它结合了服务发现与配置管理的功能,旨在简化微服务和DevOps的运维工作。
Nacos提供了一个强大的服务注册与发现功能,微服务可以在启动时向Nacos注册,同时Nacos也支持健康检查,确保只返回可用的服务实例。服务消费者可以通过Nacos发现并调用服务。
Nacos具有高可用性、高性能和易用性,支持动态配置更新,无需重启服务即可生效。此外,Nacos还提供了丰富的可视化界面,方便用户管理和监控服务。
2、环境准备 1、IDEA编码工具。
2、Maven依赖管理工具
2.1、安装和配置Zookeeper和Nacos。 2.1.1、Zookeeper (1)下载
Zookeeper是Apache旗下的产品,下载地址:Apache Zookeeper
(2)解压并启动
将Zookeeper压缩包下载好后进行解压。
解压好后还不能直接启动,还需要修改配置文件,一个很简单的修改操作。将conf目录下的zoo_sample.cfg文件改为zoo.cfg文件即可。
修改前:
修改后:
进入bin目录,在windows系统中直接双击zkServer.cmd文件启动Zookeeper,而在Linux系统下则需要运行zkServer.sh文件。
2.1.2、Nacos (1)下载
Nacos 是阿里的产品,现在是 SpringCloud 中的一个组件。它的功能要比 Eureka、Zookeeper 更加丰富,在国内比较受欢迎。
下载地址:Nacos GitHub下载地址
(2)下载后解压
(3)修改数据库配置
进入conf目录下,打开application.properties文件,需要在这里面修改数据库的配置。
在修改数据库配置之前需要走一个必不可少的流程,就是将conf目录下的mysql-schema.sql在指定的数据库中执行一次,让数据库中有所需要的表。
数据库的配置信息从33行开始。
#*************** Config Module Related Configurations ***************# ### If use MySQL as datasource: ### Deprecated configuration property, it is recommended to use `spring.
Java类库是Java的应用程序接口(API),通常以包的形式组织类库
1、java.lang:默认导入的包,提供程序设计的常用基础类和接口;
2、java.util:工具类库,提供包含集合框架、集合类、日期时间等工具类;
3、java.io:Java的标准输入输出流;
4、java.applet:实现Java Applet 小程序的类库;
5、java.net:提供实现网络应用与开发的类库;
6、java.sql:提供访问并处理存储在数据源(通常是关系型数据)中的数据;
7、java.awt和java.swing:提供用户构建图形用户界面的类库;
8、java.awt.event:图形界面中用户交互控制和事件相应类库;
字符串String 使用构造方法创建String类的对象 1、String s=new String();//生成一个空字符串
2、String s=new String("Hello Wrold");//生成一个有参数的新字符串
3、char a[]={'a','b','c'}; String s=new String(a);//所得s=abc
4、char a[]={'a','b','c','d','e','f'} String s=new String(a,2,3);//s=cde //该处方法意思为,读取a的数组从下标为2开始读取,往后读三位
5、byte[] a={54,55,56}; String s=new String(a);//s='678'因为'6'的unicode码为54
6、byte[] a={54,55,56}; String s=new String(a,1,2);//s='78' //从下标1开始读取,往后读两位
String创建字符串对象区别:通过双引号自动创建的字符串对象存在于常量池,
通过构造方法创建的1字符串对象存在于堆内存;
String类中的成员方法 1、int n1="Hello World".length(); //获取字符串长度
2、String first=new String("ABC"); sec=new String("abc") boolean bol=first.equals(sec);//此时为false
3、String first=new String("ABC"); sec=new String("abc") boolean bol=first.equalsIgnoreCase(sec);//此时为true
4、String first="computer"; first.startWith("com");//返回true,是否以com为前缀 5、String first="computer"; first.endWith("ter");//返回true,是否以ter为后缀
欢迎来到我的Blog,点击关注哦💕
前言 二叉树遍历是指按照一定的顺序访问二叉树中的每个节点,使得每个节点恰好被访问一次。遍历是二叉树上最重要的运算之一,是二叉树上进行其他运算的基础。
一、二叉树遍历概念 二叉树遍历分类 前序遍历 :根节点–>左子树–>右子树。在前序遍历时,首先访问根节点,然后依次访问左子树和右子树。中序遍历 : 左子树–>根节点–>右子树。在中序遍历时,首先访问左子树,然后访问根节点,最后访问右子树。后序遍历:左子树–>右子树–>根节点。在后序遍历时,首先访问左子树和右子树,然后访问根节点。层序遍历: 由顶层到底层,一层一层遍历。 二叉树其他操作 树节点的个数,树深度,树 k 层的个数,查找节点。
二、二叉树遍历实现 我们以下面为例子:
1 2 3 4 5 6 7 8 9 2_right_NULL 3_left_NULL 2.1 二叉树建立 1.定义一个结构体,分别有左右两个指针。
2.为每一个节点创建孔家。
3.创建二叉树,并如上图连接。
//定义结构体 typedef int BTTypeData; typedef struct BinaryTree { BTTypeData data; struct BinaryTree* left; struct BinaryTree* right; }BinaryTree; //创建空间 BinaryTree* BuyBinaryTree(BTTypeData x) { BinaryTree* node = (BinaryTree*)malloc(sizeof(BinaryTree)); if (node == NULL) { perror("malloc fail"); return NULL; } node->data = x; node->left = NULL; node->right = NULL; return node; } //建树 BinaryTree* CreateBinaryTree() { BinaryTree* node1 = BuyBinaryTree(1); BinaryTree* node2 = BuyBinaryTree(2); BinaryTree* node3 = BuyBinaryTree(3); BinaryTree* node4 = BuyBinaryTree(4); BinaryTree* node5 = BuyBinaryTree(5); BinaryTree* node6 = BuyBinaryTree(6); BinaryTree* node7 = BuyBinaryTree(7); BinaryTree* node8 = BuyBinaryTree(8); BinaryTree* node9 = BuyBinaryTree(9); node1->left = node2; node1->right = node4; node2->left = node3; node4->left = node5; node4->right = node6; node3->right = node7; node6->left = node8; node6->right = node9; return node1; } 2.
码到三十五 : 个人主页 目录 一、引言二、Post_Filter后置过滤器概述三、使用场景四、DSL使用1. 使用DSL构建包含Post_Filter的查询2. Elasticsearch的先聚合再后置过滤 五、优化策略六、结语 一、引言 在Elasticsearch中,过滤文档以满足特定条件是一个常见的需求。传统的过滤器(Filter)在Elasticsearch的早期版本中扮演着重要角色,但在后续的版本中,过滤器的概念逐渐被查询(Query)中的布尔子句(Bool Clause)所取代。
然而,在某些场景下,我们可能需要在查询执行完成后对结果进行额外的过滤,这就是Post_Filter后置过滤器的作用所在。本文将详细介绍Elasticsearch中的Post_Filter后置过滤器技术,包括其工作原理、使用场景、DSL使用示例以及优化策略等内容。
二、Post_Filter后置过滤器概述 Post_Filter后置过滤器是一种在查询执行完成后对结果进行过滤的机制。与传统的过滤器不同,Post_Filter不会对查询的性能产生显著影响,因为它是在查询完成后对结果进行过滤的。这使得Post_Filter在处理大量数据或复杂查询时成为一种高效的选择。
Post_Filter的工作原理是在查询执行完毕后,对返回的文档集进行过滤。这意味着所有与查询匹配的文档都会被检索出来,然后Post_Filter会对这些文档进行额外的过滤操作,以满足特定的条件。这种机制允许我们在不牺牲查询性能的前提下,对结果进行精细化的控制。
三、使用场景 Post_Filter后置过滤器适用于以下场景:
需要对查询结果进行二次过滤 在某些情况下,我们可能需要根据额外的条件对查询结果进行过滤。这些条件可能无法在查询阶段直接指定,或者它们的计算成本较高,不适合在查询阶段执行。这时,我们可以使用Post_Filter对这些条件进行过滤。
需要对聚合结果进行过滤 在Elasticsearch中,聚合操作允许我们对数据进行统计和分析。然而,在某些情况下,我们可能需要对聚合结果进行过滤,以排除不满足特定条件的聚合项。Post_Filter可以在聚合完成后对结果进行过滤,实现这一需求。
需要对高亮结果进行过滤 在全文搜索中,高亮功能允许我们将匹配的关键词以特殊的方式显示出来,以便用户快速定位到相关信息。然而,在某些情况下,我们可能需要对高亮结果进行过滤,以排除不满足特定条件的高亮项。Post_Filter可以在高亮操作完成后对结果进行过滤,实现这一需求。
四、DSL使用 1. 使用DSL构建包含Post_Filter的查询 GET /products/_search { "query": { "bool": { "must": [ { "match": { "description": "smartphone" } } ], "filter": [ { "range": { "price": { "gte": 100, "lte": 500 } } } ] } }, "post_filter": { "term": { "brand.keyword": "Apple" } }, "highlight": { "
jdk-8u411-windows-x64.exe
https://cfdownload.adobe.com/pub/adobe/coldfusion/java/java8/java8u411/jdk/jdk-8u411-windows-x64.exe
jdk-11.0.23_windows-x64_bin.exe
https://cfdownload.adobe.com/pub/adobe/coldfusion/java/java11/java11023/jdk-11.0.23_windows-x64_bin.exe
Others:
https://helpx.adobe.com/coldfusion/kb/coldfusion-downloads.html#downloads3
国内相对低版本的 jdk11 在华为云镜像仓库有提供:
Index of openjdk-local
官网注册即可下载:
Java Downloads | Oracle
参考:git 用户分享开源仓库下载地址
https://gist.github.com/wavezhang/ba8425f24a968ec9b2a8619d7c2d86a6?permalink_comment_id=4633459
目录 1. 捕获过滤器 (Capture Filters)基本捕获过滤器组合捕获过滤器 2. 显示过滤器 (Display Filters)基本显示过滤器复杂显示过滤器协议特定显示过滤器 3. 进阶显示过滤器技巧使用函数和操作符逻辑操作符 4. 常见网络协议过滤表达式示例HTTP 协议HTTPS 协议DNS 协议DHCP 协议ARP 协议ICMP 协议SMTP 协议POP3 协议IMAP 协议 1. 捕获过滤器 (Capture Filters) 捕获过滤器使用 Berkeley Packet Filter (BPF) 语法,主要用于在捕获数据包时进行过滤。以下是一些捕获过滤器的示例:
基本捕获过滤器 捕获所有 TCP 包:tcp 捕获特定 IP 地址的数据包:host 192.168.1.1 捕获特定网络的数据包:net 192.168.1.0/24 捕获特定端口的数据包:port 80 捕获源地址为特定 IP 的数据包:src host 192.168.1.1 捕获目标地址为特定 IP 的数据包:dst host 192.168.1.1 组合捕获过滤器 捕获特定源地址且目标端口为 80 的数据包:src host 192.168.1.1 and port 80 捕获特定源和目标地址的数据包:src host 192.168.1.1 and dst host 192.
useState useState 是 React Hooks API 中的一个函数,它允许你在函数组件中添加局部状态。通过 useState,函数组件可以像类组件一样拥有和管理自己的状态,从而使得函数组件更加动态和可交互。
useState 函数接受一个初始状态作为参数,并返回一个包含两个元素的数组。第一个元素是当前的状态值,第二个元素是一个函数,用于更新这个状态。
import React, { useState } from 'react'; function Example() { // 声明一个新的状态变量, 我们称之为 “count” const [count, setCount] = useState(0); return ( <div> <p>你点击了 {count} 次</p> <button onClick={() => setCount(count + 1)}> 点我 </button> </div> ); } 在上面的例子中,useState(0) 初始化了一个名为 count 的状态变量,并将其初始值设置为 0。setCount 是一个函数,用于更新 count 的值。每当用户点击按钮时,就会调用 setCount(count + 1),从而更新 count 的值。
注意事项 1、状态更新可能是异步的:React 可能会推迟状态的更新以提高性能。因此,不要依赖当前的状态来计算下一个状态。如果你需要基于当前状态来更新状态,可以使用函数形式的更新器:
setCount(prevCount => prevCount + 1); 2、状态更新会触发重新渲染:每当状态值发生变化时,React 都会重新渲染组件。这是 React 保持 UI 与状态同步的方式。
现实生活
和现实爱情一样
只会欺负穷人
coze,俗称扣子,英文含义为亲热的聊天儿,是字节跳动发布的免费AI产品,每个人都可借助它创建自己的AI对话机器人,也叫AI Bot,还具有很强大的插件生态来实现不同类型的对话机器人。
下面就来打造一个属于自己的AI对话机器人。
第一步,注册coze账号
coze分为国内版和国外版。
国内版:www.coze.cn
国际版:www.coze.com
区别是国外版使用的大模型是gpt,效果会更好。还有就是国际版官网是英文的。
为了好理解,这里以国内版为例来操作了。
第二步,创建AI Bot
点击左上角的按钮
点击创建bot
比如这里要创建一个会讲好笑的段子的机器人,取名为笑话大王。
第三步,配置
在编排的右边选择模式和大模型,这里模式可以选择agent,大模型默认选豆包,这是字节推出的大模型。
然后就需要写人设和回复逻辑了。建议按照角色,技能,限制三个方面来写,如果你不想写,也可以先去通义千问,去问问怎么写,然后复制过来。
第四步,添加插件
在右侧第一个就是插件,我们可以为自己的机器人添加插件来增强机器人的能力比如这里可以添加头条新闻,bing搜索。
第五步,知识
增加这部分,就可以支持用户上传文件或者url。
第六步,记忆
记住之前的聊天,可用于后面更好的回答。
第七步,开场白
可以主动介绍机器人的技能。这里设置为:来听一个笑话吧。
第八步,看效果了
往右边滑动,可以看到预览与调试,在这里就可以看到自己打造的AI机器人啦。
如下,输入上班人的笑话
最后一步,发布
点击右上角的发布,我们的AI机器人就可以给其他人用了。
默认是直接发布到coze bot商店。
由于微信的聊天属性太强了,和AI Bot很配,coze也可以发布到公众号,但是需要配置,这里也就趁热打铁,点击配置,根据提示找到自己公众号的AppId。注意区分服务号和订阅号。
扫码成功后,重新进入发布页面,就有了。
一般等几分钟就好了。现在就可以去自己的微信公众号里面,点击发消息,然后输入一句话试一下笑话大王了。
最后
如果你也有兴趣,也可以在coze上打造属于自己的AI产品,快去试试吧。