React Native 项目实战 —— 记账本应用开发指南

React Native 项目实战 —— 记账本应用开发指南

  • 项目概述:本文将指导您使用 React Native 开发一个简单的记账本应用,帮助用户记录收入和支出。
  • 核心内容:我们将分析功能模块、设计接口、划分组件结构、管理数据流、实现页面跳转,并处理跨平台兼容性。
  • 适用人群:适合初学者和有一定经验的开发者,需具备 React Native 基础知识。
  • 技术栈:使用 React Navigation、React Native Paper、Context API 和 AsyncStorage。
项目简介

记账本应用是一个实用的移动应用,允许用户跟踪个人财务,包括添加交易、查看历史记录和分类管理。它是学习 React Native 的理想项目,涵盖了从 UI 设计到数据管理的多个开发环节。React Native 的跨平台特性使我们能够以单一代码库构建同时运行在 iOS 和 Android 上的应用。

功能模块与实现

您将学习如何将应用分解为模块(如认证、交易管理)、设计用户界面(如主屏幕、添加交易屏幕)、组织组件、管理状态、设置导航,并确保应用在不同平台上表现一致。以下是主要步骤:

  • 功能分析:定义用户登录、交易管理等模块。
  • 接口设计:使用 React Native Paper 创建直观界面。
  • 组件划分:构建可复用组件,如交易卡片。
  • 数据流:通过 Context API 和 AsyncStorage 管理交易数据。
  • 导航:使用 React Navigation 实现屏幕切换。
  • 跨平台:处理 iOS 和 Android 的差异。

React Native 是一个强大的跨平台移动应用开发框架,允许开发者使用 JavaScript 和 React 构建同时运行在 iOS 和 Android 上的应用。本文是 React Native 开发系列的第 8 篇,专注于通过一个实际项目——记账本应用,深入探索功能模块分析、接口设计、页面组件结构划分、数据流管理、页面跳转和跨平台兼容处理技巧。本文将提供详细的代码示例和最佳实践,帮助初学者和有经验的开发者掌握 React Native 的核心开发技能。目标是构建一个简单的记账本应用,用户可以记录收入和支出、查看交易历史并按类别管理交易。

1. 引言:记账本应用与 React Native

记账本应用是一个实用的移动应用,旨在帮助用户跟踪个人财务。它涵盖了 React Native 开发的多个关键方面,包括用户界面设计、状态管理、导航和跨平台兼容性。通过这个项目,您将学习如何将复杂需求分解为可管理的模块,设计直观的界面,组织组件结构,管理数据流,并确保应用在 iOS 和 Android 上表现一致。

1.1 应用简介

记账本应用允许用户:

  • 记录交易:添加收入或支出交易,包括金额、日期、类别和描述。
  • 查看历史:浏览交易列表,支持按日期或类别过滤。
  • 管理类别:创建和编辑交易类别,如“餐饮”或“交通”。
  • 查看摘要:显示总收入和支出的概览。

为简化开发,本文将重点实现以下功能:

  • 用户登录(模拟认证)
  • 主屏幕,显示交易摘要和最近交易列表
  • 添加交易屏幕
  • 交易详情屏幕,支持编辑和删除

1.2 为什么选择 React Native?

React Native 的跨平台特性使其成为开发记账本应用的理想选择:

  • 单一代码库:一套代码同时支持 iOS 和 Android,减少开发和维护成本。
  • 组件化架构:React 的组件模型适合模块化开发,便于复用代码。
  • 丰富的生态系统:支持如 React Navigation 和 React Native Paper 的库,加速开发。
  • 接近原生性能:通过桥接调用原生组件,确保流畅的用户体验。

1.3 技术栈

我们将使用以下工具和技术:

工具/库用途
React Navigation页面导航
React Native PaperUI 组件和 Material Design 风格
Context API状态管理
AsyncStorage本地数据持久化

2. 项目设置

在开始开发之前,需要设置 React Native 项目环境。以下是初始化项目的步骤:

2.1 初始化项目

运行以下命令创建新项目:

npx react-native init BookkeepingApp
cd BookkeepingApp

2.2 安装依赖

安装必要的库:

npm install @react-navigation/native @react-navigation/stack react-native-paper @react-native-async-storage/async-storage

对于 iOS,还需安装 CocoaPods 依赖:

cd ios && pod install && cd ..

2.3 项目结构

建议采用以下目录结构:

BookkeepingApp/
├── src/
│   ├── components/
│   ├── context/
│   ├── navigation/
│   ├── screens/
│   └── styles/
├── App.js
└── package.json

3. 功能模块分析

为了系统地开发应用,我们将功能分解为以下模块:

3.1 认证模块

  • 功能:用户登录和注册(本文模拟登录,无需真实后端)。
  • 需求
    • 登录屏幕:输入用户名和密码。
    • 注册屏幕:输入用户名、邮箱和密码。
    • 保存用户状态以保持登录。

3.2 交易管理模块

  • 功能:添加、编辑、删除和查看交易。
  • 需求
    • 添加交易:输入金额、日期、类别、描述和类型(收入/支出)。
    • 交易列表:显示所有交易,支持点击查看详情。
    • 交易详情:显示详细信息,支持编辑或删除。

3.3 分类管理模块

  • 功能:管理交易类别。
  • 需求
    • 默认类别:如“餐饮”、“交通”、“娱乐”。
    • 添加新类别:输入类别名称。
    • 编辑或删除类别。

3.4 报告模块

  • 功能:生成收入和支出摘要。
  • 需求
    • 显示总收入和支出。
    • 支持按日期或类别过滤。

为简化,本文将实现认证(模拟)、交易管理和基本报告功能。

4. 接口设计

用户界面是应用成功的关键。我们将使用 React Native Paper 提供 Material Design 风格的组件,确保界面美观且一致。

4.1 屏幕设计

以下是主要屏幕的布局:

  1. 登录屏幕

    • 标题:应用名称
    • 输入字段:用户名、密码
    • 按钮:登录、注册链接
  2. 主屏幕

    • 头部:显示总收入和支出摘要
    • 列表:最近交易
    • 浮动按钮:添加新交易
  3. 添加交易屏幕

    • 表单:金额、日期、类别(下拉菜单)、描述、收入/支出开关
    • 按钮:保存、取消
  4. 交易详情屏幕

    • 显示:交易详细信息
    • 按钮:编辑、删除、返回

4.2 设计原则

  • 简洁性:界面清晰,避免过多元素。
  • 一致性:使用 React Native Paper 的主题确保风格统一。
  • 可访问性:为按钮和输入字段添加 accessibilityLabel

5. 页面组件结构划分

React Native 的组件化开发要求我们为每个屏幕设计合理的组件层次结构。以下是主要屏幕的组件划分:

5.1 主屏幕

组件名称描述
Header显示应用名称和用户问候
SummaryCard显示总收入和支出
TransactionList使用 FlatList 显示最近交易
TransactionItem单个交易卡片,显示金额、类别等
FAB浮动动作按钮,跳转到添加交易屏幕

5.2 添加交易屏幕

组件名称描述
TransactionForm包含所有输入字段的表单
TextInput输入金额和描述
Picker选择类别
DatePicker选择日期
Switch切换收入/支出
Button保存或取消

5.3 交易详情屏幕

组件名称描述
DetailCard显示交易详细信息
Button编辑、删除、返回

5.4 可复用组件

  • CustomTextInput:带标签和错误提示的输入框。
  • CustomButton:统一样式的按钮。

6. 数据流管理

数据流管理是记账本应用的核心。我们将使用 Context API 管理全局状态,并结合 AsyncStorage 实现数据持久化。

6.1 数据模型

模型属性
用户id, username, email
交易id, amount, date, category, description, type (income/expense)
类别id, name, icon

6.2 Context API 设置

创建一个 TransactionContext 管理交易数据:

