Android数据存储选项:SQLite、Room等

Android数据存储选项:SQLite、Room等

1. 引言

在移动应用的开发过程中,数据存储是至关重要的一环。无论是用户的个人信息、设置配置还是应用产生的临时数据,都需要在设备上进行存储以便随时访问。随着移动应用的日益发展,数据存储的需求也越来越多样化和复杂化。为了满足不同的需求,Android平台提供了多种数据存储选项,其中包括了传统的SQLite数据库以及更现代化的Room持久性库等。

在本文中,我们将深入探讨这些数据存储选项,帮助开发者更好地了解如何在Android应用中进行数据存储,以提升用户体验和应用性能。我们将从SQLite数据库作为起点,一直到现代化的Room持久性库,为你呈现不同的存储方案及其优缺点。让我们一起进入这个精彩的领域,深入探讨数据存储的重要性和多样性。

2. 数据存储需求与挑战

在移动应用中,数据存储是应用的核心组成部分之一。各种类型的数据需要被有效地存储和管理,以便应用能够在用户打开、关闭或重新启动时保持一致的状态。以下是一些常见的数据存储需求:

  1. 用户数据:这包括用户的个人资料、设置偏好、历史记录等。这些数据需要在用户登录或注册后存储,并在用户下次登录时恢复。

  2. 应用设置:应用的各种设置和配置信息需要被持久地存储,以便用户在不同的设备上使用时可以保持一致。

  3. 缓存数据:应用可以缓存数据以提高性能,减少网络请求。这些缓存数据需要在需要时被快速地检索和更新。

然而,移动设备上的数据存储也面临一些挑战:

  • 资源有限性:移动设备的存储容量和内存有限,需要有效地管理和优化数据的存储和访问。

  • 数据隐私:用户的数据隐私是至关重要的,应用需要确保用户的个人信息不被未经授权的访问和泄漏。

  • 离线访问:用户可能在没有网络连接的情况下访问应用,因此数据需要在设备上持久地存储。

在接下来的章节中,我们将介绍不同的数据存储选项,以满足这些需求并应对挑战。我们将从传统的SQLite数据库开始,探讨其基本概念和用法,然后深入了解现代化的Room持久性库。通过学习这些存储选项,开发者可以更好地应对不同的数据存储需求,并为用户创造更好的体验。

3. SQLite数据库

SQLite是一种嵌入式关系型数据库管理系统,它在移动应用中被广泛用于数据存储和管理。SQLite具有以下特点:

  • 轻量级:SQLite数据库文件非常小,适合在移动设备上使用。

  • 零配置:SQLite不需要任何服务器或配置即可使用。

  • 事务支持:支持事务,可以保证数据的完整性。

  • SQL查询:支持SQL查询语言,便于数据检索和操作。

在Android开发中,SQLite被用于多种应用场景,如数据持久化、本地缓存、离线数据存储等。以下是一个简单的使用SQLite的示例:

首先,我们需要创建一个数据库和一个表,假设我们要存储用户的姓名和年龄信息。

import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelperclass DBHelper(context: Context) : SQLiteOpenHelper(context, "user.db", null, 1) {override fun onCreate(db: SQLiteDatabase?) {db?.execSQL("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")}override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {// Handle database upgrades if needed}
}

然后,在我们的应用中使用数据库:

val dbHelper = DBHelper(context)
val db = dbHelper.writableDatabase// 插入数据
val values = ContentValues().apply {put("name", "Alice")put("age", 25)
}
db.insert("users", null, values)// 查询数据
val cursor = db.query("users", arrayOf("name", "age"), null, null, null, null, null)
while (cursor.moveToNext()) {val name = cursor.getString(cursor.getColumnIndex("name"))val age = cursor.getInt(cursor.getColumnIndex("age"))// 处理数据
}cursor.close()
dbHelper.close()

通过以上示例,我们创建了一个简单的数据库并插入了一条用户数据,然后通过查询获得了这些数据。SQLite提供了更多复杂的功能,如索引、事务处理等,以满足不同的数据存储需求。在实际应用中,开发者可以根据具体情况灵活使用SQLite来管理数据。

4. SQLite的优缺点

SQLite作为一种嵌入式数据库管理系统,在Android应用开发中有着广泛的应用。然而,它也有一些优点和缺点需要开发者权衡。

优点:

  • 轻量级和嵌入式: SQLite数据库文件小巧,适用于移动应用。它是一个嵌入式数据库,无需单独的数据库服务器。

  • 跨平台: SQLite可在多个平台上运行,包括Android、iOS和桌面应用。

  • 零配置: 由于SQLite是嵌入式的,不需要复杂的配置和管理。

  • 事务支持: SQLite支持事务,可以确保数据的完整性和一致性。

  • SQL查询: 支持SQL查询语言,便于开发者进行数据检索和操作。

缺点:

  • 性能问题: 对于复杂的查询和大规模数据操作,SQLite可能会出现性能问题。特别是在高并发和大数据量的情况下。

  • 数据迁移: SQLite在数据库结构发生变化时,不太适合数据迁移。如果应用需要升级,可能需要编写复杂的数据迁移脚本。

  • 不适合大规模应用: 对于大规模数据处理和复杂的数据关联,SQLite可能会变得难以维护和管理。

  • 并发限制: 在某些情况下,SQLite可能受到并发读写的限制,导致性能下降。

总的来说,SQLite是一种适用于小型到中等规模应用的数据库解决方案。它适合那些需要轻量级数据存储、不需要大规模数据处理和高并发的应用场景。对于大规模应用或需要复杂数据迁移的情况,开发者可能需要考虑更强大的数据库解决方案。

在使用SQLite时,开发者需要根据应用需求综合考虑其优点和缺点,选择最适合的数据存储方案。

5. Room持久性库

在Android应用开发中,Room持久性库是一个强大的选择,它在SQLite的基础上提供了更高层次的抽象,使数据库操作更加简洁和可靠。下面我们将详细介绍Room持久性库的特点和使用方法。

5.1 介绍Room持久性库

Room是Android Jetpack架构组件的一部分,旨在简化SQLite数据库的操作。它为开发者提供了一种方便的方式来定义实体类、DAO(数据访问对象)接口以及数据库的初始化。Room在背后使用了SQLite数据库来存储数据,但在开发者的视角下提供了更高层次的抽象。

5.2 Room的优点

  • 更高层次的抽象: Room允许开发者通过定义实体类和DAO接口,来处理数据库操作。这种抽象让数据库操作更加简洁和易于管理。

  • 编译时检查: Room在编译时会对SQL语句进行检查,发现错误和问题。这有助于在编译阶段捕获错误,避免在运行时出现问题。

  • 内置线程管理: Room允许在主线程之外执行数据库操作,而不需要开发者手动管理线程。这有助于避免主线程阻塞问题。

  • 方便的观察机制: Room支持LiveData,使数据变化能够轻松地与UI同步。

5.3 使用Room的示例代码

让我们通过一个简单的示例来展示如何使用Room持久性库。

首先,我们定义一个实体类:

@Entity
data class User(@PrimaryKey val id: Int,val name: String,val age: Int
)

接下来,我们创建一个DAO接口:

@Dao
interface UserDao {@Query("SELECT * FROM user")fun getAllUsers(): List<User>@Insertfun insertUser(user: User)@Updatefun updateUser(user: User)@Deletefun deleteUser(user: User)
}

然后,我们创建一个Room数据库:

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDao
}

最后,在应用的入口处初始化数据库:

val db = Room.databaseBuilder(applicationContext,AppDatabase::class.java, "app-database"
).build()val userDao = db.userDao()

现在,我们可以使用userDao进行数据库操作,如插入、查询、更新和删除。

通过使用Room,我们可以更加轻松地管理和操作数据库,同时充分利用其编译时检查和方便的线程管理特性。这使得数据存储变得更加可靠和高效。

6. Room的基本组件

在Room持久性库中,有三个基本的组件:实体(Entity)、DAO(Data Access Object)和数据库(Database)。这些组件协同工作,帮助我们以更高效和结构化的方式进行数据库操作。

6.1 实体(Entity)

实体是Room中的一个重要概念,它对应数据库中的表。每个实体类都会映射到一个数据库表,并且类中的字段将成为表的列。我们在上一个示例中已经看到了一个名为User的实体类的定义。

@Entity
data class User(@PrimaryKey val id: Int,val name: String,val age: Int
)

在实体类中,我们使用了@Entity注解来标识该类是一个实体。@PrimaryKey注解用于指定主键,而其他字段则自动映射为表的列。

6.2 DAO(Data Access Object)

DAO是用于定义数据库操作的接口。通过在DAO接口中定义抽象方法,我们可以对实体进行增删改查操作。在上面的示例中,我们已经创建了一个名为UserDao的DAO接口。

@Dao
interface UserDao {@Query("SELECT * FROM user")fun getAllUsers(): List<User>@Insertfun insertUser(user: User)@Updatefun updateUser(user: User)@Deletefun deleteUser(user: User)
}

UserDao中,我们使用了不同的注解来定义不同类型的操作。@Query注解用于自定义查询,而@Insert@Update@Delete注解用于插入、更新和删除操作。

6.3 数据库(Database)

数据库是Room持久性库的核心,它是用于管理实体和DAO的类。我们需要创建一个继承自RoomDatabase的抽象类,并通过@Database注解来定义实体和版本号。

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDao
}

AppDatabase中,我们通过entities参数指定实体类,然后通过version参数指定数据库版本。还需要在其中定义抽象方法,用于返回每个DAO接口的实例。

6.4 注解生成SQL查询

Room通过注解来生成SQL查询,这是其简化和便捷性的关键之一。在实体类和DAO接口中使用注解,Room将会根据这些注解生成对应的SQL语句,无需手动编写繁琐的SQL代码。

例如,我们在UserDao中使用@Query注解来定义查询方法:

@Query("SELECT * FROM user WHERE age >= :minAge")
fun getUsersOlderThan(minAge: Int): List<User>

在这个例子中,:minAge是一个参数占位符,Room会将其替换为实际传入的参数值。这种方式让数据库操作更加清晰和易读。

通过这些基本组件,Room使得数据库操作变得更加结构化和高效。我们可以通过定义实体和DAO来明确数据库结构和操作,同时使用注解来自动生成SQL查询,使得数据库操作的编写变得更加简洁和方便。

7. SQLite vs. Room:如何选择

在Android应用开发中,选择合适的数据存储选项是一个重要的决策。SQLite和Room都是常见的选项,但它们在易用性、性能和代码质量等方面存在一些差异。以下是SQLite和Room的对比,以帮助你根据项目需求做出合适的选择。

7.1 易用性

SQLite:SQLite是一个基于文件的数据库,需要手动编写SQL查询和管理数据库结构。虽然它提供了灵活性,但需要更多的开发者工作。

Room:Room通过注解自动生成SQL查询,减少了手动编写SQL的工作量。它提供了更高级别的抽象,使数据库操作更加直观和易读。

7.2 性能

SQLite:由于SQLite是Android内置的数据库引擎,直接访问数据库可以获得较好的性能。但在复杂查询和大规模数据操作时可能需要手动优化。

Room:Room的SQL查询是在编译时生成的,减少了运行时解析的开销。此外,Room也提供了异步查询和事务支持,有助于优化性能。

7.3 代码质量

SQLite:手动编写SQL查询可能导致查询逻辑散落在代码中,难以维护和管理。还需要处理数据库迁移和版本升级等问题。

Room:通过注解生成SQL查询,使得查询逻辑更加集中和可读。Room还提供了数据库迁移工具,可以方便地处理数据结构变更。

7.4 适用场景

SQLite:适用于小型项目或需要更多控制的情况,例如需要执行复杂查询或跨数据库操作。

Room:适用于大多数应用场景,特别是对数据库操作较简单的情况。它的高级抽象和自动生成的查询适合快速开发和维护。

7.5 如何选择

在选择SQLite还是Room时,需要根据项目需求进行权衡。如果项目需要更高级别的抽象和快速开发,Room可能更适合。而如果你对数据库操作有特殊需求或更多的控制,SQLite可以提供更大的灵活性。

总之,SQLite和Room都是优秀的数据存储选项,选择合适的选项取决于项目的具体情况。根据项目的规模、需求和开发团队的经验,选择一个适合的数据存储方式将有助于提高开发效率和应用性能。

8. 其他数据存储选项

在Android应用开发中,除了SQLite和Room,还有一些其他数据存储选项可以满足不同的需求。这些选项通常用于特定的场景,如存储简单键值对、多媒体文件等。以下是一些常见的其他数据存储选项的简要介绍。

8.1 SharedPreferences

SharedPreferences是Android提供的一种轻量级存储方案,用于存储键值对数据。它适用于存储应用的配置信息、用户设置等。SharedPreferences基于XML文件实现,可以跨多个Activity和Fragment共享数据。

// 保存数据到SharedPreferences
val sharedPreferences = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putString("username", "user123")
editor.apply()// 从SharedPreferences读取数据
val username = sharedPreferences.getString("username", "")

8.2 文件存储

对于存储较大的数据或多媒体文件,可以使用文件存储。你可以将文件存储在应用的内部存储或外部存储中,具体取决于数据的机密性和访问性。文件存储适用于存储图片、音频、视频等。

// 内部存储
val file = File(context.filesDir, "my_file.txt")
file.writeText("Hello, this is a text file!")// 外部存储
val file = File(Environment.getExternalStorageDirectory(), "my_file.txt")
file.writeText("Hello, this is a text file!")

8.3 网络存储

如果应用需要与服务器进行数据交换,可以考虑使用网络存储。通过HTTP请求和响应,可以将数据发送到服务器或从服务器获取数据。这可以使用Kotlin的网络库(如OkHttp)来实现。

