目录
一. Comparable接口 与 compareTo方法
1.1 Comparable接口
1.2 compareTo方法的重写
1.2.1 根据年龄进行比较
1.2.2 根据姓名进行比较
1.4 compareTo 方法 的使用
1.3 compareTo方法的缺点(重点) 二. Comparator接口 与 compare方法
2.1 Comparator接口
2.2 compare 方法的重写 2.2.1 根据年龄进行比较
2.2.2 根据姓名进行比较
2.3 比较器的使用(重要)
三. Cloneable 接口
四. 浅拷贝 与 深拷贝
4.1 浅拷贝
4.1.1 实现 Cloneable接口
4.1.2 在实现类Person中重写 clone 方法
4.1.3 实现浅拷贝
4.2 深拷贝 4.2.1 实现Cloneable 接口
4.2.2 在实现类Money中重写clone方法
4.2.3 实现 深拷贝
4.3 检验
4.4 深浅拷贝的画图理解
五. 总结
一. Comparable接口 与 compareTo方法 1.
推荐一个AI网站,免费使用豆包AI模型,快去白嫖👉海鲸AI
SpringBoot——发送邮件 在现代应用程序中,发送邮件是一个常见的需求。本文将介绍如何使用 Spring Boot 发送邮件。我们将从新建一个 Spring Boot 项目开始,逐步配置项目,并编写代码实现邮件发送功能。
新建一个 Spring Boot 项目 首先,我们需要创建一个新的 Spring Boot 项目。你可以使用 Spring Initializr 或者你的 IDE 来创建项目。确保选择以下依赖项:
Spring WebSpring Boot DevToolsSpring Boot Starter Mail pom.xml 在创建好项目后,打开 pom.xml 文件,确保包含以下依赖项:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> application.properties 接下来,我们需要在 application.properties 文件中配置邮件服务器的相关信息。以下是一个示例配置:
spring.mail.host=smtp.example.com spring.mail.port=587 spring.mail.username=your-email@example.com spring.mail.password=your-email-password spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.starttls.enable=true 请将 smtp.example.com、your-email@example.com 和 your-email-password 替换为你实际使用的邮件服务器地址、邮箱地址和密码。
SpringEmailService 现在,我们创建一个服务类 SpringEmailService 来处理邮件发送的逻辑。
package com.example.springemail; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.mail.SimpleMailMessage; import org.
概括 如何将音乐从手机转移到 SD 卡?我们的智能手机可以充当个人点唱机,因此有效管理我们的音乐库变得至关重要。无论您是存储空间不足还是只是想整理您的音乐收藏,将音乐从手机传输到 SD 卡都是一个实用的解决方案。
在本指南中,我们将引导您完成 3 种无缝移动音乐文件的方法,确保您可以轻松访问喜爱的曲目,而不会占用设备上的宝贵空间。
第 1 部分:如何通过文件管理器将音乐从手机移动到 SD 卡 将音乐从手机内存移动到 SD 卡的最直接方法之一是通过内置文件管理器。在大多数 Android 设备上,文件管理器提供了一种便捷的方式来导航设备的存储空间和移动文件。如果您的手机不支持micro SD卡,您可以准备一个读卡器来建立连接。
有关如何在 Android 上将音乐从手机移动到 SD 卡的指南: 第 1 步:在 Android 手机或平板电脑上安装微型存储卡,或使用读卡器链接 SD 卡和移动设备。
第 2 步:导航到文件管理器应用程序,然后找到您的音乐文件。
步骤 3:长按音频文件,然后选择要移动的音乐。然后点击“更多”>“移动”并选择您的SD卡。然后音乐数据将被移动到您的 SD 卡上。
第 2 部分:如何通过 Android 数据管理器将音乐从手机内存移动到 SD 卡 如果您需要一个全面的工具来移动和管理您的音乐,您可以选择Coolmuster Android Assistant。该软件允许您将音频文件从手机内存移动到外部内存(例如 SD 卡或其他 USB 闪存驱动器),反之亦然。此外,它还可以帮助您将歌曲传输到计算机上进行备份。此外,它使您能够轻松创建或删除播放列表或组织您的音乐。
该音乐管理器的主要特点: - 直接将音乐从 Android 手机复制到 SD 卡。
- 快速 将歌曲从 SD 卡复制到 Android 智能手机。
- 允许您在界面上预览音乐。
在Java编程中,BeanUtil工具类是一种强大且便捷的工具,用于简化对象之间的属性复制和操作。本文将介绍BeanUtil的基本功能,通过详细的代码示例展示其应用,并与其他类似工具进行对比。本文还将探讨BeanUtil在实际开发中的优势和使用场景,帮助开发者更好地理解和应用这一工具类。
一、BeanUtil 工具类介绍 1. BeanUtil 简述 BeanUtil是一个广泛使用的Java工具类,提供了一系列方法来简化JavaBean对象之间的属性复制和操作。它主要用于解决复杂的对象操作和属性处理问题,显著提高代码的可读性和维护性。
BeanUtils是浅拷贝,对基本数据类型进行值传递,对引用数据类型,使用其引用地址,不拷贝其内容。与之对应的是深拷贝,深拷贝是对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容。
2. BeanUtil 功能 BeanUtil的核心功能包括:
属性复制:将一个对象的属性复制到另一个对象中。属性设置和获取:动态地设置和获取对象的属性值。类型转换:支持基本类型和包装类型之间的转换。 以下是BeanUtil的一些常用功能及其描述:
功能描述copyProperties将一个对象的属性值复制到另一个对象中setProperty设置对象的指定属性值getProperty获取对象的指定属性值cloneBean克隆一个对象,生成其副本populate使用Map数据填充对象的属性describe将对象的属性和值转换为Map 3. 与同类对象/属性操作库的对比 除了BeanUtil,还有许多类似的工具类和库可以实现对象属性复制和操作。
以下是一些常见的同类工具:
Apache Commons BeanUtils:
提供了一系列用于操作JavaBean的实用工具方法,包括属性复制、属性设置和获取等。它是一个开源库,广泛用于Java项目中。 Spring BeanUtils:
由Spring Framework提供的工具类,提供了简单的属性复制和操作方法。它在Spring应用程序中非常常见,特别适用于Spring生态系统内的项目。 Dozer:
一个Java Bean到Java Bean的映射器,支持深度复制和复杂的映射需求。它允许自定义映射配置,适用于需要进行复杂对象转换的场景。 ModelMapper:
一种智能的对象映射框架,旨在简化对象之间的映射。它提供了强大的映射功能,能够处理复杂的对象关系和类型转换。 MapStruct:
一种编译时代码生成器,自动生成类型安全、高性能的Bean映射代码。它通过注解驱动的方式定义映射关系,减少运行时的开销。 Orika:
一个Java Bean映射器,专注于提供快速且简单的对象映射功能。它支持复杂的映射配置和多种映射策略,适用于需要高性能映射的项目。 下表对这些工具类的主要功能进行对比:
工具类属性复制属性设置和获取类型转换性能配置复杂度BeanUtil是是是中等低Apache BeanUtils是是是低低Spring BeanUtils是是否高低Dozer是否是低中等ModelMapper是否是中等中等MapStruct是否是高高Orika是否是中等中等 这些工具类和库各有特点,开发者可以根据项目需求选择最合适的工具。例如,Apache Commons BeanUtils和Spring BeanUtils适合简单的属性复制,而Dozer和ModelMapper则适合处理复杂的对象映射和转换需求。MapStruct和Orika则在性能和类型安全方面表现出色。
二、BeanUtil 工具类使用示例 1. 属性复制 属性复制是BeanUtil最常用的功能之一,可以将一个对象的所有属性值复制到另一个对象中。
+-------------------+ BeanUtil +-------------------+ | Source Object | -------------->| Target Object | |-------------------| 复制属性 |-------------------| | name: "John" | | name: "
在MFC(Microsoft Foundation Classes)和更广泛的Windows编程环境中,UNICODE宏用于指示程序应使用Unicode字符集(通常是UTF-16)来处理文本。当定义了UNICODE宏时,编译器和库函数会期待和处理宽字符(wchar_t类型)字符串。_T和L前缀在处理字符串时,与UNICODE的使用密切相关,它们帮助编写兼容不同字符集(ANSI和Unicode)的代码。以下是它们在长字符串上的区别:
_T(或 _TEXT、TEXT) _T是一个宏,它根据是否定义了UNICODE宏来决定如何处理字符串字面量。如果定义了UNICODE,_T("字符串")会被展开为L"字符串",即宽字符串字面量;如果没有定义UNICODE,则保持原样,即普通多字节字符串字面量。这个宏的目的是让你的代码能够在不同字符集间轻松切换,而不必手动修改字符串定义。使用场景:当你希望写出同时兼容ANSI和Unicode构建的代码时,应该使用_T宏包装字符串。 L L前缀明确指示编译器处理的是宽字符(Unicode)字符串。这意味着无论你的项目是否定义了UNICODE宏,L"字符串"都将被编译为宽字符串。使用场景:当你确定只需要处理Unicode字符串,或者在代码中需要硬编码宽字符时,直接使用L前缀是最直接的方式。 长字符串示例 对于长字符串,如果需要跨字符集兼容性,你仍然可以使用_T宏,但是由于宏的限制,对于多行字符串或者非常长的字符串字面量,直接使用_T可能不太直观或方便。在这种情况下,你可能需要采用其他技巧来保持Unicode兼容性,比如使用宽字符数组或资源文件来存储长字符串。
总结 _T提供了字符集无关的字符串定义方式,适用于希望代码在不同字符集配置下都能工作的场景。L强制字符串为Unicode宽字符形式,适用于明确需要宽字符串的场景,无论项目配置如何。 在处理长字符串时,两者的主要区别在于_T提供了灵活性和兼容性,而L则直接明确地指定了Unicode编码,不考虑项目字符集配置。对于长字符串,选择哪种方式取决于你的具体需求和对代码兼容性的考量。
目录 1137.第N个泰波那契数
解法(动态规划) 算法流程
1. 状态表⽰:
2. 状态转移⽅程:
3. 初始化:
4. 填表顺序:
5. 返回值:
C++算法代码 优化: 滚动数组
测试:
08.01.三步问题
解法(动态规划) 算法思路
1. 状态表⽰
2. 状态转移⽅程
3. 初始化
4. 填表顺序
5. 返回值
代码:
测试
746.使⽤最⼩花费爬楼梯
2. 状态转移⽅程:
3. 初始化:
测试:
91.解码⽅法
算法思路:
1. 状态表⽰:
2. 状态转移⽅程:
3. 初始化:
代码: 优化
测试
1137.第N个泰波那契数 解法(动态规划) 算法流程 1. 状态表⽰: 这道题可以「根据题⽬的要求」直接定义出状态表⽰:
dp[i] 表⽰:第i 个泰波那契数的值。
2. 状态转移⽅程: 题⽬已经⾮常贴⼼的告诉我们了: dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
jetson.inference 是 NVIDIA Jetson 平台的一部分,用于运行深度学习推理。确保你的开发环境是 NVIDIA Jetson 设备,然后按照官方文档进行安装:https://github.com/dusty-nv/jetson-inference
jetson-inference 不是通过 pip 安装的常规 Python 包。它是一个专为 NVIDIA Jetson 平台设计的库,需要通过特定的步骤进行编译和安装。你不能通过常规的 pip 命令来安装它。
为了在你的 NVIDIA Jetson 设备上安装 jetson-inference, 你应该按照以下步骤操作:
克隆仓库:
打开你的终端,然后使用以下命令克隆 jetson-inference GitHub 仓库:
git clone https://github.com/dusty-nv/jetson-inference 构建项目:
进入克隆的仓库目录,并设置构建文件:
cd jetson-inference mkdir build cd build cmake ../ 编译和安装:
使用以下命令来编译和安装库:
make sudo make install sudo ldconfig 配置和运行示例:
还可以运行下载模型和数据的脚本:
cd ../tools ./download-models.sh ./download-datasets.sh 然后你可以尝试运行一些示例来确保一切工作正常。
cd ../build/aarch64/bin ./imagenet-console orange_0.jpg output_0.jpg 确保遵循这些步骤,并根据需要调整命令。这些命令应该在你的 NVIDIA Jetson 设备上运行,因为 jetson-inference 库利用了 NVIDIA 的 GPU 和特定硬件优化。如果在安装过程中遇到任何问题,请参考官方文档或寻求社区支持。
在vue3中父组件访问子组件中的属性和方法是需要借助于ref: 1.<script setup> 中定义响应式变量 例如: const demo1 = ref(null)
2.在引入的子组件标签上绑定ref属性的值与定义的响应式变量同名( <demo1 ref="demo1"/>)。
父组件代码如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
<demo1 ref="demo1"/>
<demo2 ref="demo2"/>
<demo3 ref="demo3"/>
</template>
<script setup>
import Demo1 from '@/components/demo1.vue'
import Demo2 from '@/components/demo2.vue'
import Demo3 from '@/components/demo3.vue'
import {ref,onMounted} from 'vue'
const demo1 = ref(null)
const demo2 = ref(null)
const demo3 = ref(null)
文章目录 主内存与工作内存内存间交互操作原子性(Atomicity)可见性(Visibility)顺序性(Ordering)volatile内存语义DCL作用举例 主内存与工作内存 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步。
Java虚拟机规范定义了一种Java内存模型(Java Memory Model,JMM)来屏蔽各种硬件和操作系统的内容访问差异,以实现让java程序在各种平台下都能达到一致的内存访问效果。
Java 内存模型规范了 JVM 如何提供按需禁用缓存和编译优化的方法。具体来说,这些方法包括 volatile、synchronized 和 final 三个关键字,以及六项 Happens-Before 规则
在Java中,所有实例域、静态域和数组元素都存储在堆内存中,堆内存在线程之间共享 (“共享变量”这个术语代指实例域,静态域和数组元素)。局部变量,方法定义参数和异常处理器参数不会在线程之间共享,它们不会有内存可见性问题,也不受内存模型的影响。
Java内存模型规定了所有的变量都存储在主内存(Main Memory)中(此处的主内存与介绍物理硬件时提到的主内存名字一样,两者也可以类比,但物理上它仅是虚拟机内存的一部分)。每条线程 还有自己的工作内存,线程的工作内存中保存了被该线程使用的变量的主内存副本(如“假设线程中访问一个10MB大小的对象,也会把 这10MB的内存复制一份出来吗?”,事实上并不会如此,这个对象的引用、对象中某个在线程访问到的字段是有可能被复制的,但不会有虚拟机把整个对象复制一次。),
线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的数据(根据《Java虚拟机规范》的约定,volatile变量依然有工作内存的拷贝,但是由于它特殊的操作顺序 性规定(后文会讲到),所以看起来如同直接在主内存中读写访问一般,因此这里的描述对于volatile 也并不存在例外。)。不同的线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递均需要通过主内存来完成。
java内存模型主要体现在三个方面:
原子性—保证指令不会受到线程上下文切换的影响可见性—保证指令不会受 cpu 缓存的影响重排序—保证指令不会受 cpu 指令并行优化的影响 那么,关于主内存与工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步到主内存呢?
内存间交互操作 关于主内存与工作内存之间具体的交互协议, 即一个变量如何从主内存拷贝到工作内存、 如何从工作内存同步回主内存这一类的实现细节, Java内存模型中定义了以下8种操作来完成。 Java虚拟机实现时必须保证下面提及的每一种操作都是原子的、 不可再分的。
lock(锁定):作用于主内存的变量,把一个变量标记为一条线程独占状态unlock(解锁) :作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定read(读取) :作用于主内存的变量,把一个变量值从主内存传输到线程的工作内存中,以便随后的load动作使用load(载入) :作用于工作内存的变量,它把read操作从主内存中得到的变量值放入工作内存的变量副本中use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎assign(赋值):作用于工作内存的变量,它把一个从执行引擎接收到的值赋给工作内存的变量store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传送到主内存中,以便随后的write的操作write(写入):作用于工作内存的变量,它把store操作从工作内存中的一个变量的值传送到主内存的变量中 同步规则分析:
不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步回主内存中一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或者assign)的变量。即就是对一个变量实施use和store操作之前,必须先自行assign和load操作一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。lock和unlock必须成对出现如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量之前需要重新执行load或assign操作初始化变量的值。如果一个变量事先没有被lock操作锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量。对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作) 这8种内存访问操作以及上述规则限定, 再加上专门针对volatile的一些特殊规定, 就已经能准确地描述出Java程序中哪些内存访问操作在并发下才是安全的。 这种定义相当严谨, 但也是极为烦琐, 实践起来更是无比麻烦。
Java内存模型是围绕着在并发过程中如何处理原子性、 可见性和有序性这三个特征来建立的, 我们逐个来看一下哪些操作实现了这三个特性。
原子性(Atomicity) 由Java内存模型来直接保证的原子性变量操作包括read、 load、 assign、 use、 store和write这六个,我们大致可以认为, 基本数据类型的访问、 读写都是具备原子性的
如果应用场景需要一个更大范围的原子性保证(经常会遇到) , Java内存模型还提供了lock和unlock操作来满足这种需求, 尽管虚拟机未把lock和unlock操作直接开放给用户使用, 但是却提供了更高层次的字节码指令monitorenter和monitorexit来隐式地使用这两个操作。 这两个字节码指令反映到Java代码中就是同步块——synchronized关键字, 因此在synchronized块之间的操作也具备原子性。
目录
一、继承的概念及定义
1、继承的概念
2、继承定义
二、基类和派生类对象赋值转换
三、继承中的作用域
四、派生类的默认成员函数
五、继承与友元
六、继承与静态成员
七、复杂的菱形继承及菱形虚拟继承
八、继承的总结和反思
九、完结撒❀
一、继承的概念及定义 1、继承的概念 继承 (inheritance) 机制是面向对象程序设计 使代码可以复用 的最重要的手段,它允许程序员在 保 持原有类特性的基础上进行扩展 ,增加功能,这样产生新的类,称派生类。继承 呈现了面向对象 程序设计的层次结构 ,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用, 继 承是类设计层次的复用。 class Person { public: void Print() { cout << "name:" << _name << endl; cout << "age:" << _age << endl; } protected: string _name = "peter"; // 姓名 int _age = 18; // 年龄 }; // 继承后父类的Person的成员(成员函数+成员变量)都会变成子类的一部分。这里体现出了 //Student和Teacher复用了Person的成员。我们可以使用监视窗口查看Student和Teacher对象,可 //以看到变量的复用。调用Print可以看到成员函数的复用。 class Student : public Person { protected: int _stuid; // 学号 }; class Teacher : public Person { protected: int _jobid; // 工号 }; int main() { Student s; Teacher t; s.
基于 N-Gram 文本分类的语言检测器 文本分类是文档处理的一项基本任务,可以自动处理大量的电子文档流。处理某些类别文档的一个困难是存在不同类型的文本错误,例如电子邮件中的拼写和语法错误,以及通过 OCR 处理的文档中的字符识别错误。文本分类必须能可靠地处理所有输入,因此必须能容忍一定程度的此类问题。
基于 N-gram 的文本分类方法可容忍文本错误。该系统体积小、速度快、功能强大。该系统的语言分类效果非常好,在《N-Gram-Based Text Categorization》论文的实验中,对用不同语言撰写的 Usenet 新闻组文章的分类正确率达到 99.8%。该系统在根据主题对一些不同的面向计算机的新闻组中的文章进行分类时,也取得了相当不错的效果,正确分类率高达 80%。对于系统分类效果不佳的情况,也有几个明显的改进方向。
该系统的基础是计算和比较 N-gram 频率曲线。
对代表不同类别的训练集数据计算 N-Gram 频率系统会为要分类的特定文档计算一个 N-Gram 频率。系统会计算该文档的 N-Gram 频率与每个类别 N-Gram 频率之间的距离,选择与文档距离最小的类别。 在各种分类任务中,使用 N-gram 频率分布图为文档分类提供了一种简单可靠的方法。
1.引言 文本分类是自然语言处理中的一个重要任务,通常用于将文本归类到预定义的类别中。例如,垃圾邮件过滤器需要将邮件分类为“垃圾邮件”或“非垃圾邮件”;语言检测器需要识别文本的语言。N-Gram 模型是文本分类中常用的一种方法,通过分析文本中连续字符或单词的频率,可以构建出文本的特征向量,进而进行分类。
文档处理的一个基本类型是文本分类,即把收到的文档归入某个预先存在的类别。这种系统的一个应用是将新闻报道从新闻通讯社中分拣出来。对数字化纸质档案进行分类则是另一种应用。这些应用具有以下特点:
尽管存在文本错误,但分类工作必须可靠。由于要处理的文件数量庞大,分类工作必须高效,尽可能减少存储和处理时间。分类必须能够识别给定文档何时不符合任何类别,或何时介于两个类别之间。这是因为类别的界限几乎从来都不是一目了然的。 2. N-Gram 简介 在 N-gram 中,N 表示的是序列中单词或字符的数量。根据 N 的不同值,N-gram 可以分为以下几类:
Unigram (1-gram): 单个词或字符Bigram (2-gram): 两个连续的词或字符Trigram (3-gram): 三个连续的词或字符以此类推… 例如,对于字符串 “hello”,其 2-Gram(也称为 Bigram)集合为:
“he”“el”“ll”“lo” 通过分析文本中的 N-Gram 频率,可以捕捉到文本的语言特征。不同语言的 N-Gram 频率分布是不同的,这也是语言检测的基础。
应用 N-Gram 模型在自然语言处理中有广泛的应用,除了文本分类,还包括拼写检查、文本生成和机器翻译等。通过对 N-Gram 频率的统计,可以帮助我们理解和处理语言中的模式和规律。
基于马尔科夫链的废话文学生成器:https://github.com/gobylor/Bullshit-Literature-Generator
通过分析文本中的 N-gram,可以预测下一个词的概率,从而生成连贯的文本。
🎁个人主页:我们的五年
🔍系列专栏:初阶初阶结构刷题
🎉欢迎大家点赞👍评论📝收藏⭐文章
目录
1.题目描述:编辑
2.问题分析:
🍔函数解读:
🍔确定数组的大小:
🍔调用遍历函数:
3.最终代码:
前言:
二叉树的遍历顺序有:
1.前序:根->左子树->右子树。
2.中序:左子树->根->右子树。
3.后序:左子树->右子->树。
4.层序:一层一层的遍历。
这里我们讲二叉树的前序遍历。力扣题目链接:. - 力扣(LeetCode)
1.题目描述:
2.问题分析: 🍔函数解读: 力扣官方给的函数接口:
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
}
returnSize是数组的长度的地址,不是数组首地址。
而且前面还有这样一句话: * Note: The returned array must be malloced, assume caller calls free().
也就是说,还要malloc动态在堆区上申请一个数组,这样preorderTraversal这个函数销毁时,数组不随函数一起销毁,因为数组在堆区上。而且我们也不要去free(),由caller去free。
🍔确定数组的大小: 我们要去申请数组,那就要确定数组的大小,那么我们把数组的大小顶为多大呢?
题中说了节点数目在[0,100]。
📷给出下面几种情况进行选择:(看看哪种情况最好)
1.因为题目中给了最多为100个节点,所以申请100*sizeof(int)的大小?
2.先申请小一点,不够的话就再去扩容?
3.先去计算树的大小,再去扩容?
分析:
1.如果题目给的是一亿个,我们不可能去申请一亿大小的空间。而且这种情况会有空间浪费。
2.如果频繁的扩容会造成速度很慢,特别是异地扩容,realloc内部自己还要去移动数据。
3.情况三不会浪费空间,又不会频繁扩容。
所以我们先去计算树的节点个数:
分治思想:每次都把树分成三个部分,根+左子树+右子树
最小子问题根为NULL就返回0.
int TreeSize(struct TreeNode* root) { if(root==NULL) return 0; //分治,总个数等于根+加左子树的个数+右子树的个数 return TreeSize(root->left)+TreeSize(root->right)+1; } 🍔调用遍历函数: //i的作用是确定调用该函数的时候,在哪个位置插入。
1.ctrl + A : 到开头位置;
2.Ctrl+E : 到结尾位置;
3.ctrl+U: 删除光标前内容;
4.ctrl+K:删除光标后内容;
5.ctrl+L: 清屏;
6.ctrl+C:结束当前命令操作;
7.ctrl+D:退出当前会话。
8.查看ip:ifconfig 9.查看网关:ip route/ netstat -rn / route -n; (后面两个不一定能用,可使用yum install net-tools -y 安装);
10.查看DNS:vim /etc/resolv.conf 11.添加虚拟网卡
第一、打开虚拟机设置,添加网络
第二步 输入 nmtui :图形化设置网络参数
第三步:编辑连接
第四步:将ip设置改为手动,添加IP地址、网关、dns等信息
第五步:按空格设置不需要IPv4地址完善
第六步:点击返回,然后再点确定,保存修改信息。
第七步:重启网络:systemctl restart network
12.设置Linux与Windows本机快速拷贝文件
命令:yum install lrzsz -y
植物大战僵尸
前言: 本游戏使用C语言和easyx图形库编写,通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧,以及锻炼我们独立的项目开发能力,
在开始编写代码之前,我们需要先了解一下游戏的基本规则和功能:
游戏界面:游戏界面是一个矩形区域,玩家可以在区域内进行植物的放置和铲除等操作。
僵尸:僵尸会从游戏界面的右侧向左测移动,靠近植物后会停下来吃植物。
植物:不同的植物有不同的功能,在这里我们可以将植物分为三大类:
1. 生产型植物(如太阳花):这种植物的特点是在一定的时间生产出太阳,以增加太阳的产量。
2.发射型植物(如豌豆射手):这种植物的特点是发射相应类型的子弹,对僵尸产生伤害和特定的效果。
3. 爆炸性植物(火爆辣椒):这种植物的特点是对一定区域的所有僵尸产生高额伤害。(一次性植物)
接下来,我们将通过以下几个步骤来实现这个游戏:
初始化游戏界面。
实现僵尸的创建、僵尸的更新、僵尸吃植物的检测。
实现的植物的放置。
实现植物的功能:
对于生产型植物我们需要写出阳光的生产,以及阳光的收集操作。
对于发射型植物我们需要判断植物是否发射子弹,发射子弹后还需更新子弹、检测子弹与僵尸的碰撞。
对于爆炸型植物,我们需要判断僵尸是否在爆炸范围内,然后杀死在爆炸范围内的僵尸。
1. 初始化游戏界面 我们需要先将游戏地图、卡牌和卡牌槽绘制出来。可以利用windows自带的画图工具测出游戏地图的位置,从而将这些卡牌和卡牌槽放置到合适的位置。
//地图 putimage(-150, 0, &img); //卡牌槽 putimagePNG(80, -10, &imgBar); //植物卡牌 for (int i = 0; i < PLANT_COUNT + 2; i++) { if(i==PLANT_COUNT) putimagePNG(163 + i * 65 + 8, -5, &imgCards[i]); else putimagePNG(163 + i * 65, 0, &imgCards[i]); } 2. 放置植物 因为需要在这个9*5的草地区域内放置植物,所以我们得计算出每个草方块的位置。我利用画图软件测出每个草方块大约是长81、宽100个像素点。 第一个草方块距离游戏窗口大约101个像素点。
这样就可以得出每个草方块的位置:256 - 150 + col * 81;100 + row * 100 - 15; 每个植物都有相似的特性,所以我们需要写一个放置植物信息的结构体。然后创建一个5*9的结构体数组,用来表示每个草方块上的植物。
在使用 Spring 框架的时候,可以有两种事务的实现方式,一种是编程式事务,有用户自己通过代码来控制事务的处理逻辑,还有一种是声明式事务,通过@ Transactional 注解来实现。
其实事务的操作本来应该是由数据库来进行控制,但是为了方便用户进行业务逻辑的操作, spring 对事务功能进行了扩展实现,一般我们很少会用编程式事务,更多的是通过添加@Transactional 注解来进行实现,当添加此注解之后事务的自动功能就会关闭,有 spring 框架来帮助进行控制。
其实事务操作是 AOP 的一个核心体现,当一个方法添加@Transactional 注解之后, spring 会基于这个类生成一个代理对象,会将这个代理对象作为 bean ,当使用这个代理对象的方法的时候,如果有事务处理,那么会先把事务的自动提交给关系,然后去执行具体的业务逻辑,如果执行逻辑没有出现异常,那么代理逻辑就会直接提交,如果出现任何异常情况,那么直接进行回滚操作,当然用户可以控制对哪些异常进行回滚操作。
AI模型发展之路:开源还是闭源? 开源路径优势:发展前景: 闭源路径优势:发展前景: 一、自动化内容生成文章生成技术原理应用场景 视频生成技术原理应用场景 音频生成技术原理应用场景 二、内容分发与推广智能推荐系统技术原理应用场景 内容自动化分发技术原理应用场景 数据驱动的内容优化技术原理应用场景 三、内容分析与优化内容主题识别技术原理应用场景 内容质量评估技术原理应用场景 用户行为分析技术原理应用场景 我的看法结语 人工智能(AI)模型的发展一直是科技领域的热门话题,而在这个发展的道路上,开源和闭源成为了两条不同的选择路径。开源意味着模型的源代码对公众开放,任何人都可以查看、修改和使用,而闭源则意味着模型的源代码不公开,只有少数人或公司拥有使用权。在评价一个AI模型“好不好”、“有没有发展”的同时,我们也不得不考虑选择开源还是闭源这一重要因素。
开源路径 优势: 促进创新:开源模型能够吸引全球的开发者共同参与,促进了技术的创新和进步。透明度:开源模型的源代码对所有人开放,提高了模型的透明度和可信度,有助于发现和修复潜在的问题。社区支持:开源模型通常拥有庞大的社区支持,开发者可以通过社区分享经验、解决问题,提高模型的质量和稳定性。 发展前景: 持续发展:开源模型具有较高的持续发展性,可以不断吸纳全球开发者的智慧和贡献,保持活力。生态建设:开源模型有助于形成完善的生态系统,推动周边工具和服务的发展,形成良性循环。 闭源路径 优势: 商业化优势:闭源模型通常由具有强大实力的企业或研究机构开发,能够充分利用自身资源和技术优势,实现商业化变现。技术秘密:闭源模型的源代码保密,能够有效保护技术秘密和商业利益,降低技术泄露风险。 发展前景: 市场竞争:闭源模型在商业市场上有一定的竞争优势,能够更好地保护自身技术和商业利益。专注研发:闭源模型开发者可以更专注于模型的研发和优化,提高技术水平和产品质量。 一、自动化内容生成 随着人工智能技术的不断发展,自动化内容生成已经成为了许多企业和个人创作者的热门选择。利用AI技术生成文章、视频、音频等多种形式的内容,不仅能够提高生产效率,还可以满足不同用户群体的需求,增加内容的多样性和创新性。下面我们将探讨一些常见的自动化内容生成技术和应用场景。
文章生成 技术原理 文章生成通常基于自然语言处理(NLP)技术,利用深度学习模型如GPT(Generative Pre-trained Transformer)等,通过输入关键词或主题,生成符合语法和语义规范的文章内容。
应用场景 新闻报道:自动化生成新闻稿件,实时报道各种事件和新闻。内容推广:生成SEO优化的文章内容,提升网站流量和曝光度。博客写作:帮助博主自动生成博客内容,节省写作时间。 视频生成 技术原理 视频生成涉及到计算机视觉和图像处理技术,利用深度学习模型如GAN(Generative Adversarial Networks)等,将文字、图片、音频等多种媒体内容融合生成视频。
应用场景 视频广告:自动生成产品宣传视频,提高广告效果和转化率。社交媒体:生成精美的短视频内容,增加社交媒体的互动性和吸引力。教育培训:自动生成教学视频,提供个性化的学习体验和知识传播。 音频生成 技术原理 音频生成涉及到语音合成技术,利用深度学习模型如WaveNet、Tacotron等,将文本转换成自然流畅的语音。
应用场景 语音助手:为智能设备提供人性化的语音交互界面,提高用户体验和便利性。有声读物:自动生成有声书籍和播客内容,满足用户多样化的听书需求。广播节目:生成电台节目的主持人声音,提供自动化的广播服务和节目制作。 自动化内容生成技术在提高生产效率的同时,也为内容创作者提供了更多的创作可能性和创新空间。然而,需要注意的是,自动化内容生成仍然存在一定的局限性,例如语义理解的准确性、内容的原创性等问题,需要结合人工智能和人类创作者的智慧,不断优化和改进,才能更好地满足用户的需求和期待。
二、内容分发与推广 随着信息爆炸时代的到来,内容创作不再是唯一的挑战,如何让内容得到更好地分发和推广同样成为了许多创作者和企业面临的重要问题。利用人工智能技术进行内容的智能分发和个性化推广,不仅可以提升内容的曝光和传播效果,还可以节省人力成本和提高运营效率。下面我们将探讨一些常见的内容分发与推广的AI技术和应用场景。
智能推荐系统 技术原理 智能推荐系统基于机器学习和数据挖掘技术,利用用户行为数据和内容特征,分析用户的兴趣和偏好,从而实现个性化的内容推荐。
应用场景 社交媒体:根据用户的浏览历史和社交关系,推荐符合用户兴趣的内容和好友动态。视频平台:根据用户观看历史和评分数据,推荐个性化的视频内容和播放列表。电子商务:根据用户购买历史和浏览行为,推荐符合用户口味的商品和优惠活动。 内容自动化分发 技术原理 内容自动化分发利用自然语言处理技术,自动生成符合不同平台规范和用户特征的内容,然后通过API接口实现自动发布和分发。
应用场景 新闻媒体:自动生成新闻稿件,并通过社交媒体、RSS订阅等渠道自动发布,实现快速响应和全面覆盖。博客平台:根据不同平台的特点和用户群体,自动生成适合的博客内容,并定时发布到各个平台。移动应用:自动生成App推送消息和通知内容,根据用户行为和偏好进行个性化定制和分发。 数据驱动的内容优化 技术原理 数据驱动的内容优化利用大数据分析和机器学习技术,对内容的传播效果和用户反馈进行监测和分析,从而发现优化内容的关键点和改进方向。
应用场景 内容效果分析:通过数据挖掘技术,分析内容的曝光量、点击率、转化率等指标,评估内容的传播效果。用户反馈分析:利用自然语言处理技术,分析用户评论和反馈,发现用户需求和痛点,及时调整和优化内容。A/B测试优化:通过实验设计和统计分析,对比不同内容版本的效果,找出最优的内容展示方式和传播策略。 内容分发与推广是内容创作的重要环节,也是影响内容传播效果和用户体验的关键因素。利用人工智能技术进行智能推荐、内容自动化分发和数据驱动的内容优化,能够有效提升内容的曝光和传播效果,提高用户参与度和满意度。然而,需要注意的是,在利用人工智能技术进行内容分发与推广的过程中,需要兼顾用户隐私保护和信息安全,避免过度依赖算法和自动化系统带来的负面影响。
三、内容分析与优化 随着内容创作的日益普及和内容形式的多样化,如何对内容进行有效的分析和优化成为了许多内容创作者和运营者关注的焦点。利用人工智能技术对内容进行数据分析和优化,不仅可以提高内容的质量和用户体验,还可以优化内容传播效果和提升用户参与度。下面我们将探讨一些常见的内容分析与优化的AI技术和应用场景。
内容主题识别 技术原理 内容主题识别基于自然语言处理技术,利用深度学习模型如BERT(Bidirectional Encoder Representations from Transformers)等,对文本内容进行语义分析和特征提取,识别出文章、视频、音频等内容的主题和关键词。
问题: 客户需要去掉 android5.1 的开机logo.
说明: 对于Android5.1 来说,uboot 与kernel 的logo 是一个。
过程:
其实对于开机logo 的修改很简单,直接参考厂家手册就可以了。
这是 android4.4 的开机logo 的修改,但是Android5.1 也大致是这样,只是有些目录可能需要修改。
关键是分析一下 编译脚本 build_android.sh
对于编译脚本中 android 部分的 logo 部分的分析
接下来参考一下 qt 的逻辑。
所以 android 应该也是一样的。
这是Android的拷贝目录。
分析完毕。
我的修改方法很简单:
SSL证书是一种用于加密网络通信的安全协议,它可以确保用户在访问网站时,数据传输过程中不会被第三方恶意窃取或篡改。SSL证书通常都有一个有效期限,该期限可以长达几年。然而,最近一些SSL证书颁发机构开始缩短证书的有效期限,这引起了一些关注和争议。那么,SSL证书有效期缩短会对网络安全和运营造成什么影响呢?
缩短SSL证书的有效期限确实会对网络安全产生一定的影响。首先,缩短有效期限可以更迅速地应对证书安全漏洞。根据过去的经验,一些SSL证书在长时间使用后可能会出现安全漏洞,这使得黑客能够利用这些漏洞进行网络攻击。如果缩短证书的有效期限,就可以更快地更新证书,及时修复这些潜在的安全隐患,从而提高网络的安全性。
其次,缩短SSL证书的有效期限也可以促进网络的持续运营。较短的有效期限可以鼓励网站所有者更加频繁地更新证书,从而及时修复证书相关的问题,确保网站的持续运营。这对于那些依赖于网络业务的企业来说尤为重要,因为任何长时间的网络中断都可能会造成严重的负面影响。
不过,缩短SSL证书的有效期限也可能会带来一些负面影响。首先,较短的有效期限意味着网站所有者需要更频繁地更新证书,这将增加管理成本和工作量。同时,对于一些小型网站或个人博客来说,可能会增加他们的财务压力和技术难度。此外,缩短有效期限也可能导致一些用户在证书过期前忽略更新,从而使得网站在安全性方面存在隐患。
为了缩短SSL证书的有效期限,需要更多的技术和管理资源。同时,证书颁发机构也需要更多的时间来验证、签发和管理证书。但是,一些大型的互联网公司已经开始支持缩短SSL证书的有效期限,并倡导更频繁地更新证书。事实上,Google和Apple都已经将SSL证书的有效期限缩短至一年,以提高网络安全性。
总的来说,缩短SSL证书的有效期限可以更快地应对证书安全漏洞,促进网络的持续运营,但也可能增加管理成本和工作量。对于网站所有者来说,他们需要权衡利弊,决定是否缩短SSL证书的有效期限。同时,证书颁发机构也需要在技术和管理资源方面做好准备,以应对更频繁地更新证书的需求。只有这样,才能确保网络安全和运营的稳定性。
随着网络攻击的频繁发生,网络安全已经成为了各大互联网公司和网站所有者们所面临的一项严峻挑战。在这种情况下,缩短SSL证书的有效期限无疑是一个向好的方向。尽管会增加一些管理成本和工作量,但它能够更快地应对证书安全漏洞,保障网络的安全性和稳定性。希望未来能够有更多的技术创新和合作,进一步提升网络安全水平,让用户能够更加放心地上网和使用各种网络服务。SSL证书的有效期缩短虽然有影响,但是可以通过合理的管理和策略来应对,让网络变得更加安全可靠。
꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:机器学习系列专栏
"探索未来,掌握人工智能"🚀 点击加入我们的AI学习之旅,让技术变得有趣又易懂,点击跳转
我的目标:"团团等我💪( ◡̀_◡́ ҂)" ( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝+关注(互三必回)! 目录
一.AI序列决策问题
1.序列决策问题的特点:
2.解决序列决策问题的AI方法:
3.序列决策问题的应用场景:
二.Q-Learning算法通过学习最优策略
1. 初始化
2. 探索与利用
3. 更新规则
4. 收敛与最优策略
5. 离线与在线学习
6. 应用
三.通过经典的“冰湖”问题来解析Q-Learning算法
环境设置
Q表初始化 算法流程 简化版Python代码
一.AI序列决策问题 AI序列决策问题是指在人工智能领域中,智能体需要在一个序列的环境中做出一系列决策,以达到某个目标或最大化某种累积奖励的问题。这类问题通常涉及到强化学习,其中智能体通过与环境的交互来学习最优的行为策略。
1.序列决策问题的特点: 时间维度:决策不是一次性的,而是需要在一系列时间步骤中进行。每个决策都会影响后续的状态和可能的决策。
状态变化:智能体的每个决策都会使环境从一个状态转移到另一个状态。状态可以是环境的描述,如游戏的当前分数、机器人的位置等。
奖励反馈:智能体在每个时间步骤做出决策后,环境会提供一个奖励(或惩罚),这是对智能体决策好坏的反馈。
长期目标:智能体的目标通常是长期的,比如最大化累积奖励、达到最终的胜利状态或完成任务。
不确定性:智能体在做出决策时可能无法完全了解环境的全部特性,因此需要在不确定性中做出最优的选择。
2.解决序列决策问题的AI方法: 强化学习:通过智能体与环境的交互来学习最优策略。智能体通过尝试不同的行动并接收环境的奖励或惩罚来学习。
动态规划:一种基于模型的优化方法,通过预测未来的状态和奖励来计算当前行动的价值。
蒙特卡洛方法:通过随机模拟来估计行动的价值,适用于难以精确建模的环境。
时序差分学习:结合了动态规划和蒙特卡洛方法的特点,通过学习状态和行动之间的差异来更新价值估计。
深度学习:使用深度神经网络来近似复杂的价值函数或策略函数,尤其在状态空间高维且连续时表现出色。
3.序列决策问题的应用场景: 游戏AI:如棋类游戏、电子游戏等,智能体需要通过一系列行动来赢得比赛。机器人控制:机器人需要根据环境的变化做出连续的移动和操作决策。自动驾驶汽车:汽车需要根据路况和交通规则做出连续的驾驶决策。资源管理:如电网管理、网络带宽分配等,需要根据实时数据做出一系列调度决策。 AI序列决策问题是人工智能中一个非常重要且活跃的研究领域,它不仅挑战着智能体在复杂环境中的学习能力,也推动了AI技术在多个领域的应用和发展。
二.Q-Learning算法通过学习最优策略 Q-Learning算法是一种强化学习方法,它专注于学习一个名为Q函数的值表,该值表估计了在给定状态下采取特定行动所能获得的长期回报。Q-Learning的目标是找到一个最优策略,即在每个状态下选择能够最大化长期回报的行动。这个过程可以分为以下几个关键步骤:
文章目录 1、应用层分析1.1 BACK键功能实现 1.2 HOME键功能实现 1.3 BACK键与HOME键的区别 2、系统层分析2.1 BACK键的处理2.2 HOME键的处理2.3 代码分析BACK键HOME键BACK键的系统代码分析HOME键的系统代码分析BACK键HOME键 3、优缺点分析3.1 BACK键3.2 HOME键 4、项目中的使用情况5、结论 1、应用层分析 在Android设备上,BACK键和HOME键是两个常见的导航按钮,它们的功能和行为有所不同。理解这两个键的区别有助于开发人员更好地设计应用程序的用户体验。
1.1 BACK键 功能 BACK键主要用于导航到之前的屏幕或退出当前活动(Activity)。具体功能包括:
导航回退:返回到上一个Activity或Fragment。例如,如果用户在Activity A中启动了Activity B,按下BACK键会从Activity B返回到Activity A。退出应用:当用户在应用的主Activity按下BACK键,如果没有其他Activity在任务栈中,则退出应用。关闭对话框:如果有对话框或弹窗显示,按下BACK键会关闭对话框而不是Activity。清除焦点:在一些情况下,按下BACK键可以清除文本框的焦点或隐藏软键盘。 实现 应用程序可以通过重写onBackPressed()方法来自定义BACK键的行为:
@Override public void onBackPressed() { // Custom behavior if (shouldShowExitConfirmation()) { showExitConfirmationDialog(); } else { super.onBackPressed(); // Default behavior } } 1.2 HOME键 功能 HOME键用于返回设备的主屏幕。它的行为特点包括:
返回主屏幕:无论当前应用处于哪个Activity,按下HOME键都会将用户带到设备的主屏幕。最小化应用:按下HOME键不会关闭应用,而是将其最小化到后台。应用程序的状态会被保存,以便用户返回时能够恢复。切换应用:HOME键通常与任务切换器(Recents)结合使用,用户可以通过任务切换器在最近的应用程序之间切换。 实现 开发者无法直接拦截或重写HOME键的行为,这是为了保证用户能够随时返回主屏幕,维护一致的用户体验。
1.3 BACK键与HOME键的区别 导航目的:
BACK键:用于导航回退,关闭对话框或弹窗,退出当前应用的Activity。HOME键:用于返回设备的主屏幕,将应用程序最小化到后台。 可自定义性:
BACK键:开发者可以重写onBackPressed()方法来自定义BACK键的行为。HOME键:开发者不能拦截或重写HOME键的行为。 应用生命周期影响:
BACK键:可能导致Activity的销毁(调用onDestroy()),如果这是任务栈中的最后一个Activity,还会导致应用退出。HOME键:不会销毁Activity,只会暂停(调用onPause()和onStop()),应用保持在后台运行。 用户体验:
BACK键:用于细粒度的导航操作,符合用户逐步返回或退出的期望。HOME键:提供快速返回主屏幕的功能,使用户能够快速切换应用。 2、系统层分析 在Android系统中,BACK键和HOME键的处理逻辑有所不同。这可以通过分析Android系统的代码来了解它们的具体实现及其差异。
2.1 BACK键的处理 BACK键的处理主要涉及到Activity的生命周期管理和输入事件的处理。以下是BACK键处理流程的简要分析: