实验二、网络属性设置《计算机网络》

精神状态 be like:边写边崩溃,越写越得劲儿。 目录 一、实验目的: 二、实验内容 三、实验步骤: 四、实验小结 一、实验目的: 掌握 IP 地址、子网掩码等网络属性的设置。 二、实验内容 预备知识: 1、要使用网络,本机必须从DHCP服务器中自动获取IP地址等属性,或者设置静态(即固定) 的IP地址。如果只是在局域网中使用,原则上可用任意的IP地址,最常用的是 192.168.0.1--192.168.0.254范围内的任意值。欲为网卡绑定静态IP地址,按如下操作: 1、 打开网络属性设置窗口:即TCP/IP属性设置窗口。选―控制面板→网络和拨号连接→本地 连接→属性→Internet协议(TCP/IP)→属性,如下图所示,根据当前网络状况,设置相应的 网络属性。 2、IP地址又称逻辑地址和软件地址,标识你电脑所属组织或所在地理位置,如上一步骤所 示,可以设置192.68.0.1至192.168.0.254中的任意地址;子网掩码用于标识你所在网络(子 网)的大小,192.168.0。*网段的默认子网掩码为255.255.255.0;默认网关的地址为你电 4脑所在网络中最近的路由器的IP地址,该路由器可以帮助完成不同网段数据的转发;首选DNS 服务器是主用DNS服务器,完成域名至IP地址转换的工作。 三、实验步骤: 1.打开网络属性设置窗口:即TCP/IP属性设置窗口。 选―控制面板→网络和拨号连接→本地 连接→属性→Internet协议(TCP/IP)→属性,如下图所示,根据当前网络状况,设置相应的 网络属性。 2.获取ip地址: 第一步:输入win+r进入命令提示符 第二步:输入ipconfig 四、实验小结 ipconfig命令作用是: 1、输入ipconfig命令,可以查看电脑的ip地址; 2、输入ipconfig或all命令,可以查看电脑的ip地址,mac地址,其他网卡信息; 3、输入ipconfig或release命令,可以释放电脑的ip地址。 4、Ipconfig命令原理是: ipconfig 属于 DOS 命令之一,是调试计算机网络的常用命令。其作用在于: 不添加参数时 ipconfig 命令可查看电脑 ip 参数配置信息,如 ip 地址、默认网关、 子网掩码、DNS(域名服务)、WINS 服务器等地址。添加了不同参数的 ipconfig命令可以执行更多网络调试操作。

数据仓库与数据挖掘总复习练习2-3(实验六 2024.6.5)

一、练习2 is_unique是否值唯一 range(范围,步长) head()、tail()默认显示5条 缺失值情况 计算(最少多少元素求和、元素相乘) pct_change() latax(工具:专用于写公式) 注:画图需要安装其他包Matplotlib sample()随机采样 nunique()不重复元素 数据对齐(数据运算) (index中值最好不要重复,避免计算错误) panda认为nan值不相等 保存Series值到list cities中index:数值,data:地名 in关键字 二、练习3 注:pandas版本变化需要注意 指定index列 一列作为index,一列作为数据 默认为dataframe(多行多列)形式 dataframe变为series对象 读取谷歌股票数据,把date列日期处理 读取内战数据,使用哪两列构造series对象 排序(此时有3个series对象:pokeman,google,battles) sort_values() 缺失值操作 计算占比value_counts() 按人为区间统计

大数据处理(选修)实验课:实验二 Spark Streaming实验

