Kotlin Compose 与传统 Android UI 开发对比
在移动应用开发领域,Android 开发一直是技术演进的前沿阵地,而 UI 开发作为用户与应用交互的核心环节,其技术体系的变革更是备受瞩目。
技术演进背景
Android UI 开发体系发展脉络
原生 View 体系阶段
在早期的 Android 开发中,原生 View 体系占据了主导地位。开发者通过继承 View 类并重写其方法来自定义控件,这种基于面向对象的开发模式要求开发者对 View 的绘制、事件处理等机制有深入理解。每个自定义控件都成为一个独立的类,开发者需要处理大量的细节,如测量、布局和绘制过程,这使得开发过程较为复杂且容易出错。
XML 布局文件与 Java/Kotlin 代码的分离是这一阶段的典型特征。开发者在 XML 文件中定义界面布局,包括控件的类型、属性和层次结构。然后在 Java 或 Kotlin 代码中通过 findViewById 方法获取控件实例,进而设置事件监听器、更新控件状态等。这种 XML+Java/Kotlin 混合开发模式虽然在一定程度上实现了界面与逻辑的分离,但在实际开发中也存在诸多问题。例如,当布局变得复杂时,XML 文件容易变得冗长且难以维护;代码与布局之间的关联依赖于控件的 ID,一旦 ID 发生冲突或更改,就可能导致运行时错误。
传统开发代码示例 :
布局文件(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><Buttonandroid:id="@+id/btnClick"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Click Me"/><TextViewandroid:id="@+id/tvCount"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Count: 0"/></LinearLayout>
代码文件(MainActivity.java)
public class MainActivity extends AppCompatActivity {private int count = 0;private TextView tvCount;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tvCount = findViewById(R.id.tvCount);Button btnClick = findViewById(R.id.btnClick);btnClick.setOnClickListener(v -> {count++;tvCount.setText("Count: " + count);});}
}
现代声明式 UI 框架的兴起背景
随着移动应用的不断发展,用户对应用的界面交互要求越来越高,传统的 UI 开发模式在应对复杂的界面和频繁的状态变化时逐渐暴露出效率低下的问题。开发一个复杂的界面,需要在 XML 中定义复杂的布局层次,然后在代码中手动更新 UI 组件的状态,这不仅增加了开发的工作量,也使得代码变得难以维护。
在这种背景下,声明式 UI 框架逐渐兴起。声明式 UI 的核心思想是让开发者直接描述界面的最终状态,而不是手动控制界面的变化过程。这种开发模式使得 UI 的构建更加直观和高效,能够显著减少代码量并降低开发难度。同时,声明式 UI 框架通常具备更好的性能优化机制,能够自动处理界面的更新和重绘,从而提高应用的运行效率。
Compose 技术定位
Kotlin Compose 是 Google 推出的一种现代声明式 UI 框架,它基于 Kotlin 语言,旨在彻底改变 Android UI 开发的方式。Compose 被定位为 Google 官方的 Modern Toolkit,是 Android UI 开发的未来方向。它不仅仅是一个简单的 UI 框架,而是一个集成了众多先进技术和理念的开发工具包,能够为开发者提供更高效、更灵活、更强大的 UI 开发体验。
Compose 的出现,使得 Android 开发者可以摆脱传统 XML 布局和复杂的 View 操作,直接使用 Kotlin 代码以声明式的方式构建 UI。它将界面、逻辑和数据紧密地结合在一起,通过函数式编程的方式实现界面的动态更新,极大地简化了开发流程并提高了开发效率。同时,Compose 还具备跨平台的潜力,能够在多个平台上运行,为开发者提供了更广阔的应用场景。
Compose 开发代码示例 :
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dpclass MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {ContentView()}}
}@Composable
fun ContentView() {var count by remember { mutableStateOf(0) }Column(modifier = Modifier.padding(16.dp)) {Button(onClick = { count++ }) {Text(text = "Click Me")}Text(text = "Count: $count")}
}
Compose 核心技术特征
声明式编程范式
UI=ƒ(State) 数学表达
在 Kotlin Compose 中,UI 被视为一个函数的输出,而这个函数的输入是应用的状态。即 UI = f(state),这一数学表达式直观地体现了声明式 UI 的核心思想。开发者只需关注如何根据当前的状态生成对应的 UI,而无需手动控制 UI 的更新过程。当应用的状态发生变化时,Compose 会自动重新执行相关的函数,生成新的 UI 并将其渲染到屏幕上。
例如,一个简单的计数器应用,其状态是一个整数计数值。在 Compose 中,开发者可以定义一个函数,该函数根据计数值的状态构建一个显示计数值和两个按钮(增加和减少计数)的界面。当用户点击按钮导致计数值改变时,Compose 会自动检测到状态的变化,并重新执行界面构建函数,更新显示的计数值。
Compose 中 UI=ƒ(State) 代码示例 :
@Composable
fun CounterView(count: Int, onIncrement: () -> Unit, onDecrement: () -> Unit) {Column {Text(text = "Count: $count")Row {Button(onClick = onDecrement) {Text(text = "-")}Button(onClick = onIncrement) {Text(text = "+")}}}
}// 使用示例
var count by remember { mutableStateOf(0) }
CounterView(count = count,onIncrement = { count++ },onDecrement = { count-- }
)
状态驱动更新机制
Compose 的状态驱动更新机制是其声明式编程范式的核心实现之一。在 Compose 中,状态是通过特殊的变量或对象来表示的,这些状态可以是简单的基本数据类型,也可以是复杂的对象。当状态发生变化时,Compose 会自动跟踪这些变化,并重新执行与该状态相关的 UI 构建函数,从而实现界面的更新。
Compose 提供了多种方式来定义和管理状态。例如,可以使用 mutableStateOf 函数来创建一个可变的状态对象,该对象可以存储任意类型的值,并且当其值发生变化时会通知 Compose 进行界面更新。此外,Compose 还支持将状态作为参数传递给可组合函数,使得状态可以在不同的界面组件之间共享和传递。
Compose 状态驱动更新代码示例 :
@Composable
fun Greeting(name: String) {var isSelected by remember { mutableStateOf(false) }Surface(color = if (isSelected) Blue else White,modifier = Modifier.padding(8.dp)) {Text(text = "Hello, $name!",modifier = Modifier.padding(16.dp).clickable { isSelected = !isSelected })}
}
布局系统差异
XML 布局的优缺点分析
XML 布局作为传统 Android UI 开发的主要布局方式,具有一定的优缺点。
优点方面,XML 布局实现了界面与逻辑的分离,开发者可以在 XML 文件中专注于界面的设计,而在 Java/Kotlin 代码中处理业务逻辑。这有助于团队中的不同成员(如 UI 设计师和开发人员)并行工作。XML 布局还提供了丰富的布局类型和属性,能够满足各种复杂的界面布局需求,如线性布局、相对布局、约束布局等。此外,Android Studio 提供了强大的 XML 布局设计工具,如拖拽式布局编辑器、预览功能等,方便开发者进行可视化开发。
然而,XML 布局也存在一些缺点。随着界面复杂度的增加,XML 文件容易变得臃肿和难以维护。开发者需要在 XML 文件中手动调整控件的层次结构和属性,这可能导致布局效率低下。而且,XML 布局与代码的交互相对繁琐,需要通过 findViewById 等方法进行关联,容易出现控件 ID 冲突或找不到控件等问题。此外,XML 布局的热重载能力有限,在开发过程中修改布局文件后需要重新运行应用才能看到效果,这影响了开发效率。
传统 XML 布局代码示例 :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/titleTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Welcome to My App"app:layout_constraintTop_toTopOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"/><Buttonandroid:id="@+id/loginButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Login"app:layout_constraintTop_toBottomOf="@id/titleTextView"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"/></androidx.constraintlayout.widget.ConstraintLayout>
Compose 布局模型:布局修饰符与测量逻辑
Compose 的布局模型与传统的 XML 布局有显著不同。在 Compose 中,布局是通过可组合函数和布局修饰符来实现的。可组合函数定义了界面的结构和内容,而布局修饰符则用于控制界面组件的布局属性,如大小、位置、对齐方式等。
Compose 的布局修饰符提供了一种灵活且直观的方式来定制界面组件的布局。开发者可以将多个修饰符组合在一起,以实现复杂多样的布局效果。例如,可以通过 Modifier.padding() 修饰符为组件添加内边距,通过 Modifier.size() 修饰符设置组件的大小,通过 Modifier.align() 修饰符指定组件的对齐方式等。
Compose 的测量逻辑遵循一个清晰的流程:测量子项 → 确定自身尺寸 → 放置子项。每个可组合函数在布局过程中都会经历这三个步骤。首先,它会测量其子组件所需的尺寸,然后根据自身的布局规则和修饰符确定自己的尺寸,最后将子组件放置在合适的位置。这种测量逻辑使得 Compose 能够精确地计算每个界面组件的布局,确保界面的正确性和性能。
Compose 布局代码示例 :
@Composable
fun MyAppTheme(darkTheme: Boolean = isSystemInDarkTheme(),content: @Composable () -> Unit
) {val colors = if (darkTheme) {DarkColors} else {LightColors}MaterialTheme(colors = colors,typography = Typography,shapes = Shapes,content = content)
}@Composable
fun MyScreen() {MyAppTheme {Surface(modifier = Modifier.fillMaxSize()) {Column(modifier = Modifier.padding(16.dp).fillMaxWidth(),horizontalAlignment = Alignment.CenterHorizontally) {Text(text = "Welcome to My App",style = Typography.h5,modifier = Modifier.padding(bottom = 16.dp))Button(onClick = { /* Handle login */ },modifier = Modifier.align(Alignment.CenterHorizontally)) {Text(text = "Login")}}}}
}
核心差异深度解析
状态管理机制对比
传统模式的 findViewById 与数据绑定
在传统的 Android UI 开发中,状态管理主要依赖于 findViewById 方法和数据绑定技术。开发者通过 findViewById 获取 UI 组件的实例,然后在代码中手动更新组件的状态,如设置文本、图片、可见性等。这种方式在简单的界面中尚可接受,但在复杂的界面中,随着状态的增多和交互的复杂化,手动更新 UI 组件的状态变得越来越困难且容易出错。
数据绑定技术的出现一定程度上改善了这种情况。通过数据绑定,开发者可以在 XML 布局文件中直接引用数据模型中的字段,从而实现界面与数据的双向绑定。当数据模型中的数据发生变化时,界面会自动更新;反之,当用户通过界面交互修改了数据时,数据模型也会自动更新。然而,数据绑定的配置相对复杂,需要定义数据模型、绑定适配器等,并且在运行时会增加一定的性能开销。
传统数据绑定代码示例 :
布局文件(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<layoutxmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="user"type="com.example.data.User"/></data><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.name}"android:textSize="18sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{user.email}"android:textSize="14sp"/></LinearLayout>
</layout>
代码文件(MainActivity.java)
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);User user = new User("John Doe", "john@example.com");binding.setUser(user);}
}
Compose 状态提升与单向数据流
Compose 采用了一种不同的状态管理方式,即状态提升与单向数据流。在 Compose 中,状态通常被定义在尽可能高的层级,然后通过参数传递的方式将状态和事件处理函数传递给需要的子组件。这种状态提升的做法使得状态的管理和更新更加集中和可控。
单向数据流是 Compose 状态管理的核心原则之一。状态的变化只能由特定的事件触发,这些事件通常发生在 UI 组件中,如用户点击按钮、输入文本等。当事件发生时,事件处理函数会更新状态,然后 Compose 会根据新的状态重新渲染界面。数据的流动是单向的,从状态源出发,经过事件处理和状态更新,最终影响界面的显示。这种单向数据流机制使得数据的流向清晰明确,减少了因数据循环依赖或状态不一致而导致的问题。
Compose 状态管理代码示例 :
@Composable
fun UserProfile(initialName: String,initialEmail: String
) {var name by remember { mutableStateOf(initialName) }var email by remember { mutableStateOf(initialEmail) }Column(modifier = Modifier.padding(16.dp)) {Text(text = "Name: $name")Text(text = "Email: $email")OutlinedTextField(value = name,onValueChange = { name = it },label = { Text("Name") },modifier = Modifier.fillMaxWidth())OutlinedTextField(value = email,onValueChange = { email = it },label = { Text("Email") },modifier = Modifier.fillMaxWidth())}
}
性能优化对比
传统 View 的布局层级优化
在传统的 Android 开发中,布局层级的优化是提高 UI 性能的关键之一。复杂的布局层级会导致过多的测量和绘制操作,从而增加 CPU 和内存的消耗,影响应用的流畅性。为了优化布局层级,开发者通常会采用合并布局、减少嵌套等方法。例如,使用 ConstraintLayout 替代嵌套的 LinearLayout 或 RelativeLayout,以减少布局的嵌套深度,从而降低测量和布局的开销。
此外,还可以通过移除不必要的 View 组件、使用更高效的布局类型等方式来优化布局性能。例如,避免使用过多的 FrameLayout 来实现简单的叠加效果,而是使用更合适的布局方式;对于不需要响应用户交互的 View,可以设置 android:layout_width 和 android:layout_height 为 wrap_content 或 match_parent,并去掉不必要的背景等,以减少绘制的复杂度。
传统布局层级优化前代码示例 :
<LinearLayoutxmlns:android="ht
相关文章:
Kotlin Compose 与传统 Android UI 开发对比
在移动应用开发领域,Android 开发一直是技术演进的前沿阵地,而 UI 开发作为用户与应用交互的核心环节,其技术体系的变革更是备受瞩目。 技术演进背景 Android UI 开发体系发展脉络 原生 View 体系阶段 在早期的 Android 开发中,原生 View 体系占据了主导地位。开发者通…...
docker-compose——安装redis
文章目录 一、编写docker-compose.yaml文件二、编写redis.conf文件三、启动docker-compose 一、编写docker-compose.yaml文件 version: 3.3 services:redis:image: redis:latestcontainer_name: redisrestart: alwaysports:- 6379:6379volumes:- ./redis/data:/data- ./redis/…...
MFC 调用海康相机进行软触发
初始化相机类文件 #pragma once #include "MvCameraControl.h" class CMvCamera { public:CMvCamera();~CMvCamera();//初始化相机int InitCamera();int SaveCurrentImage(CString filePath);//关闭相机void CloseCamera();//设置int SetEnumValue(IN const char* s…...
第二章 变量和运算符
主要内容 关键字和标识符变量和常量八大基本数据类型Scanner键盘输入基本数据类型的类型转换算术运算符赋值运算符扩展赋值运算符比较运算符逻辑运算符三目运算符运算符的优先级别 学习目标 知识点要求关键字和标识符理解变量和常量掌握八大基本数据类型掌握Scanner键盘输入…...
【starrocks】StarRocks 常见 HTTP 操作与导入错误排查指南
文章目录 一、Stream Load:通过 HTTP 导入数据二、导入状态查询三、取消导入任务四、节点状态监控查看所有 Backend 状态:查看所有 Frontend 状态: 五、导入失败的排查方式1. 查询导入任务状态2. 下载详细错误日志3. 查看 FE/BE 节点日志FE 日…...
网络协议分析 实验七 FTP、HTTP、DHCP
文章目录 实验7.1 FTP协议练习二 使用浏览器登入FTP练习三 在窗口模式下,上传/下传数据文件实验7.2 HTTP(Hyper Text Transfer Protocol)练习二 页面提交练习三 访问比较复杂的主页实验7.3 DHCP(Dynamic Host Configuration Protocol) 实验7.1 FTP协议 dir LIST&…...
ET ProcessInnerSender类(实体) 分析
ProcessInnerSender 作用是进程内部发送Actor消息 字段 TIMEOUT_TIME 超时时间RpcId 用来累加requestCallback 存储RPC的回调事件list 用来获取MessageQueue中的Actor消息 方法 Awake 初始化在MessageQueue中注册待处理的消息队列Destroy 移除在MessageQueue中的消息队列U…...
远程连接工具
绿色轻便ToDesk https://www.todesk.com/download.html 向日葵 https://sunlogin.oray.com/download...
MySQL库级管理:数据库管理与存储引擎剖析
引言 各位数据库爱好者们好!今天我们要深入探讨MySQL数据库的基本操作,这是每位开发者必须掌握的"内功心法" 💪。无论你是刚接触MySQL的小白,还是需要复习基础的老手,这篇教程都将带你系统学习数据库的核心…...
MongoDB 的核心概念(文档、集合、数据库、BSON)是什么?
MongoDB 是一个面向文档的数据库,它的核心概念与传统的关系型数据库(RDBMS)有所不同。以下是它的四个主要核心概念: 文档 (Document) 定义: 文档是 MongoDB 中的基本数据单元。它类似于关系型数据库中的一行记录&#…...
占位符读取标准输入缓冲区规则
1、如果标准输入缓冲区中的前若干个字符都是空白字符,%s,%d,%f都能直接跳过并且从第一个非空白字符开始读取,但%c不能,而是直接读取。 2、%s遇到空白字符时停止,不会读取遇到的空白字符。 3、%d遇到非数字…...
使用Docker部署MongoDB
使用Docker部署MongoDB 使用Docker部署MongoDB是一种快速、便捷的方式,以下是详细步骤: 1. 基本部署 拉取MongoDB镜像 docker pull mongo:latest运行MongoDB容器(最简单方式) docker run --name mongodb -d -p 27017:27017 m…...
如何通过命令提示符(CMD)检查虚拟化是否已启用
想确认 Windows 11 或 10 电脑或笔记本上的虚拟化是否已启用,可以使用命令提示符或 PowerShell 中的 systeminfo 命令。之前已经介绍过使用图形界面的检查方法。在大多数现代系统中,虚拟化默认在 BIOS 中启用,但我们无需打开 BIOS/UEFI 固件菜单即可确认这一点。 虚拟化是一…...
【氮化镓】AlGaN合金中成分相关的辐射响应
2025年,美国宾夕法尼亚州立大学Miaomiao Jin等人基于分子动力学模拟方法,研究了AlGaN合金中成分依赖的辐射响应。研究结果表明,AlGaN合金的辐射损伤特性与铝含量密切相关:随铝含量增加,单次碰撞事件产生的缺陷减少,但由于累积效应,富铝系统更易形成扩展间隙缺陷簇,导致…...
『 测试 』软件测试全流程与Bug管理核心要点解析
文章目录 1 软件测试生命周期2 Bug2.1 Bug 的概念2.2 提出清晰的 Bug2.3 Bug 级别2.4 Bug 的生命周期2.5 作为测试人员与开发人员发生冲突怎么办 1 软件测试生命周期 软件测试贯穿于软件的整个生命周期; 需求分析 测试前需要对需求进行分析, 分析通常站在三个角度去考虑, 即用…...
【springcloud学习(dalston.sr1)】使用Feign实现接口调用(八)
该系列项目整体介绍及源代码请参照前面写的一篇文章【springcloud学习(dalston.sr1)】项目整体介绍(含源代码)(一) (一)Feign的理解 前面文章【springcloud学习(dalston.sr1)】服务消费者通过restTemplat…...
嵌入式Linux Qt开发:2、Qt creator简单配置、Qt Designer使用以及信号槽机制使用
一、前言 Qt creator比较轻量,而且是Qt自带的IDE,基本可以开箱即用,个人使用起来感觉还是比较舒服的,并且其自带的FakeVim也可以做一些Vim的配置,其主界面可以简单配置显示很多的窗口,让开发更加顺畅。 Q…...
【Vue 3 + Vue Router 4】如何正确重置路由实例(resetRouter)——避免“VueRouter is not defined”错误
在使用 Vue 3 和 Vue Router 4 开发中大型 SPA 应用时,我们经常会遇到需要动态添加或删除路由的场景。尤其是在权限控制和用户登出后重置路由的需求中,正确地实现 resetRouter 非常关键。 然而,许多开发者在迁移或初始化项目时,会…...
企业内部通讯,企业级即时通讯软件选择
企业内部的沟通往往涉及大量敏感信息,如商业机密、财务数据、客户信息等。BeeWorks IM即时通讯平台采用全私有化部署,企业可以将服务器部署在自己的数据中心或私有云环境中,确保所有数据的存储和传输都在企业可控的网络内完成。这种部署方式从…...
300. 最长递增子序列
理解最长递增子序列(LIS)是解决该问题的关键。子序列是从给定数组中按顺序选取的元素序列,例如数组 [1, 2, 3, 4, 5] 的子序列可以是 [2, 3, 4]。需要注意的是,子序列的元素在原数组中不一定是连续的。因此,最长递增子…...
MongoDB入门
1.MongoDB 基本概念详解 2.MongoDB 快速实战 3.MongoDB 核心操作与原理详解 Mongo 是 humongous 的中间部分,在英文里是“巨大无比”的意思。所以 MongoDB 可以翻译 成“巨大无比的数据库”,更优雅的叫法是“海量数据库”。Mongodb是一款非关系型数据库…...
MySQL基础原理
目录 一、MySQL架构 1、四层架构 2、MySQL运行机制 二、MySQL存储引擎 1、不同存储引擎对比 2、InnoDB存储结构 2.1 内存结构 2.2 磁盘结构 3、日志先行策略 3.1 核心思想 3.2 关键组件与流程 3.3 数据安全保证 3.3.1 崩溃恢复 3.3.2 持久性保障 一、MySQL架构 …...
Python刷题练习
文章目录 1.寻找相同字串2.密钥格式化3.五键键盘的输出4.单词重量5.输出指定字母在字符串的中的索引6.污染水域7.九宫格按键输入8.任务最优调度9.高效的任务规划 1.寻找相同字串 题目描述: 给你两个字符串t和p,要求从t中找到一个和p相同的连续子串,并输…...
基于GPUGEEK 平台进行深度学习
一、平台简介 GPUGEEK 是一个专注于提供 GPU 算力租赁服务的平台,在人工智能与深度学习领域为用户搭建起便捷的算力桥梁。它整合了丰富多样的 GPU 资源,涵盖 RTX - 4090、RTX - 3090、A100 - PCIE 等多种型号,满足不同用户在模型训练、数据处…...
基于Matlab的非线性Newmark法用于计算结构动力响应
基于Matlab的非线性Newmark法用于计算结构动力响应,主要针对材料非线性或几何非线性问题。 1. Newmark法基本原理 Newmark法是一种隐式时间积分方法,通过预估-校正步骤更新位移、速度和加速度: 预测步: un1unΔtvn…...
Oracle — PL-SQL
介绍 Oracle PL/SQL是专为Oracle数据库设计的过程化编程语言,深度融合SQL语句与结构化编程逻辑,旨在高效处理复杂数据操作与业务规则。其核心特征为“块结构”,程序由声明、执行、异常处理三部分组成,支持模块化开发,显…...
第七节第二部分:接口的综合案例
案例分析 代码: Student类 package com.Interface_Demo;public class Student {private String name;private char sex;private double score;public Student() {}public Student(String name, char sex, double score) {this.name name;this.sex sex;this.scor…...
【AI古风美学渲染】:淡雅光影中的细腻呈现
“顶作AI”作为国内首个深度融合中文语义的生成式AI平台,以近百亿级参数的Lens跨模态模型为核心,开创了“自然语言即生产力”的创作模式。该平台突破传统工具对专业术语的依赖,用户仅需输入如“水墨风格的山间庭院,晨雾中若隐若现…...
JVM学习专题(二)内存模型深度剖析
目录 1.JVM结构体系 编辑 2.跨平台特性 3.JVM整体结构及内存模型 1.栈内存 1、栈帧: 1.局部变量表 2.操作数栈 3.动态链接 4.方法出口 2、创建对象 2.程序计数器: 3.方法区 4.堆 5.本地方法区 6.总结 1.JVM结构体系 JDK、JRE 和 JVM…...
Prometheus 的介绍与部署(入门)
一、什么是Prometheus; 1.介绍 Prometheus 是一个功能强大的监控工具,适用于各种环境。通过简单的安装和配置,可以快速实现对系统和服务的监控。无论是单机环境、容器化环境还是 Kubernetes 集群,Prometheus 都能提供灵活…...
JavaSwing之-JDialog
JavaSwing之-JDialog JDialog 是 Java Swing 中用于创建对话框窗口的容器类,继承自 Dialog 类(AWT),常用于显示临时信息、获取用户输入或执行模态操作。它是 javax.swing.JDialog 包中的类。 与 JFrame 不同的是,JDia…...
配置Nginx解决http host头攻击漏洞【详细步骤】
前言 大概内容: 安全系统渗透测试出host头攻击漏洞,下面是解决步骤,本人已测过无问题。 server_name aaabbb.com; if ($http_Host !~* ^127.0.0.1|aaabbb.com|localhost$){return 403;}...
如何用Redis实现分布式锁?RedLock算法的核心思想?Redisson的看门狗机制原理?
一、Redis分布式锁基础实现 public class RedisDistributedLock {private JedisPool jedisPool;private String lockKey;private String clientId;private int expireTime 30; // 默认30秒public boolean tryLock() {try (Jedis jedis jedisPool.getResource()) {// NX表示不…...
LeetCode 热题 100 35.搜索插入位置
目录 题目: 题目描述: 题目链接: 思路: 核心思路: 思路详解: 代码: Java代码: 题目: 题目描述: 题目链接: 35. 搜索插入位置 - 力扣&…...
电流检测放大器的优质选择XBLW-INA180/INA181
前言: 在当前复杂的国际贸易环境下,关税的增加使得电子元器件的采购成本不断攀升,电子制造企业面临着巨大的成本压力。为了有效应对这一挑战,实现国产化替代已成为众多企业降低生产成本、保障供应链稳定的关键战略。对此芯伯乐推出…...
序列化和反序列化:从理论到实践的全方位指南
你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…...
Leetcode (力扣)做题记录 hot100(62,64,287,108)
力扣第62题:不同路径 62. 不同路径 - 力扣(LeetCode) class Solution {public int uniquePaths(int m, int n) {int[][] array new int[m][n];for(int i 0;i<n;i){array[0][i] 1;}for(int i 0;i<m;i){array[i][0] 1;}for(int i …...
【Linux】shell内置命令fg,bg和jobs
Shell 内置命令 fg(foreground 的缩写)。它用于将后台挂起的任务恢复到前台运行。 例如: 假设你运行了一个耗时的 SVN 操作(如 svn update 或 svn checkout)。按下 CtrlZ 将该进程挂起到后台。输入 fg…...
鸿蒙OSUniApp 制作动态加载的瀑布流布局#三方框架 #Uniapp
使用 UniApp 制作动态加载的瀑布流布局 前言 最近在开发一个小程序项目时,遇到了需要实现瀑布流布局的需求。众所周知,瀑布流布局在展示不规则尺寸内容(如图片、商品卡片等)时非常美观和实用。但在实际开发过程中,我…...
通用软件项目技术报告 - 导读II
现在,我们正式进入报告的第三个主要领域:3. 领域三:核心业务逻辑与算法实现。 连接: 我们已经讨论了如何存储数据(领域一)和如何设计 API 让外部或内部服务可以访问这些数据或触发操作(领域二)。现在,我们将深入应用程序的“心脏”——实际执行业务规则、进行计算和(…...
新能源汽车三电质量护盾:蓝光三维扫描技术显身手
在绿色低碳的潮流下,新能源汽车行业快速发展,车企们纷纷加速电气化转型。由于电动汽车动力系统构造与内燃机车辆的构造有很大不同,制造商及其供应商必须加快工程研发设计及生产,而这对质量保证过程提出了新的挑战。 对于新能源汽…...
针对已训练好的YOLOv8模型的优化策略
以下是针对已训练好的YOLOv8模型的优化策略,结合模型微调、结构改进、训练策略调整等方法,可进一步提升检测性能或适应特定场景需求: 一、超参数调优 学习率动态调整 初始学习率(lr0):若模型收敛后仍有优化…...
AI 产业化浪潮:从生成智能到星载计算,中国如何重塑全球竞争格局
2025 年的科技版图上,人工智能正经历着从技术奇点到产业爆点的历史性跨越。当生成式 AI 突破实验室围墙走进千行百业,当智能体开始在数字世界自主决策,当卫星搭载的大模型在太空展开计算,一场由技术创新驱动的产业革命正在重塑全球…...
Python如何解决中文乱码
Python文件头部声明 # -*- coding: utf-8 -*- # 必须放在文件第一行或第二行中文字符串定义方式 # Python 3 chinese_str "中文" # 默认就是Unicode# Python 2 chinese_str u"中文" # 必须加u前缀字符串编码转换黄金法则 # 解码:字节串 …...
android studio导入项目
如果 gradle-8.0-bin.zip 没有下载成功 可以点击进入这个网站:https://services.gradle.org/distributions/ 找到和自己本版相同的gradle-8.0-bin.zip文件找到自己版本进行下载; 如果下载依赖失败, 可以手动下载依赖编译过程中的jar https://repo.maven.apache.org/…...
Android Studio Meerkat与Gradle构建工具升级实战指南
简介 Android Studio Meerkat和Gradle构建工具的升级将带来显著的性能提升和开发体验优化。在Android生态快速演进的2025年,开发者亟需掌握这些新特性以提升工作效率。本指南将从零开始,详细讲解如何升级Android Studio和Gradle构建工具,配置新特性,并提供实际应用场景的代…...
TCP/IP参考模型详解:从理论架构到实战应用
一、参考模型基础概念与分类 计算机网络参考模型是为解决网络通信标准化问题而设计的逻辑框架。在众多模型中,TCP/IP参考模型以其高实用性和广泛应用,成为现代网络架构的基石。该模型采用分层设计思想,将复杂的网络通信功能划分为多个层次&am…...
【Linux网络】网络层
网络层 在复杂的网络环境中确定一个合适的路径 IP 协议 IPV4 点分十进制[0,255].[0,255].[0,255].[0,255]IPV6 IP地址目标网格目标主机 基本概念 主机:配有IP地址,但是不进行路由控制的设备;路由器:即配有IP地址,又能进行路由控制;节点:主机和路由器的统称。 两个问题 路…...
FastAPI + OpenAI 模型 的 GitHub 项目结构模板
FastAPI OpenAI 模型 的 GitHub 项目结构模板,适合用作大模型(如 GPT-4) API 服务的基础框架。该模板包括了基本的项目结构、配置、文档以及与 OpenAI API 的交互方式。 项目结构 fastapi-openai-api/ ├── app/ │ ├── __init__.p…...
基于EFISH-SCB-RK3576/SAIL-RK3576的无人快递柜控制器技术方案
国产化替代J1900的智能化升级方案 一、硬件架构设计 多模态感知模块 智能识别单元: 双MIPI-CSI接口接入4K摄像头,NPU加速包裹条码识别(速度>5件/秒,准确率>99.99%),支持破损检测&…...