import React, { createContext, useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';export const TransactionContext = createContext();export const TransactionProvider = ({ children }) => {const [transactions, setTransactions] = useState([]);const [categories, setCategories] = useState([{ id: 1, name: '餐饮', icon: 'food' },{ id: 2, name: '交通', icon: 'car' },{ id: 3, name: '娱乐', icon: 'movie' },]);useEffect(() => {const loadTransactions = async () => {try {const storedTransactions = await AsyncStorage.getItem('transactions');if (storedTransactions) {setTransactions(JSON.parse(storedTransactions));}} catch (error) {console.error('加载交易失败', error);}};loadTransactions();}, []);const addTransaction = async (transaction) => {const newTransactions = [...transactions, { id: Date.now(), ...transaction }];setTransactions(newTransactions);try {await AsyncStorage.setItem('transactions', JSON.stringify(newTransactions));} catch (error) {console.error('保存交易失败', error);}};const updateTransaction = async (id, updatedTransaction) => {const newTransactions = transactions.map((t) =>t.id === id ? { ...updatedTransaction, id } : t);setTransactions(newTransactions);try {await AsyncStorage.setItem('transactions', JSON.stringify(newTransactions));} catch (error) {console.error('更新交易失败', error);}};const deleteTransaction = async (id) => {const newTransactions = transactions.filter((t) => t.id !== id);setTransactions(newTransactions);try {await AsyncStorage.setItem('transactions', JSON.stringify(newTransactions));} catch (error) {console.error('删除交易失败', error);}};return (<TransactionContext.Providervalue={{ transactions, categories, addTransaction, updateTransaction, deleteTransaction }}>{children}</TransactionContext.Provider>);
};

6.3 数据持久化

AsyncStorage 用于将交易数据保存到设备上,确保应用关闭后数据不丢失。每次添加、更新或删除交易时,更新 AsyncStorage。

6.4 最佳实践

  • 最小化状态:仅存储必要数据。
  • 错误处理:捕获 AsyncStorage 操作的错误。
  • 性能优化:避免频繁读写 AsyncStorage,考虑批量操作。

7. 页面导航

我们将使用 React Navigation 实现页面跳转,结合堆栈导航器(Stack Navigator)管理屏幕。

7.1 导航设置

创建一个 AppNavigator.js

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import LoginScreen from '../screens/LoginScreen';
import HomeScreen from '../screens/HomeScreen';
import AddTransactionScreen from '../screens/AddTransactionScreen';
import TransactionDetailScreen from '../screens/TransactionDetailScreen';const Stack = createStackNavigator();const AppNavigator = () => {return (<NavigationContainer><Stack.Navigator initialRouteName="Login"><Stack.Screen name="Login" component={LoginScreen} /><Stack.Screen name="Home" component={HomeScreen} /><Stack.Screen name="AddTransaction" component={AddTransactionScreen} /><Stack.Screen name="TransactionDetail" component={TransactionDetailScreen} /></Stack.Navigator></NavigationContainer>);
};export default AppNavigator;

7.2 屏幕实现