1. 创建code源文件的文件夹 终端中输入如下命令 cd /usr/local/spark/mycode mkdir streaming cd streaming mkdir -p src/main/scala cd src/main/scala 注意:这一步需要提前创建mycode文件夹,否则如果直接全文复制之后回车会导致后面的指令全部无效! 2. 编写WordCount的scala代码 用vim打开一个scala文件: vim TestStructuredStreaming.scala 在该文件输入以下内容: import org.apache.spark.sql.functions._ import org.apache.spark.sql.SparkSession object WordCountStructuredStreaming{ def main(args: Array[String]){ val spark = SparkSession.builder.appName("StructuredNetworkWordCount"). getOrCreate() import spark.implicits._ val lines = spark.readStream.format("socket").option("host","localhost"). option("port",9999).load() val words = lines.as[String].flatMap(_.split(" ")) val wordCounts = words.groupBy("value").count() val query = wordCounts.writeStream.outputMode("complete"). format("console").start() query.awaitTermination() } } 以上是WordCount的scala代码,阅读代码可以知道这里用的端口是9999,记住它,后面要用。 3. 安装sbt sbt是用来打包scala的工具。由于前文并没有讲解sbt 的用法(甚至没教怎么安装orz,感觉是任务书被阉割导致的,实验一的spark安装中包含了这一部分,但很容易被忽略),先补充一下sbt的配置步骤(参考了大数据原理与应用 第十六章 Spark 学习指南 (xmu.edu.cn)) 官网下载地址:Download | sbt (scala-sbt.

Java 还能不能继续搞了?

金三银四招聘季已落幕,虽说行情不是很乐观,但真正的强者从不抱怨。 在此期间,我收到众多小伙伴的宝贵反馈,整理出132道面试题,从基础到高级,有八股文,也有对某个知识点的深度解析。包括以下几部分: Java:基础、线程、并发编程、 网络编程、JVM。框架:Spring Boot、Spring Cloud。数据库:Redis、MySQL。架构:系统设计、技术选型、分布式理论等。 准备好迎接金九银十吧!!! Java 基础 以下面试题可以移步至: 《Java基础面试题》 Java 创建对象有几种方式?有了数组为什么还要ArrayList?重载和重写的区别什么是内部类?应用在什么场景?介绍下Java中的四种引用static都有哪些用法?HashCode在集合中的作用Hash冲突怎么处理?深拷贝和浅拷贝的区别是什么?你知道什么是fail-fast吗?介绍下你对红黑树的理解异常处理影响性能吗?介绍下try-with-resource语法你知道哪些数据结构?AVL树是怎么保持平衡性的?为什么红黑树比AVL树效率高? Java 线程 以下面试题可以移步至: 《Java线程面试题》 《Java线程安全面试题》 创建线程有几种方法?介绍下线程的生命周期?如何停止正在运行的线程?什么是线程安全?线程安全需要保证几个基本特性?为什么wait和notify方法要在同步块中调用?Synchronized和Lock的区别?常用的线程池有哪些?为什么需要线程池?简述一下线程池的工作原理线程池的拒绝策略有哪些?说说ThreadLocal的原理?如何保证线程安全?为什么需要确保共享变量的可见性?volatile是如何保证可见性、有序性?谈一下 CAS 机制实现原理?CAS 机制存在什么问题?简述一下synchronized工作原理?简述一下synchronized锁升级的过程?什么是锁粗化和锁消除?为什么 HashMap 是线程不安全的? Java 并发编程 以下面试题可以移步至: 《Java并发编程面试题》 AQS是什么?AQS唤醒节点时,为什么是从后往前找?AQS为什么用双向链表?AQS为什么要有一个虚拟的head节点?ReentrantLock 的底层实现ReentrantLock的公平锁和非公平锁的区别ReentrantReadWriteLock如何实现读写锁?CountDownLatch,Semaphore有什么用?你知道哪些常用的阻塞队列?阻塞队列中的虚假唤醒是什么? Java 网络编程 什么是网络编程?什么是BIO、NIO、IO多路复用?Java NIO是New IO还是Non-blocking IO?聊一下你对Netty的认识?Netty和Java NIO是什么关系?Netty为什么那么高效? Spring Boot 以下面试题可以移步至: 《Spring Boot面试题 》 什么是 Spring Boot?Spring Boot 有哪些核心注解?Spring Boot 自动装配是什么?Spring Boot 自动装配原理?Spring Boot 配置文件的加载顺序bootstrap.properties 和 application.properties 有何区别 ?Spring Boot Actuator是什么?Spring Boot项目如何热部署?Spring Boot 中的 starter 是什么 ?Spring Boot 有哪些 starter ? Spring Cloud 以下面试题可以移步至:

OpenAI 发布的 GPT-4o是什么,有什么功能?

Openai 刚刚在太平洋时间 5 月 13 日星期一上午 10 点在发布了 GPT-4o,这是一种新的人工智能模式,集合了文本、图片、视频、语音的全能模型。 能实时响应用户的需求,并通过语音来实时回答你,你可以随时打断它。 GPT-4o具有视觉能力,能识别物体并根据视觉做出快速的响应和回答,具有非常强的逻辑推理能力。 它还能够从用户的声音中检测他们的情绪。 它的速度比 GPT4-turbo 快 2 倍,价格便宜 50%! GPT-4o是什么? GPT-4o(“o”代表“omni”)是迈向更自然的人机交互的一步——它接受文本、音频和图像的任意组合作为输入,并生成文本、音频和图像的任意组合输出。它可以在短至 232 毫秒的时间内响应音频输入,平均为 320 毫秒,这与人类在对话中的响应时间相似。它在英语文本和代码上的性能与 GPT-4 Turbo 的性能相匹配,在非英语文本上的性能显着提高,同时 API 的速度也更快,成本降低了 50%。与现有模型相比,GPT-4o 在视觉和音频理解方面尤其出色。 在 GPT-4o 之前,您可以使用语音模式与 ChatGPT 对话,平均延迟为 2.8 秒 (GPT-3.5) 和 5.4 秒 (GPT-4)。为了实现这一目标,语音模式是由三个独立模型组成的管道:一个简单模型将音频转录为文本,GPT-3.5 或 GPT-4 接收文本并输出文本,第三个简单模型将该文本转换回音频。这个过程意味着主要智能来源GPT-4丢失了大量信息——它无法直接观察音调、多个说话者或背景噪音,也无法输出笑声、歌唱或表达情感。 借助 GPT-4o,我们跨文本、视觉和音频端到端地训练了一个新模型,这意味着所有输入和输出都由同一神经网络处理。由于 GPT-4o 是我们第一个结合所有这些模式的模型,因此我们仍然只是浅尝辄止地探索该模型的功能及其局限性。 GPT-4o模型评估 根据传统基准测试,GPT-4o 在文本、推理和编码智能方面实现了 GPT-4 Turbo 级别的性能,同时在多语言、音频和视觉功能上设置了新的高水位线。 GPT-4o语言标记化 有 20 种语言被选为新分词器跨不同语系压缩的代表。 模型安全性和局限性 GPT-4o 通过过滤训练数据和通过训练后细化模型行为等技术,在跨模式设计中内置了安全性。我们还创建了新的安全系统,为语音输出提供防护。 我们根据我们的标准评估了 GPT-4oPreparedness Framework and in line with our voluntary commitments准备框架并符合我们的自愿承诺。我们对网络安全、CBRN、说服力和模型自主性的评估表明,GPT-4o 在这些类别中的任何类别中的得分都不高于中等风险。该评估涉及在整个模型训练过程中运行一套自动化和人工评估。我们使用自定义微调和提示测试了模型的安全缓解前和安全缓解后版本,以更好地激发模型功能。

Objective-C之通过协议提供匿名对象

概述 通过协议提供匿名对象的设计模式,遵循了面向对象设计的多项重要原则: 接口隔离原则:通过定义细粒度的协议来避免实现庞大的接口。依赖倒置原则:高层模块依赖于抽象协议,而不是具体实现。里氏替换原则:不同的类实现相同协议,可以互换使用。单一职责原则:将不同职责分离到不同的协议中,使得类的职责单一且明确。 这种设计方式使得代码更加灵活、可维护、可扩展,并且易于测试和复用。 在 Objective-C 中,通过协议提供匿名对象是一种设计模式,通常用于实现接口(协议)的一致性和灵活性。这个设计模式有助于实现松耦合、提高可扩展性和维护性。我们可以从以下几个设计原则来分析和理解这种做法: 1. 接口隔离原则(Interface Segregation Principle) 接口隔离原则是指应将庞大的接口拆分成更小、更具体的接口,使得客户端只需依赖于它们实际需要的接口。在 Objective-C 中,通过协议来定义接口,可以确保类只实现其需要的协议方法。 示例 @protocol Downloadable <NSObject> - (void)download; @end @protocol Uploadable <NSObject> - (void)upload; @end @interface MyClass : NSObject <Downloadable, Uploadable> @end @implementation MyClass - (void)download { // 实现下载逻辑 } - (void)upload { // 实现上传逻辑 } @end 通过这种方式,MyClass 可以选择性地实现 Downloadable 和 Uploadable 协议,而不需要实现庞大的单一接口。 2. 依赖倒置原则(Dependency Inversion Principle) 依赖倒置原则强调高层模块不应该依赖于低层模块,而应该依赖于抽象。在 Objective-C 中,通过协议来定义接口,使得高层模块可以依赖于这些协议,而不是具体的实现类。 示例 @protocol DataProcessor <NSObject> - (void)processData:(NSData *)data; @end @interface DataHandler : NSObject @property (nonatomic, weak) id<DataProcessor> processor; - (void)handleData:(NSData *)data; @end @implementation DataHandler - (void)handleData:(NSData *)data { [self.

推荐开源阅读器:FBReader for Android —— 现代化电子书阅读的首选

推荐开源阅读器:FBReader for Android —— 现代化电子书阅读的首选 1、项目介绍 FBReader 是一款专为 Android 设备打造的开源电子书阅读器,它拥有简洁易用的界面和强大的书籍管理功能。该项目自 2017 年以来不断更新,提供了对包括 Nook Glowlight Plus 在内的多种设备的支持,确保了在各种平台上的顺畅体验。FBReader 不仅是一款软件,更是热爱阅读的人们享受电子书世界的理想伙伴。 2、项目技术分析 FBReader 基于 GPL v2 或更高版本授权,采用现代化的 Gradle 构建系统,使得开发者能够轻松地构建和定制。其独特之处在于,对于 Android 2.x 的设备,它采用了 Web 浏览器进行用户认证,以应对 Google 对 OAuth 进行的安全升级。这一设计展示了项目团队对用户体验与安全性的重视,同时也保证了老用户的使用不受影响。 3、项目及技术应用场景 FBReader 可广泛应用于日常的电子书阅读场景,无论你是热衷于 Kindle、Nook 还是其他 Android 设备的用户,都能享受到流畅的阅读体验。它特别适合那些喜欢在线阅读、订阅图书网络服务的读者,尤其是 FBReader Book Network 的用户,可以方便地通过内置浏览器进行身份验证。此外,对于开发人员来说,FBReader 提供了一个学习如何构建高效阅读应用的优秀案例。 4、项目特点 兼容性广:支持多种 Android 设备,包括较旧的版本。安全性高:利用 Web 浏览器进行 OAuth 认证,遵循最新的安全标准。持续更新:开发者团队积极维护,定期发布更新,改进性能和修复问题。开放源码:遵循 GPL 协议,允许自由使用、修改和分发,鼓励社区参与开发。 综上所述,FBReader for Android 是一个强大且灵活的电子书阅读工具,无论是普通用户还是开发者,都能从中受益。如果你正在寻找一款可信赖的阅读应用,FBReader 绝对值得你尝试。立即下载,开启你的无界阅读之旅吧!

禁用layui树形表格的多选框checkbox

1. 背景 在使用树形表格渲染数据时,需要对数据进行批量操作。相对于选中数据后,再做错误提示。直接把数据的多选框禁用掉更加直观。 2. 实现 DisabledTableCheckBox: () => { // 获取所有行 var tableElem = $(".layui-table-fixed-l"); var rows = tableElem.find('tr'); for (var i = 1; i < rows.length; i++) { var row = rows[i]; // 检查行是否包含非根节点的标志(例如,parentId不为空) if (row.getAttribute('data-level') == 0) { // 找到行内的checkbox var checkbox = row.querySelector('input[type="checkbox"]'); // 禁用checkbox checkbox.setAttribute("disabled", true); row.setAttribute("title", "根节点不能审核!"); // 可以添加类来改变外观,表明它被禁用了 checkbox.classList.add('layui-disabled'); } } }// 渲染表格 调用点 tableRender: function () { var self = this; treeTable.render({ elem: "

设计模式-单例模式(创建型)

创建型-单例模式 了解单例 单例模式是一种创建型设计模式,它提供了一种创建对象的最佳方式;它必须保证: 单例类只能有一个实例化对象;单例类必须创建自己的唯一实例;单例类必须给其他对象提供实例; 另外: 它的目的是:确保一个类只用一个实例,并提供一种全局访问入口来访问该实例设计思想:在获取实例的时候判断实例是否存在,如果存在,则直接返回,如果不存在则创建实例;关键代码:构造方法私有化; 角色 单例类:包含单例实例的类静态成员变量:用于存储单例的静态成员变量,final修饰防止被继承获取实例方法:静态方法,用于获取单例实例私有构造方法:防止外部直接实例化类线程安全处理:确保多线程环境下单例创建的安全性 实现方式 饿汉式单例 特点:类一加载就实例化单例对象 public class Mgr01 { //静态成员变量存储单例,final修饰防止被继承 private final static Mgr01 INSTANCE = new Mgr01(); //构造方法私有化,防止外部直接实例化 private Mgr01() { } //静态方法,用于获取单例 public static Mgr01 getInstance(){ return INSTANCE; } } 另一种写法,在静态代码块中实例化对象 public class Mgr02 { private final static Mgr02 INSTANCE ; static { INSTANCE = new Mgr02(); } public static Mgr02 getMgr02() { return INSTANCE; } } 懒汉式单例 特点: 使用单例时才实例化对象 线程不安全写法:

JSQLParser用于解析SQL语句并创建抽象语法树(AST)

JSQLParser简介 JSQLParser是一个Java库,用于解析SQL语句并创建抽象语法树(AST)。该库非常强大,可以解析大多数标准SQL语法,并支持许多数据库的专用语法。 主要特点 语法支持广泛:支持大多数SQL语法,包括SELECT、INSERT、UPDATE、DELETE、CREATE TABLE、ALTER TABLE等。数据库独立:JSQLParser可以解析常见数据库(如MySQL、PostgreSQL、Oracle等)的SQL语法。AST生成:解析SQL并生成相应的抽象语法树(AST),供后续操作使用。 核心功能 解析SQL JSQLParser的主要功能是将SQL字符串解析为语法树。可以通过以下方式实现: import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.Statement; public class JSQLParserExample { public static void main(String[] args) { String sql = "SELECT * FROM users WHERE id = 1"; try { Statement statement = CCJSqlParserUtil.parse(sql); System.out.println(statement); } catch (Exception e) { e.printStackTrace(); } } } 解析后的操作 解析后的语法树可以进行各种操作,例如读取表名、列名、条件等。在解析SQL之后,可以进一步操作生成的语法树: import net.sf.jsqlparser.parser.CCJSqlParserUtil; import net.sf.jsqlparser.statement.select.Select; import net.sf.jsqlparser.statement.select.PlainSelect; public class JSQLParserExample { public static void main(String[] args) { String sql = "

【数据结构】穿梭在二叉树的时间隧道:顺序存储的实现

专栏引入 哈喽大家好,我是野生的编程萌新,首先感谢大家的观看。数据结构的学习者大多有这样的想法:数据结构很重要,一定要学好,但数据结构比较抽象,有些算法理解起来很困难,学的很累。我想让大家知道的是:数据结构非常有趣,很多算法是智慧的结晶,我希望大家在学习数据结构的过程是一种愉悦的心情感受。因此我开创了《数据结构》专栏,在这里我将把数据结构内容以有趣易懂的方式展现给大家。 1.二叉树的顺序存储结构 之前我们谈过了树的存储结构,并且谈到了顺序存储结构对树这种一对多的关系结构实现起来还是比较困难的。但二叉树是一种特殊的树,由于二叉树的特殊性,使得它可以使用顺序存储结构来实现,二叉树的顺序存储结构就是使用一维数组存储二叉树中的节点,并且节点的存储位置,也就是数组的下标要能体现出来节点之间的逻辑关系,比如:双亲和孩子的关系、左孩子右兄弟的关系等。先来看看完全二叉树的顺序存储,就用下面这棵二叉树为例: 将这棵二叉树存入数组中,相应的下标对应其同样的位置,很多数据结构相关书籍上下标都是将0空置,从1开始存储,其实下标0的位置是否存放数据对堆的实现的难度没有影响,为了节省空间我对下标为0的位置进行了存储,如下图: 这下我们可以看出来完全二叉树的优越性了吧,由于它严格的定义,所以用顺序结构也可以表现出二叉树的结构来,当然对于一般的二叉树,尽管层序编号不能反映出来逻辑关系,但是可以将其按完全二叉树来编号,只不过,把不存在的节点设置为"NULL"而已,就像下面的图中,虚线部分表示不存在: 我们再考虑一种极端的情况:一颗深度为h的右斜树。它只有h个节点,却要分配个存储单元空间,这显然是对存储空间的浪费,如下图所示: 所以,二叉树的顺序存储结构一般只适用于完全二叉树。上一篇中我们提到了堆是一个特殊的完全二叉树,所以这篇我们就以堆为例子来实现二叉树的顺序存储。 2.堆 2.1堆的概念 堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子节点的值,称为大顶堆;或者每个结点的值都小于等于其左右孩子结点的值,称为小顶堆。如下图所示: 从堆的定义可以知道:根节点一定是堆中所有结点的最大(小)值 。在上一篇堆二叉树的性质介绍时,有一个性质还没和大家介绍,因为这个性质就仿佛是为堆量身定制的,所以我计划在介绍堆时再介绍它: 如果一棵有n个节点的完全二叉树(其深度为)的节点按层序编号(从第一层到第层,每层从左到右),对任一节点i(1≤i≤n)有: 如果i=1,则节点i是二叉树的根,无双亲;如果i>1,则双亲是节点。如果2i>n,则节点i没有左孩子(节点i为叶子节点),否则其左孩子是节点2i。如果2i+1>n,则节点i没有右孩子;否则其右孩子是节点2i+1。 在这个性质第二、三条,也就是说明下标i与2i和2i+1的双亲子女的关系:双亲结点=(子节点-1)/2。 2.2堆的实现 我们先来定义一下堆的结构: typedef int HPDataType; typedef struct Heap { HPDataType* a; int size; int capacity; }HP; 2.2.1堆的创建和销毁 堆的创建我们使用顺序存储来实现,所以它的创建和销毁的实现代码和顺序表的实现的相同。首先是堆的创建函数: void HeapInit(HP* php) { assert(php); php->a = NULL; php->size = 0; php->capacity = 0; } 接着是堆的销毁函数: void HeapDestroy(HP* php) { assert(php); free(php->a); php->a = NULL; php->size = php->capacity = 0; } 2.2.2堆的向上调整 一说到调整我们肯定会对两个数据进行交换,我们先来写一个交换函数: void Swap(HPDataType* p1, HPDataType* p2) { HPDataType tmp = *p1; *p1 = *p2; *p2 = tmp; } 堆的向上调整是将一个元素插入到小堆时,调整堆的结构,使其满足小堆的性质过程。实现堆的向上调整的要先将元素插入到数组的最后一个位置(这一步我们在堆的插入操作中实现)。这时候我们就要比较插入元素和其双亲结点的大小关系,然后做出调整。这里我们可以用循环实现,用循环来实现比用递归实现的好处有:

GaussDB如何创建修改数据库和数据表

目录 一、背景 二、创建数据库和数据表 1. 创建数据库 2.创建数据表 三、修改表结构 1. 添加列 2. 修改列 3. 删除列 四、添加约束 1. 添加主键约束 2. 添加外键约束 3.添加唯一性约束 五、示例代码 -- 创建数据库 -- 使用新创建的数据库 -- 创建 department 表 -- 创建 employee 表 -- 修改表结构:添加列 -- 修改表结构:修改列类型 -- 删除列 ​编辑 六、 总结 一、背景 GaussDB 是一款由华为开发的企业级分布式数据库,具有高性能、高可用、高可靠性等特点,广泛应用于各种业务场景。本指南将介绍如何在 GaussDB 中创建数据库和数据表,修改表结构,并添加约束。 二、创建数据库和数据表 1. 创建数据库 在 GaussDB 中创建数据库可以使用 `CREATE DATABASE` 语句。以下是一个创建名为 `example_db` 的数据库的示例: CREATE DATABASE example_db; 2.创建数据表 在创建数据库之后,可以使用 `CREATE TABLE` 语句来创建数据表。以下是一个创建名为 `employee` 的数据表的示例,该表包含员工的基本信息: CREATE TABLE employee ( emp_id SERIAL PRIMARY KEY, first_name VARCHAR(50), last_name VARCHAR(50), birth_date DATE, hire_date DATE, salary NUMERIC(10, 2) ); 三、修改表结构 在实际使用中,可能需要对现有的数据表进行结构上的修改。可以使用 `ALTER TABLE` 语句来添加、修改或删除表中的列。

前端js 元素拖拽案例

js原生元素拖拽案例 下面是一个简单的使用原生 JavaScript 实现元素拖拽的代码示例: <!DOCTYPE html> <html> <head> <style> .draggable { width: 100px; height: 100px; background-color: red; position: absolute; cursor: move; } </style> </head> <body> <div class="draggable"></div> <script> window.onload = function() { var draggable = document.querySelector('.draggable'); var isDragging = false; var offsetX = 0; var offsetY = 0; draggable.addEventListener('mousedown', function(event) { isDragging = true; offsetX = event.clientX - draggable.offsetLeft; offsetY = event.clientY - draggable.offsetTop; }); document.addEventListener('mousemove', function(event) { if (isDragging) { draggable.

github copilot vs 通义灵码 vs 腾讯云 AI 代码助手

​ 大家好,我是阿星,目前是一名快工作三年的前端工程师。不知道大家现在日常开发中,代码是都自己写,还是不断 tab 呢?是的,自从我使用了代码辅助工具后,50%的代码都是 AI 来帮我编写。我负责审核和校验。不知道大家使用过哪些代码辅助工具,但是我使用过了很多了,从最初的 github copilot 到目前使用的 通义千问。再到今天体验的腾讯云 AI 代码助手。下面就让我带你了解一下这三个代码辅助工具,如果你还没有使用过类似的工具,看完这篇文章,你应该会知道你想要哪一个: github copilot github copilot 是 github(也就是微软)发布的编程助手,官方称:“世界上采用最广泛的人工智能开发工具”。但是我想加一句:每月 10 刀(也就是 70 多元)。好用是真的很好用,上下文理解的很清楚,总是能给出我想要写的代码。而且我最后一次使用的时候它还支持了@workspace ,也就是将整个工作区(项目所有代码)作为预设,也就是它会在本地把所有代码都读一遍,然后给你回复。但是经过测试,效果不是很好,因为很慢,而且有时候回复的也不对,关于github copilot 更多信息,参考官方和我之前的文章: https://github.com/features/copilot https://mp.weixin.qq.com/s/lTx0oftKdFSHgKiPMQTkug, 总结一下:github copilot 是目前我心目中最好的编程助手,但是它有两大缺点, 需要花钱,而且很贵,如果你是给开源项目的贡献者,应该可以免费获取 集成到 VSCode ,需要本地开启🪜,要不然有时候会回复失败。。 通义千问 这个是我目前每天都在使用的编程工具,官方称:“你的智能编码助手”。下面介绍一下我日常如何使用它吧! 下载 进入官网:https://tongyi.aliyun.com/lingma/,点击个人免费使用,然后,点击立即安装,如果你使用 IEDA 家族的,可以参考官方按顺序操作就好 image-20240601185553210 我使用 VSCode,下载好了,可以看到,然后我们需要登录一下 image-20240601185820704 我们可以看到左侧多了一个图标,我们点击它: image-20240601190243324 可以看到一个对话框内嵌到了编辑区, 这里我们可以通过右上角来修改一些通义灵码的配置,新建对话,查看对话历史,反馈问题和查看使用手册 我们可以通过下面的对话框通过输入“/”来做一些预设的事情,也可以直接发消息,进行提问,例如:“给我生成一个判断字符串是否是 URL 的 JavaScript 工具方法”。它就会帮我们生成 image-20240601191428070 这里它贴心的给我们了最常用的操作:插入到现有的代码文件中,复制,和新建文件存储这段代码。👍 image-20240601191811791 这里我们写好了一个 copyToClipboard 代码,但是它还没有注释,我们发现方法名上有一个通义的图标,我们点击它就可以看到弹窗,我们可以直接去生成注释 当然,日常我们最常使用的还是它给我们进行代码提示: image-20240601192148037 这里我们可以看到灰色部分就是 通义灵码 帮我们生成的,代码好像没有问题,就只需要引入一下 对应的 hooks 就好了,真的好用 我们还可以写一段逻辑,然后让 通义灵码来帮我们生成代码

AI 挑战周杰伦?Suno 全新功能面世,即兴哼几句就能创作成歌,还能模仿声音!...

作者 | 王启隆 出品丨AI 科技大本营(ID:rgznai100) 2016 年,周杰伦根据女儿 Hathaway 在玩具钢琴上随意弹出的几个音符,激发出创作的灵感,谱写了一首温馨而深情的歌曲——《前世情人》。8 年过去,音乐创作逐步进入了 AI 时代,先前爆火出圈的音乐创作 AI 平台「Suno」在近日预热,未来将发布一项新功能:Sound-to-Song。意思是:用任何声音创作新歌曲(make a new song from any sound)。 即使你不像周杰伦一样拥有“绝对音感”,也不懂什么乐理与和弦,只需要哼唱一小段,Suno AI 就可以在你哼唱的基础上创作出完整的歌曲。下面便是 Suno 日前发布的第一波预热演示视频:《用喷壶演奏“迷幻摇滚”》。 某种意义上,这和 ChatGPT 推出的“语音输入”交互方式有异曲同工之妙,声音识别和语音识别如今已是各大 AI 产品的必备技术,比如说,我们基本可以在国产 AI App 使用聊天框旁边的说话功能: 但在音乐的世界,我们不需要像制作人一样苦口婆心地用对话的交互方式来教导 AI 怎么作曲,而是采用更简单的交互:直接唱出来。 这种创新的作曲方式将使用户能够把“声音采样”与“文字提示”结合起来,创作出独一无二的音乐作品。以前使用 Suno 作曲,可能还需要构思一下怎么写 Prompt 才能让 AI 明白你脑内的灵感;但现在,任何日常的声音,如 Suno 官方演示中喷壶敲击金属管的声音,都能转换成迷人的迷幻摇滚乐曲。 除了“喷壶摇滚”以外,Suno 还派出自家的工程师 Anessa 亲自演奏钢琴,并让 Suno AI 转化为完整的一首歌: Suno 不仅将 Anessa 弹的这段钢琴准确无误地变成了手风琴演奏,还进行了“续写”。这意味着 Suno 在捕捉旋律的同时,它或许还能解析出潜在的和声结构,识别出和弦进行,并基于这些和声关系生成新的和声进展。 在下面这段由 Suno 产品经理 Rebecca 进行的官方演示中,我们可以看到类似的情况: 发现问题了吗?没错,Suno 现在不止能识别和弦,还能识别演唱者的音色! 如今,AI 克隆声音已经不再是什么新鲜事,我们经常可以在各大视频网站看到有人利用各种游戏动漫中的人物声音训练 AI 翻唱歌曲,但 Suno 所做的不仅是分析演唱者的独特音色特征以及演唱习惯,它还能使用合成的个性化音色,将新创作的旋律以接近原演唱者的声音表现出来,从而实现不仅旋律上的延续,还有音色上的连贯性和一致性。

03--nginx架构实战

前言:这应该是nginx梳理的最后一章,写一些关于网站架构和网站上线的知识内容,主要是感觉到运维并不是单一方向的行业,这一章概念会有一些广泛,但是非常重要,都是这几年工作中遇到的情况,整理一下相关知识,遇到时可以直接按照目录寻找解决方案。 1、动态网站简介 当用户访问一个网站时,动态网站会根据用户的请求,实时生成并展示页面内容,而静态网站则是提前生成好的页面内容,直接展示给用户。动态网站更适合需要频繁更新和交互性强的场景(如LOL官网登录),而静态网站则更适合内容稳定的情况 动态网站根据架构不同大致有以下几种 资源文件类型开发语言网站框架index.php 开源的php Windows/Linux+nginx+php+mysql index.py 开源python Windows/Linux+apache+python+mysql index.jsp 商业JAVA windows/Linux+tomcat+JDK+Oracle index.asp 商业c# Windows+iis+asp.net+sqlserver/oracle/mogodb 2、LNMP动态网站部署 2.1、linux部署 设定静态ip为192.168.189.143 修改安全配置,这里实验环境直接关闭防火墙和SELINUX [root@localhost ~]# systemctl stop firewalld.service [root@localhost ~]# systemctl disable firewalld.service Removed "/etc/systemd/system/multi-user.target.wants/firewalld.service". Removed "/etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service". [root@localhost ~]# setenforce 0 [root@localhost ~]# vim /etc/selinux/config [root@localhost ~]# cat /etc/selinux/config SELINUX=disabled 2.2、nginx部署 nginx部署过程第一章所示 2.3、php环境部署 这里使用rpm包部署 [root@localhost ~]# yum install -y php php-mysqlnd gd php-gd 2.3.1、测试LNP环境 启动nginx [root@localhost ~]# systemctl start nginx [root@localhost ~]# systemctl enable nginx Created symlink /etc/systemd/system/multi-user.

《深入浅出存储引擎》不同数据库背后的数据存储方案

在大数据和AI时代,数据库成为各类应用不可或缺的重要组成部分。而数据库中的数据依赖存储引擎进行管理,包括数据的存储、查询、更新和删除等。因此,在设计系统时,选择正确的数据库存储引擎方案变得尤为重要。这篇文章将以关系型、NoSQL和NewSQL数据库,以及OLTP、OLAP和HTAP处理方式为切入点,深入探讨不同类型的数据库背后的存储引擎方案选型取舍。 作者:文小飞 01 关系型数据库&NoSQL数据库&NewSQL数据库 下图展示了关系型数据库、NoSQL数据库、NewSQL数据库的发展过程。 1. 关系型数据库 关系型数据库也称为SQL数据库,最早的数据库发展可以追溯至1970年IBM研发的第一个SQL数据库System R,这也是最早的SQL数据库,再后来1980~1990年这段时间涌现出来了一些SQL数据库产品,例如Oracle、DB2、SQL Server、PostgreSQL、MySQL等。 到2000年左右,关系型数据库越来越丰富,出现了很多迄今一直在发挥重要的组件,例如MySQL、Oracle等。 SQL数据库按照以“行”为单位的二维表格存储数据,这种方式最符合现实世界中的实体,同时通过事务的支持为数据的一致性提供了非常强的保证。因此SQL数据库主要适合的场景是读多写少的场景。 关系型数据库中为了适配不同的应用场景,通常会将存储引擎设计为插件式的接口。然而主流的存储引擎,仍然是读多写少的特点。以MySQL为例,InnoDB存储引擎被广泛运用,它通过B+树来存储索引和数据。B+树这种数据结构,由于其独特的特性使得查询的性能非常高。 B+树存储引擎适用于需要高效的数据查找、范围查询和顺序访问的场景。它在关系型数据库中被广泛应用,如MySQL的InnoDB存储引擎和Oracle的B+树索引。然而,B+树存储引擎对于频繁的数据插入和删除操作可能会有一定的开销,因为这会触发节点的分裂和合并操作。 2. NoSQL数据库 在面对海量数据存储、高并发访问的场景下,关系型数据库的扩展性和性能会受到限制。随着互联网的飞速发展,到2000年左右,存储海量数据、高并发处理读写的需求变得非常明显。这对SQL数据库提出了巨大挑战。为了解决这个问题,出现了支持数据可扩展性、最终一致性的NoSQL数据库。因此,NoSQL数据库可以看作是基于SQL数据库的缺陷而诞生的一种新产品。 NoSQL组件普遍选择牺牲复杂SQL的支持及ACID事务功能,以换取弹性扩展能力和更高的读写性能。这类系统主要存储半结构化或非结构化数据。根据存储的数据种类,NoSQL数据库主要分为基于文档存储的文档数据库(Document-based Database)、基于键-值存储的键值数据库(Key-Value Database)、图数据库(Graph-based Database)、时序数据库(Time Series Datebase)、宽列式存储(Wide Column-based Store)以及多模数据库(Multi-Model Database)。 不同类型的NoSQL数据库特性如下图所示。 NoSQL数据库典型的特点是具备很高的读写性能,但数据一致性保证较弱。绝大多数的NoSQL数据库适合写多读少、写多读多的场景。以列式数据库、时序数据库而言,它们通过LSM的思想,提供了非常高的写入性能。这类系统的存储引擎广泛意义上也称为LSM Tree存储引擎,这些系统单机的存储引擎有RocksDB、LevelDB等。此外再以键值数据库为例,它们绝大部分通过利用哈希表这种数据结构,外加内存介质存储数据。实现非常高的读写性能。Redis就是这类系统的典型代表。 3. NewSQL数据库 虽然NoSQL数据库解决了关系型数据库存储的缺陷,但它也没法完全替代掉关系型数据库。在NoSQL数据库出现后的一段时间内,互联网软件的构建基本上都是结合二者来提供服务。在不同的场景下选择不同的数据库进行存储数据。虽然这样的合作方式很好,但是在这样的模式下,一个用户可能会因为场景的不同而存储多份相同的数据到不同的数据库中,当用户量级和存储数据量很小的情况下没什么问题。一旦量级发生变化就会引发出新的问题。 随着存储数据量的不断增加,造成资源的浪费和成本的上升不容忽略。于是工业界和学术界都在寻找更好的解决方案,直到2010年左右,诞生了NewSQL数据库(也称为分布式数据库)。它的出发点是结合关系型数据库事务一致性,又具备NoSQL数据库的扩展性及访问性能。这无疑给系统的设计及实现带来了更大的挑战,NewSQL数据库不仅要考虑单机环境下高效存储的问题,还需要考虑多机情况下数据复制、一致性、容灾、分布式事务等问题。目前NewSQL数据库典型的代表作有TiDB、OceanBase、CockroachDB等。NewSQL数据库中绝大部分的系统还是采用LSM 树存储引擎,来实现系统高性能的写入。 02 OLTP&OLAP&HTAP对比 在现代数据管理领域,OLTP、OLAP和HTAP是常见的数据库类型,它们各自针对不同的数据处理场景和需求。本文将对这三种数据库进行对比,以帮助读者更好地理解它们的特点和适用性。 1. OLTP数据库 OLTP数据库(联机事务处理)是专门设计用于处理事务性工作负载的数据库系统。它们被广泛应用于业务应用程序,如在线购物、银行交易和订单处理等。OLTP数据库的主要特点是高并发、低延迟和高事务吞吐量。它们通过支持ACID(原子性、一致性、隔离性和持久性)特性来确保数据的一致性和可靠性。OLTP数据库通常采用规范化的数据模型,以支持高效的事务处理和即时的数据更新。 OLTP数据库主要的功能是处理用户在线实时的请求,直接为用户提供服务,因此这类数据库通常对处理请求的时延要求比较高,绝大部分的请求正常情况下会在毫秒级完成。OLTP数据库很多,除了大家最熟悉的关系型数据库(如MySQL、Oracle)外,还有Redis、MongoDB等这些非关系型数据库。绝大部分的OLTP数据库则是采用B树、B+树甚至哈希表来构建存储引擎。 2. OLAP数据库 OLAP数据库(联机分析处理),它们专注于支持决策支持和分析工作负载。OLAP数据库用于处理大量数据的复杂分析查询和报表生成。OLAP系统的关键特点是高度可扩展、支持复杂的分析操作和提供灵活的数据聚合能力。为了实现这些特性,OLAP数据库通常采用了针对分析查询优化的特殊数据结构,如多维数据模型(如星型或雪花模型)和列存储技术。此外,OLAP数据库还提供了灵活的查询语言和数据切片、切块、钻取等功能,以支持交互式的数据分析和探索。 OLAP数据库在功能上侧重于对数据或者任务进行离线处理,它不直接对用户提供服务。OLAP系统对请求的处理通常比OLTP慢得多,一般在秒级、分钟级甚至小时级,通常在数据统计、报表分析、推荐系统数据聚合分析等场景用的比较多。这一类数据库典型的代表有HBase、Teradata、Hive、Presto、Druid、ClickHouse等。互联网企业往往都需要使用OLTP和OLAP。因此为了满足这两类需求,通常需要结合多个系统一起开发使用。这样的做法当然是可行的,而且基本也是采用这种方式进行实现。绝大部分的OLAP数据库是采用LSM树构建存储引擎。 3. HTAP数据库 随着数据处理需求的不断演变,需要存储的数据量爆炸式增长,在这种模式下直接带来的存储成本问题成为新的矛盾点,人们开始探索是否能诞生一种数据库将OLTP和OLAP这两类应用合二为一呢?于是,HTAP(混合事务/分析处理)数据库应运而生。HTAP数据库旨在将OLTP和OLAP的功能集成到同一个数据库系统中,以满足实时分析和事务处理的需求。HTAP数据库通过在同一数据库上同时支持事务处理和分析查询,消除了数据复制和数据移动的需求,提供了更高的数据一致性和实时性。HTAP数据库通常采用了内存计算、分布式架构和智能查询优化等技术,以保证高性能和灵活性。这类数据库既可以处理在线事务处理,又可以处理在线分析处理。可以认为HTAP=OLTP+OLAP。HTAP的主要代表有TiDB、OceanBase、CockroachDB等。 在选择数据库时,需要考虑具体的业务需求和性能要求。如果您需要处理大量的事务性工作负载,如在线交易,那么OLTP数据库是一个理想的选择。如果您的需求是进行复杂的数据分析和报表生成,那么OLAP数据库可能更适合。而如果您需要同时满足实时分析和事务处理的需求,那么HTAP数据库是一个值得考虑的选项。 总而言之,OLTP、OLAP和HTAP数据库各自针对不同的数据处理场景和需求。了解它们的特点和适用性,可以帮助您在选择数据库时做出明智的决策,并确保满足业务的需求和性能要求。 03 总结 如果以组件的类型是关系型数据库还是非关系型数据库,并结合服务的场景是OLTP还是OLAP来对业界各种存储组件进行划分的话,可以得到如下图所示的结果。关系型数据库中既有为OLTP设计的,也有为OLAP设计的,同时还有新兴发展起来兼容二者的HTAP数据库。这些系统都有各自适用的业务场景,它们在存储引擎选型时,往往会根据适用场景来决定。如果是读多写少的场景,通常会选择B+树、哈希表来构建存储引擎。而如果是写多读少的场景,往往会选择LSM树来构建存储引擎。 关于作者:文小飞 (网名:jaydenwen/jaydenwen123),大厂资深研发工程师、公司级讲师。曾就职于腾讯等互联网公司,从事基础架构、后端开发、推荐系统架构等工作,具有丰富的基础架构经验。对技术充满热情,尤其对存储引擎、分布式共识算法等技术有较为深入的理解,曾编写开源书籍“自底向上分析 BoltDB 源码”,并发布“数据存储与检索”等网络课程。业余时间喜欢阅读开源项目源码,学习新技术。 - END - 本文摘编自《深入浅出存储引擎》,经出版方授权发布。 延伸阅读《深入浅出存储引擎》 推荐语:带你吃透存储引擎底层原理与实践技巧,攻克业务难题。通过阅读本书,读者不仅能对存储引擎,尤其是单机的存储引擎有一个整体的框架,而且能对两类存储引擎的实现思路及背后原理有个深刻的掌握,只有深刻理解了存储引擎的背后实现原理,读者不仅可以自己动手开发自己的存储引擎,更可以很快掌握关系型数据库或者NoSql这类组件的核心原理,对未来实际应用与开发提供参考。 购买链接: https://mp.weixin.qq.com/s/VyGBUZSvr1ZcRw4s4imurw

香港 Web3 的分岔路口:to 创新 or to 监管,这并不是一个问题

撰文:Babywhale,Techub News 香港 Web3 的分岔路口:to 创新 or to 监管,这并不是一个问题 刚刚过去的周末,香港虚拟资产交易平台(VATP)牌照相关的问题再一次引发了讨论。 一年多前,香港证监会发布公告称,自 2023 年 6 月 1 日起,在港运营的加密货币交易所有一年的时间向监管机构申请合规运营牌照,若一年之后仍未获批则将不允许在香港境内运营。在之后的一年多的时间里,包括 OKX、Huobi、Matrixport 等 Web3 行业内的机构以及胜利证券等券商均加入了申请的行列。 白驹过隙,转眼之后的今天,一些被认为「成竹在胸」的申请者选择了主动退出,而一些在交易所领域新的玩家却留了下来,质疑与猜测一时甚嚣尘上。虽然香港在对 Web3 的监管上从宣言发表至今一直都保持着全球领先的地位,但在交易所以及此前通过的比特币和以太坊现货 ETF 等实际落地上却总是差强人意。 我们不禁要问:曾被寄予厚望的「Web3 新都」香港,究竟怎么了? 交易所监管的「电车难题」 1967 年,菲利帕·福特率先提出了一个伦理学领域的思想实验,其内容大致是:一个疯子把五个无辜的人绑在电车轨道上。一辆失控的电车朝他们驶来,并且片刻后就要碾压到他们。幸运的是,你可以拉一个拉杆,让电车开到另一条轨道上。然而问题在于,那个疯子在另一个电车轨道上也绑了一个人。考虑以上状况,你是否应拉拉杆? 简单来说,牺牲一人,还是牺牲五人?在笔者看来,当下香港的监管层面临着类似的考验。 上周,吴说区块链独家披露了数家知名交易所主动撤回在港运营合规交易所申请的理由,其主要原因在于香港监管机构要求申请者保证目前正在运营的离岸交易所没有中国用户。显然,这些在明面上说不接受中国用户注册的交易所并没有办法保证这一点。事实上,市场最初流传着「成本过高、竞争激烈、市场体量有限」等解释,但这个漏洞百出的理由很难被所有人接受:投入产出比过低这件事难道在申请之初没有做过调研吗? 事实上,某靠近香港监管层的匿名人士曾向 Techub News 透露,香港监管机构不会让「有原罪」的交易所轻易拿到合规牌照,也就是说香港虽然支持 Web3 发展,但不会去做「洗白」这件事情,这也与吴说所了解到的情况基本吻合。 对证监会而言,现在两难的境地在于:允许所谓「有原罪」的交易所「上岸」,似乎对早期的「韭菜」并不公平;但一刀切似乎又某种程度上阻碍了将行业巨头引入香港的进程。 孰是孰非,孰轻孰重,现实已经告诉了我们监管的决定。 背后的逻辑实际上也不难理解:理论上来说,中国内地不允许出现加密货币交易所,离岸的交易所本不应该向内地用户开放,同时也应该主动进行清退,但如果你无法承诺平台上没有不符合监管规定的用户,你如何保证因为在香港就会合规运营?这不是规定,只是一个最基本的要求。 早期交易所的野蛮生长必然会牺牲掉一部分无辜者的利益,但我们认为,资本的原始积累是血腥的,优胜劣汰、弱肉强食即使在和平安宁的社会之中也是逃脱不掉的自然法则。但客观规律并不能将错误永远掩盖,大如币安也承认自己在早期存在诸多问题,历史的回旋镖永远会在未来的某一刻让你付出代价,只是可大可小。 香港的监管层在这一件事上展现了壮士断腕的决心。如此作为必定会带来一定程度上的损失,毕竟行业头部交易所的号召力有目共睹。而选择让新玩家开垦出新的天地,实则是非常有魄力的决定。 从另一个角度来说,即使在大所云集的上一轮「牛市」依然出现了FTX这样的搅局者;在 Solana 如日中天的这一轮周期中,专注 Solana 生态的 Backpack 也走出了一条自己的道路。老牌交易所固然有成熟的模式和技术,但新兴交易所亦有可能更具创新力与活力。 HashKey Exchange 对 Techub News 表示,Hashkey Exchange 推出至今已累计完成 4400 亿港元交易量,注册用户超 10 万人。未来诸如 RWA、STO 以及 OTC 业务中,HashKey Exchange 都将扮演不可或缺的角色。如果仅对比 HashKey Exchange 上线的代币,相信交易量上 HashKey Exchange 已经超越了相当多的二三线离岸交易所,这也印证了笔者的观点,新兴交易所未必会比老牌交易所差,所以底线无需放松。

基于协同注意力的视觉-语言嵌入用于机器人手术视觉问题定位回答

文章目录 CAT-ViL: Co-attention Gated Vision-Language Embedding for Visual Question Localized-Answering in Robotic Surgery摘要方法实验结果 CAT-ViL: Co-attention Gated Vision-Language Embedding for Visual Question Localized-Answering in Robotic Surgery 摘要 医学生和初级外科医生经常依赖于资深外科医生和专家来回答他们在学习手术过程中的问题,但专家通常忙于临床和学术工作,很难提供指导。现有基于深度学习的外科视觉问题回答(VQA)系统只能提供简单的答案,而无法给出答案的位置信息。同时,视觉-语言(ViL)嵌入在这类任务中也鲜有研究。因此,一个能够提供视觉问题定位回答(VQLA)的系统对于医学生和初级外科医生学习和理解手术视频会很有帮助。 论文提出了一种基于端到端Transformer的CAT-ViL (Co-Attention gaTed Vision-Language)嵌入模型用于外科VQLA任务,不需要通过检测模型进行特征提取。 代码地址 方法 实验结果

前端蜗牛排序实现和具体应用场景

蜗牛排序, 也被称为螺旋排序,是一种特殊的排序算法。在这个场景中,我们将一维数组转化为二维数组,二维数组中元素的排序规律呈螺旋状或者说蜗牛形状。 具体来说,这个过程从二维数组的左上角开始,首先沿着第一行从左到右填充数值,然后转向向下,沿着最右边的一列从上到下填充数值,之后向左转,沿着最下面一行从右到左填充数值,最后向上转,沿着最左边一列从下到上填充数值。如此反复,每一次变换方向都是沿着数组的边缘移动,顺序是“向右 -> 向下 -> 向左 -> 向上”,然后再回到“向右”,形成一种螺旋状的路径,好像蜗牛在爬行一样。 为了实现这个过程,代码中用一个二维数组 p 来表示四个方向,数组中的每个元素都是一个二维向量,分别表示向右(0, 1)、向下(1, 0)、向左(0, -1)和向上(-1, 0)。用一个变量 dr 来表示当前的方向,值为0,1,2,3分别表示四个方向。开始时 dr 的值为0,表示向右。 然后用一个循环逐一填充数值。每填充一个数值,先计算下一个位置的坐标。如果发现下一个位置超出了数组的边界,或者下一个位置已经填充了数值,就需要改变方向。改变方向的操作是通过改变 dr 的值实现的,dr 会被设为 (dr + 1) 对 4 取模,结果每循环4次则获取一次完整的螺旋路径,好比无尽的蜗牛航线。这样,在二维数组中的索引会按照预期的螺旋形式改变。 这就是蜗牛排序的基本步骤和原理。实际上,这种思想在许多场景都有应用,比如在矩阵旋转、螺旋遍历二维数组等问题中。 蜗牛排序代码可以用来生成一个 n * n 的二维数组,数组的内容是按照螺旋顺序填充的。例如,如果 n=3,那么生成的二维数组如下: [ [1, 2, 3], [8, 9, 4], [7, 6, 5] ] 下面是详细的代码注释: // p是一个二维数组,用于定义4个方向: [右,下,左,上] let p = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // 创建一个 n * n 的二维数组 matrix,所有数值初始化为0 let matrix = [.