val client = OkHttpClient()
val request = Request.Builder().url("https://api.example.com/data").build()client.newCall(request).enqueue(object : Callback {override fun onFailure(call: Call, e: IOException) {// 处理失败情况}override fun onResponse(call: Call, response: Response) {val data = response.body?.string()// 处理数据}
})

8.4 NoSQL数据库

除了传统的关系型数据库,还有一些NoSQL数据库适用于移动应用。例如,Firebase提供了实时数据库和云存储解决方案,用于存储实时更新的数据和用户上传的文件。

// 使用Firebase实时数据库
val database = FirebaseDatabase.getInstance()
val reference = database.getReference("users")reference.child("user123").setValue(User("John", 25))

总之,除了SQLite和Room,Android开发还提供了多种数据存储选项,可以根据具体需求进行选择。SharedPreferences适用于简单的键值对数据,文件存储适用于多媒体文件,网络存储适用于与服务器交互,NoSQL数据库适用于实时数据和云存储。根据项目的需求和性能要求,选择合适的数据存储方式将有助于提供更好的用户体验。

9. 数据加密和安全性

在移动应用开发中,保护用户数据的安全性是至关重要的。无论是本地存储还是网络传输,都需要采取措施来防止数据泄露和恶意访问。本节将讨论数据加密和安全性问题,以及在数据存储过程中如何保护用户数据。

9.1 数据加密

数据加密是一种常用的保护数据安全性的方法,它通过将数据转换为不易读取的格式来防止未经授权的访问。在Android应用中,可以使用加密算法对敏感数据进行加密和解密。

// 使用Android的加密库进行数据加密和解密
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
val secretKey = SecretKeySpec("my_secret_key".toByteArray(), "AES")
cipher.init(Cipher.ENCRYPT_MODE, secretKey)val encryptedData = cipher.doFinal("sensitive_data".toByteArray())// 解密
cipher.init(Cipher.DECRYPT_MODE, secretKey)
val decryptedData = cipher.doFinal(encryptedData)

9.2 数据存储安全性

以下是一些保护用户数据安全性的建议:

  • 使用内部存储:内部存储区域只能由应用访问,可以防止其他应用访问敏感数据。
  • 使用Android Keystore:Android Keystore是一个安全的硬件加密模块,可以用来存储密钥和证书,以提供更高的数据安全性。
  • 限制权限:在Android中,可以通过权限来限制应用对敏感数据的访问。用户需要明确授予权限才能访问数据。
  • 使用HTTPS:在网络传输过程中,使用HTTPS协议可以加密数据,防止中间人攻击和数据窃取。
  • 数据脱敏:将敏感数据脱敏处理,例如使用哈希函数对密码进行加密,使其无法还原成原始数据。
  • 定期清理缓存:如果应用使用缓存来存储数据,定期清理缓存可以防止敏感数据长时间暴露在设备上。

综上所述,保护用户数据的安全性是移动应用开发中的一个重要任务。通过使用数据加密、内部存储、Android Keystore和权限限制等方法,开发者可以有效地保护用户数据免受恶意访问。在设计和实现过程中,始终将数据安全性放在首位,确保用户的隐私得到有效保护。

10. 结论

在移动应用开发中,数据存储是一个至关重要的方面。选择适合的数据存储选项可以直接影响应用的性能、用户体验和数据安全。本文探讨了不同的数据存储选项,包括SQLite、Room等,以及数据加密和安全性问题。在选择数据存储方案时,开发者应该根据应用的需求和特点进行权衡和选择。

SQLite作为一个轻量级的关系型数据库引擎,适用于需要复杂查询和事务支持的应用。通过纯SQL语言,开发者可以有效地管理和查询数据,但也需要更多的手动管理。而Room作为SQLite的一个高级抽象,提供了更高层次的数据库访问和编译时检查,使得数据库操作更加方便和安全。

除了关系型数据库,还有其他的数据存储选项,如SharedPreferences和文件存储。这些选项适用于存储简单的键值对数据或多媒体文件,但在处理复杂数据结构和查询时可能显得不够灵活。

在选择数据存储方案时,开发者还需要考虑数据安全性和隐私保护。使用数据加密、内部存储和Android Keystore等方法,可以有效地保护用户数据免受恶意访问。同时,还应该注意数据存储的性能问题,避免频繁的数据库操作或文件IO影响应用的性能。

综上所述,数据存储是Android应用开发中不可忽视的一部分。选择合适的数据存储选项需要综合考虑应用的需求、性能要求和数据安全性。通过深入了解不同的数据存储选项,开发者可以在设计和开发过程中做出明智的决策,以确保应用的数据安全和性能达到最佳状态。

  • 使用ItemDecoration自定义分割线、边距等视觉效果,以增强界面的美观性。
  • 利用DiffUtil进行数据更新,避免不必要的刷新,提高数据更新的效率。
  • 添加动画效果以增加用户体验,但要注意不要过度使用,以免影响性能。

鼓励创新和优化

RecyclerView是一个强大的工具,可以满足各种不同的列表界面需求。我们鼓励开发者在设计列表界面时充分发挥创意,创造出与众不同的用户体验。同时,优化性能也是至关重要的一环,通过合理的布局设计、数据更新策略和异步加载等手段,确保列表界面在性能和用户体验上达到最佳状态。

总之,RecyclerView作为Android开发中不可或缺的一部分,将持续为我们提供强大的功能和灵活性。通过合理的应用和不断的优化,我们可以构建出功能强大、性能卓越的列表界面,为用户带来出色的移动应用体验。

11. 参考资料

在本文中,我们涵盖了使用RecyclerView构建灵活的列表界面的各个方面。以下是一些相关的参考资料和资源,供您进一步深入学习和探索:

  1. RecyclerView 官方文档
  2. Android Developer 官方培训课程 - 使用 RecyclerView
  3. RecyclerView vs ListView - 选择正确的列表控件
  4. 使用 RecyclerView 构建复杂列表
  5. Android RecyclerView 教程

这些资源将帮助您更深入地理解和应用RecyclerView在Android应用中的各种功能和优势。通过学习和实践,您可以成为一个更加熟练和有创意的Android开发者,构建出优雅和高性能的列表界面。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/81460.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot-mybatis的增删改查

目录 一、准备工作 二、常用配置 三、尝试 四、增删改查 1、增加 2、删除 3、修改 4、查询 五、XML的映射方法 一、准备工作 实施前的准备工作&#xff1a; 准备数据库表 创建一个新的springboot工程&#xff0c;选择引入对应的起步依赖&#xff08;mybatis、mysql驱动…

Flowable-网关-事件网关

目录 定义图形标记XML内容使用示例视频教程 定义 通常网关根据连线条件来决定后继路径&#xff0c;但事件网关不同&#xff0c;它提供了根据事件做选择的方式。 事件网关的每个外出顺序流都需要连接至一个捕获中间事件。当流程执行到达事件网关时&#xff0c;网关类 似处于等待…

【阻止IE强制跳转到Edge浏览器】

由于微软开始限制用户使用Internet Explorer浏览网站&#xff0c;IE浏览器打开一些网页时会自动跳转到新版Edge浏览器&#xff0c;那应该怎么禁止跳转呢&#xff1f; 1、点击电脑左下角的“搜索框”或者按一下windows键。 2、输入“internet”&#xff0c;点击【Internet选项…

Python Opencv实践 - 在图像上绘制图形

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png") print(img.shape)plt.imshow(img[:,:,::-1])#画直线 #cv.line(img,start,end,color,thickness) #参考资料&#xff1a;https://blog.csdn.ne…

百度智能云“千帆大模型平台”最新升级:接入Llama 2等33个模型!

今年3月&#xff0c;百度智能云推出“千帆大模型平台”。作为全球首个一站式的企业级大模型平台&#xff0c;千帆不但提供包括文心一言在内的大模型服务及第三方大模型服务&#xff0c;还提供大模型开发和应用的整套工具链&#xff0c;能够帮助企业解决大模型开发和应用过程中的…

04-2_Qt 5.9 C++开发指南_SpinBox使用

文章目录 1. SpinBox简介2. SpinBox使用2.1 可视化UI设计2.2 widget.h2.3 widget.cpp 1. SpinBox简介 QSpinBox 用于整数的显示和输入&#xff0c;一般显示十进制数&#xff0c;也可以显示二进制、十六进制的数&#xff0c;而且可以在显示框中增加前缀或后缀。 QDoubleSpinBox…

stl_list类(使用+实现)(C++)

list 一、list-简单介绍二、list的常用接口1.常见构造2.iterator的使用3.Capacity和Element access4.Modifiers5.list的迭代器失效 三、list实现四、vector 和 list 对比五、迭代器1.迭代器的实现2.迭代器的分类&#xff08;按照功能分类&#xff09;3.反向迭代器(1)、包装逻辑…

嵌入式开发学习(STC51-9-led点阵)

内容 点亮一个点&#xff1b; 显示数字&#xff1b; 显示图像&#xff1b; LED点阵简介 LED 点阵是由发光二极管排列组成的显示器件 通常应用较多的是8 * 8点阵&#xff0c;然后使用多个8 * 8点阵可组成不同分辨率的LED点阵显示屏&#xff0c;比如16 * 16点阵可以使用4个8 *…

【Linux命令详解 | less命令】Linux系统中用于分页显示文件内容的命令

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 分页显示文件内容2. 搜索关键词3. 显示行号4. 显示特定内容5. 只显示匹配行6. 忽略大小写搜索7. 输出到文件8. 动态查看文件增长9. 开启对二进制文件的支持10. 显示控制字符11. 忽略键盘输入12. 显示百分比进度条…

001-Spring boot 启动内置Web容器分析

目录 代码入口上下文容器 加载web容器 代码入口 上下文容器 SpringApplication.run(App.class); //追踪下去发现 context createApplicationContext();createApplicationContext()&#xff1a; return this.applicationContextFactory.create(this.webApplicationType);这里…

python 封装sql 增删改查连接MySQL

select * from Teacher limit 10 连接字符串配置MysqlConfig.py class MysqlConfig:HOST 192.168.56.210PORT 3306USER rootPASSWORD 1qaz0987654321DBStudentDBCHARSET utf8封装增删改查MysqlConnection.py Author: tkhywang 2810248865qq.com Date: 2023-06-19 15:44:48 Las…

使用MIT Kerberos Ticket Manager在windows下浏览器访问hadoop页面

Author : Spinach | GHB Link : http://blog.csdn.net/bocai8058文章目录 前言准备配置说明安装Firefox浏览器安装MIT Kerberos Ticket Manager客户端配置krb5.ini文件配置MIT Kerberos Ticket Manager客户端配置Firefox浏览器代理参数 访问WebUI 前言 kerberos是一种计算机…

linux 查看磁盘大小 内存 目录下各目录大小

查看当前服务器挂在的磁盘大小及已使用、可使用、使用占比、磁盘对应的目录等 df -TH 查看当前目录下 各子目录或文件的大小&#xff1a;右边是目录或文件名&#xff0c;左边是占用的大小 du -sh * 使用 rm命令删除目录或文件&#xff1a;删了数据找不回来&#xff0c;&#x…

【二叉树】105. 从前序与中序遍历序列构造二叉树

链接: 105. 从前序与中序遍历序列构造二叉树 先序 能够确定谁是根 中序 知道根之后&#xff0c;能够确定左子树和右子树的范围 例子 根据先序的性质&#xff08;根左右&#xff09;&#xff0c;能够确定根&#xff0c;我们就能够从总序中找出根节点&#xff08;rooti所在…

MyBatis简介及环境配置

文章目录 一、什么是MyBatis二、MyBatis开发环境配置1.创建数据库表2.添加MyBatis框架支持3.配置连接字符串和MyBatis4.添加业务代码流程 一、什么是MyBatis MyBatis是一种持久层框架&#xff0c;也是一种ORM框架&#xff08;Object Relational Mapping即对象关系映射&#xf…

C语言学习笔记 使用vscode外部console出现闪退-12

前言 在使用vscode的外部console时&#xff0c;会出现闪退现象&#xff0c;这是因为程序运行结束后&#xff0c;系统自动退出了终端&#xff08;终端机制决定的&#xff09;。我们可以在C程序结束后&#xff0c;使用system函数来暂停DOS终端系统&#xff0c;这样就可以完整地看…

RS485实验

RS485实验 介绍 RS485采用差分信号进行传输&#xff0c;半双工通信。RS485是一个总线&#xff0c;在同一总线上最多可以挂接32个节点。通信流程简单理解为默认为接收状态&#xff0c;发送数据时切换为发送状态&#xff0c;数据发送完毕后切换为接收状态。发送和接收分别由一个…

算法与数据结构-哈希表

文章目录 什么是散列表散列函数的设计原则散列冲突的解决办法1. 开放寻址法2. 链表法 什么是散列表 散列表用的是数组支持按照下标随机访问数据的特性&#xff0c;所以散列表其实就是数组的一种扩展&#xff0c;由数组演化而来。可以说&#xff0c;如果没有数组&#xff0c;就…

AndroidStudio通过Profiler查找内存泄漏

Fragment内存泄漏&#xff1a; AndroidStudio --> Profiler --> 勾选 show nearest Gc root only&#xff0c;然后查看非weakreference的引用&#xff08;weakreference是不会导致内存泄漏的&#xff09;&#xff0c;往下就能找自己项目里写的代码&#xff0c;一般此处…

SpringBoot MDC全局链路解决方案

需求 在访问量较大的分布式系统中&#xff0c;时时刻刻在打印着巨量的日志&#xff0c;当我们需要排查问题时&#xff0c;需要从巨量的日志信息中找到本次排查内容的日志是相对复杂的&#xff0c;那么&#xff0c;如何才能使日志看起来逻辑清晰呢&#xff1f;如果每一次请求都…