7.2.1 登录屏幕
import React, { useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { TextInput, Button, Title } from 'react-native-paper';const LoginScreen = ({ navigation }) => {const [username, setUsername] = useState('');const [password, setPassword] = useState('');const handleLogin = () => {// 模拟登录navigation.replace('Home');};return (<View style={styles.container}><Title style={styles.title}>记账本</Title><TextInputlabel="用户名"value={username}onChangeText={setUsername}style={styles.input}/><TextInputlabel="密码"value={password}onChangeText={setPassword}secureTextEntrystyle={styles.input}/><Button mode="contained" onPress={handleLogin} style={styles.button}>登录</Button><Button onPress={() => navigation.navigate('Home')}>跳过注册</Button></View>);
};const styles = StyleSheet.create({container: {flex: 1,padding: 16,justifyContent: 'center',},title: {fontSize: 24,textAlign: 'center',marginBottom: 24,},input: {marginBottom: 16,},button: {marginTop: 16,},
});export default LoginScreen;
7.2.2 主屏幕
import React, { useContext } from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';
import { Card, Title, Paragraph, FAB } from 'react-native-paper';
import { TransactionContext } from '../context/TransactionContext';const HomeScreen = ({ navigation }) => {const { transactions } = useContext(TransactionContext);const totalIncome = transactions.filter((t) => t.type === 'income').reduce((sum, t) => sum + t.amount, 0);const totalExpense = transactions.filter((t) => t.type === 'expense').reduce((sum, t) => sum + t.amount, 0);return (<View style={styles.container}><Title style={styles.title}>财务概览</Title><Card style={styles.summaryCard}><Card.Content><Paragraph>总收入: ${totalIncome}</Paragraph><Paragraph>总支出: ${totalExpense}</Paragraph><Paragraph>净额: ${totalIncome - totalExpense}</Paragraph></Card.Content></Card><Text style={styles.subtitle}>最近交易</Text><FlatListdata={transactions}keyExtractor={(item) => item.id.toString()}renderItem={({ item }) => (<Cardstyle={styles.card}onPress={() => navigation.navigate('TransactionDetail', { transaction: item })}><Card.Title title={item.description} subtitle={item.category} /><Card.Content><Paragraph>{item.type === 'income' ? '+' : '-'} ${item.amount}</Paragraph><Paragraph>{item.date}</Paragraph></Card.Content></Card>)}/><FABstyle={styles.fab}icon="plus"onPress={() => navigation.navigate('AddTransaction')}/></View>);
};const styles = StyleSheet.create({container: {flex: 1,padding: 16,},title: {fontSize: 24,marginBottom: 16,},subtitle: {fontSize: 18,marginVertical: 8,},summaryCard: {marginBottom: 16,},card: {marginBottom: 8,},fab: {position: 'absolute',margin: 16,right: 0,bottom: 0,},
});export default HomeScreen;
7.2.3 添加交易屏幕
import React, { useState, useContext } from 'react';
import { View, StyleSheet } from 'react-native';
import { TextInput, Button, Switch, Picker } from 'react-native-paper';
import { TransactionContext } from '../context/TransactionContext';const AddTransactionScreen = ({ navigation }) => {const { categories, addTransaction } = useContext(TransactionContext);const [amount, setAmount] = useState('');const [date, setDate] = useState(new Date().toISOString().split('T')[0]);const [category, setCategory] = useState(categories[0]?.name || '');const [description, setDescription] = useState('');const [isIncome, setIsIncome] = useState(true);const handleSave = () => {if (!amount || !category) {alert('请填写金额和类别');return;}addTransaction({amount: parseFloat(amount),date,category,description,type: isIncome ? 'income' : 'expense',});navigation.goBack();};return (<View style={styles.container}><TextInputlabel="金额"value={amount}onChangeText={setAmount}keyboardType="numeric"style={styles.input}/><TextInputlabel="日期"value={date}onChangeText={setDate}style={styles.input}/><PickerselectedValue={category}onValueChange={setCategory}style={styles.input}>{categories.map((cat) => (<Picker.Item key={cat.id} label={cat.name} value={cat.name} />))}</Picker><TextInputlabel="描述"value={description}onChangeText={setDescription}style={styles.input}/><View style={styles.switchContainer}><Text>{isIncome ? '收入' : '支出'}</Text><Switch value={isIncome} onValueChange={setIsIncome} /></View><Button mode="contained" onPress={handleSave} style={styles.button}>保存</Button><Button onPress={() => navigation.goBack()} style={styles.button}>取消</Button></View>);
};const styles = StyleSheet.create({container: {flex: 1,padding: 16,},input: {marginBottom: 16,},switchContainer: {flexDirection: 'row',alignItems: 'center',marginBottom: 16,},button: {marginTop: 8,},
});export default AddTransactionScreen;
7.2.4 交易详情屏幕
import React, { useContext } from 'react';
import { View, StyleSheet } from 'react-native';
import { Card, Title, Paragraph, Button } from 'react-native-paper';
import { TransactionContext } from '../context/TransactionContext';const TransactionDetailScreen = ({ route, navigation }) => {const { transaction } = route.params;const { deleteTransaction } = useContext(TransactionContext);const handleDelete = () => {deleteTransaction(transaction.id);navigation.goBack();};return (<View style={styles.container}><Card style={styles.card}><Card.Title title={transaction.description} subtitle={transaction.category} /><Card.Content><Paragraph>{transaction.type === 'income' ? '+' : '-'} ${transaction.amount}</Paragraph><Paragraph>日期: {transaction.date}</Paragraph><Paragraph>描述: {transaction.description}</Paragraph></Card.Content><Card.Actions><Button onPress={() => navigation.navigate('AddTransaction', { transaction })}>编辑</Button><Button onPress={handleDelete}>删除</Button></Card.Actions></Card></View>);
};const styles = StyleSheet.create({container: {flex: 1,padding: 16,},card: {marginBottom: 16,},
});export default TransactionDetailScreen;

7.3 导航参数

通过 route.params 传递交易数据到详情屏幕或编辑屏幕,确保数据流畅。

8. 数据持久化

AsyncStorage 用于持久化交易数据。TransactionContext 已实现保存和加载功能,确保数据在应用重启后保留。

8.1 最佳实践

  • 序列化数据:使用 JSON 存储复杂对象。
  • 错误处理:捕获 AsyncStorage 操作的错误。
  • 限制数据量:AsyncStorage 适合小型数据(<1MB)。

9. 跨平台兼容处理技巧

React Native 提供了跨平台支持,但仍需处理 iOS 和 Android 的差异。

9.1 平台特定代码

使用 Platform 模块处理平台差异:

import { Platform } from 'react-native';const styles = StyleSheet.create({container: {paddingTop: Platform.OS === 'ios' ? 20 : 0,},
});

9.2 样式差异

  • 阴影:iOS 使用 shadow 属性,Android 使用 elevation
  • 键盘处理:使用 KeyboardAvoidingView 确保输入框不被键盘遮挡。
import { KeyboardAvoidingView, Platform } from 'react-native';const AddTransactionScreen = () => (<KeyboardAvoidingViewbehavior={Platform.OS === 'ios' ? 'padding' : 'height'}style={styles.container}>{/* 表单内容 */}</KeyboardAvoidingView>
);

9.3 组件差异

  • Picker:React Native Paper 的 Picker 在 iOS 和 Android 上表现不同,需测试。
  • 日期选择器:考虑使用 @react-native-community/datetimepicker 确保一致性。

9.4 测试

  • 在 iOS 和 Android 模拟器上测试。
  • 使用真机验证触摸交互和性能。
  • 推荐使用 Detox 进行端到端测试。

10. 结论

通过开发记账本应用,您掌握了 React Native 的核心技能,包括功能模块分析、接口设计、组件结构划分、数据流管理、页面跳转和跨平台兼容处理。这个项目展示了如何将理论知识应用于实践,构建一个功能完整的移动应用。

10.1 挑战与解决方案

  • 挑战:管理复杂状态。
    • 解决方案:使用 Context API 和 AsyncStorage。
  • 挑战:跨平台样式差异。
    • 解决方案:使用 Platform 模块和 React Native Paper。
  • 挑战:导航参数传递。
    • 解决方案:通过 React Navigation 的 route.params。

10.2 进一步学习

  • 扩展功能:添加图表(如 react-native-chart-kit)、真实后端(如 Firebase)。
  • 优化性能:使用 useMemouseCallback 减少重新渲染。
  • 深入文档:参考 React Navigation 和 React Native Paper。

通过不断实践,您将能够构建更复杂、用户体验更佳的 React Native 应用!

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

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

相关文章

从 PPO、DPO 到 GRPO:大语言模型策略优化算法解析

从 PPO、DPO 到 GRPO&#xff1a;大语言模型策略优化算法解析 背景与简介 大语言模型&#xff08;LLM&#xff09;的训练通常分为预训练和后训练两个阶段。预训练阶段&#xff0c;模型在海量文本上学习下一词预测的能力&#xff1b;后训练阶段&#xff0c;我们希望进一步对齐…

React中使用Day.js指南

文章目录 引言什么是Day.js&#xff1f;Day.js的核心特性 安装和基础配置安装Day.js基础导入和使用 在React中的基础使用1. 显示格式化日期2. 实时时钟组件 常用插件配置1. 相对时间插件2. 高级格式化插件3. 时区处理插件 实战案例&#xff1a;博客文章时间组件高级应用场景1. …

【系统设计【1】】系统设计面试方法论:从0到百万用户的需求到架构的推演

文章目录 一、系统设计面试的底层逻辑&#xff1a;从需求到架构的推演&#xff08;一&#xff09;需求澄清&#xff1a;界定问题边界&#xff08;二&#xff09;分层设计&#xff1a;从单节点到分布式的演进1. Web层&#xff1a;无状态化与负载均衡2. 数据层&#xff1a;数据库…

京津冀城市群13城市空间权重0-1矩阵

京津冀城市群13城市空间权重0-1矩阵 1、数据说明&#xff1a;京津冀13个城市&#xff1a;北京市、保定市、沧州市、承德市、邯郸市、衡水市、廊坊市、秦皇岛市、石家庄市、唐山市、邢台市、张家口市、天津市、 2、指标解释&#xff1a;空间权重矩阵是一种用于表征空间表达式的…

七大技术路线解析:自动驾驶如何被数据重新定义

自动驾驶技术从实验室的算法验证走向大规模量产应用&#xff0c;是一场充满挑战的征程。这段征程的核心驱动力&#xff0c;不仅是芯片和传感器的升级&#xff0c;更是一场关于数据的“喂养”竞赛——从简单的像素标注到多模态大模型的理解&#xff0c;数据需求的演变悄然推动着…

计网复习知识(16)传输层及其协议功能

目录 考研大纲 1.传输层概述 端口号 有连接/无连接传输 可靠/不可靠传输 2.UDP协议 2.1 udp数据报 2.2 udp检验 3.TCP协议 3.1 TCP协议的框架梳理 3.2 TCP报文段**** 3.3 三次握手与四次挥手 三次握手 四次挥手 3.4 可靠传输与流量控制 流量控制&#xff1a;滑动…

每天一个前端小知识 Day 1

语义化 HTML&#xff08;Semantic HTML&#xff09; 1. 什么是语义化 HTML&#xff1f; 语义化 HTML 指的是使用符合内容含义的标签&#xff0c;而不仅仅为了布局或样式。例如&#xff1a; <article>…</article> <nav>…</nav> <header>…&l…

在docker中部署mysql

部署 MySQL&#xff08;端口 9006&#xff09; 1. 创建数据目录 mkdir -p ~/qihuang/mysql/data2. 启动 MySQL 容器 docker run -d \--name mysql-qihuang \-p 9006:3306 \-v ~/qihuang/mysql/data:/var/lib/mysql \-e MYSQL_ROOT_PASSWORDroot \-e MYSQL_DATABASEqihuangdb…

JavaScript基础-事件对象

一、前言 在前端开发中&#xff0c;用户与页面的交互行为&#xff08;如点击按钮、输入文本、滚动页面等&#xff09;都会触发相应的事件。而这些事件发生时&#xff0c;浏览器会自动创建一个 事件对象&#xff08;Event Object&#xff09;&#xff0c;它包含了当前事件的所有…

蓝桥杯_染色_bfs_Java

临时抱抱佛脚&#xff0c;太浮躁了&#xff0c;蓝桥杯已经快1个半月没做题了。 本人比较菜&#xff0c;感觉这个时间节点也只能把暴力题给尽量多做做&#xff0c;找找做题手感&#xff0c;其他就纯凭运气了吧。T-T。 题目 问题描述 小蓝有一个 n 行 m 列的白色棋盘, 棋盘的每一…

MySQL 究极奥义·动态乾坤大挪移·无敌行列转换术

导入大SQL文件 [mysqld] # 大批量导入优化 bulk_insert_buffer_size1G max_allowed_packet1G innodb_autoextend_increment512M innodb_buffer_pool_size4G innodb_log_buffer_size4G innodb_log_file_size4G动态行列转换 DROP TABLE IF EXISTS tb_score;CREATE TABLE tb_sco…

Excel大厂自动化报表实战(互联网金融-数据分析周报制作中)

这是Excel大厂自动化报表实战第三期--互联网金融-数据分析周报制作中 数据资源已经与这篇博客捆绑&#xff0c;有需要者可以下载通过网盘分享的文件&#xff1a;2.4自动化报表-8月成交数据.xlsx&#xff0c;2.4自动化报表-8月获客数据.csv等2个文件 链接: https://pan.baidu.c…

langchain从入门到精通(七)——利用回调功能调试链应用 - 让过程更透明

1. Callback 功能介绍 Callback 是 LangChain 提供的回调机制&#xff0c;允许我们在 LLM 应用程序的各个阶段使用 hook &#xff08;钩子&#xff09;。钩子的含义也非常简单&#xff0c;我们把应用程序看成一个一个的处理逻辑&#xff0c;从开始到结束&#xff0c;钩子就是在…

如何使用Postman做接口自动化测试

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 本文适合已经掌握 Postman 基本用法的读者&#xff0c;即对接口相关概念有一定了解、已经会使用 Postman 进行模拟请求等基本操作。 工作环境与版本&#xff1a; …

ELK日志文件分析系统——E(Elasticsearch)

目录 基本概念 一、架构设计 二、核心原理 三、关键特性 四、应用意义 部署步骤 ‌一、环境准备‌ ‌二、安装 Elasticsearch‌ ‌三、关键配置&#xff08;elasticsearch.yml&#xff09;‌ ‌四、启动与验证‌ ‌五、集群扩展&#xff08;新增节点&#xff09;‌ …

融智学教育观及其数学公式体系凝练汇总

摘要&#xff1a;本文系统阐述了邹晓辉教授的融智学教育观&#xff0c;通过原创数学公式体系构建了人机协同教育模型。核心内容包括&#xff1a;认知本体论&#xff08;文明智慧当量方程&#xff09;、方法论&#xff08;七遍通训练算子&#xff09;、生态位控制论&#xff08;…

互联网大厂Java求职面试:AI大模型应用实践中的架构挑战与实战

互联网大厂Java求职面试&#xff1a;AI大模型应用实践中的架构挑战与实战 引言 在当今技术飞速发展的时代&#xff0c;AI大模型已成为企业数字化转型的重要引擎。无论是内容生成、智能客服、个性化推荐&#xff0c;还是知识图谱构建和语义理解&#xff0c;大模型的应用场景正在…

龟兔赛跑算法(Floyd‘s Cycle-Finding Algorithm)寻找重复数

龟兔赛跑算法&#xff08;Floyd’s Cycle-Finding Algorithm&#xff09;寻找重复数 问题描述 给定一个长度为 N1 的数组 nums&#xff0c;其中每个元素的值都在 [1, N] 范围内。根据鸽巢原理&#xff0c;至少有一个数字是重复的。请找出这个重复的数字。 要求&#xff1a; …

紫光展锐T8300以创新音频技术重塑感知世界

数字化时代&#xff0c;从语音通话到智能交互&#xff0c;从聆听音乐到创作Vlog&#xff0c;声音已成为隐形的基础措施。日益发展的音频技术正在重构用户感知世界的方式&#xff0c;重塑用户的听觉体验。 T8300是紫光展锐专为全球主流用户打造的5G SoC&#xff0c;采用了紫光展…

写作词汇积累(A):颇有微词、微妙(“微”字的学习理解)

一、颇有微词 1、基本介绍 【颇有微词】指对某人或某事有轻微的批评、不满或不同意见&#xff0c;但表达得含蓄委婉 【颇】表示程度较深&#xff0c;【微词】表示隐晦的批评 【微】表示隐晦的、不直白的&#xff0c;强调批评的委婉性 2、使用实例 1、尽管公司的新考勤制度…