当前位置: 首页 > news >正文

Android学习制作app(ESP8266-01S连接-简单制作)

一、理论

部分理论见arduino学习-CSDN博客和Android Studio安装配置_android studio gradle 配置-CSDN博客

以下直接上代码和效果视频,esp01S的收发硬件代码目前没有分享,但是可以通过另一个手机网络调试助手进行模拟。也可以直接根据我的代码进行改动自行使用,代码中已经对模块进行了详细注释。本人不是java开发专业人士,也是通过ai完成的。

使用以下文件需要完成AndroidStdio的安装和SDK,SDK插件、gradle的配置,详细可以见之前的文章。

1、主xml文件制作界面

通过linearlayout布局,制作简单的界面,app头部为标题,中间为按钮和text显示。

<?xml version="1.0" encoding="utf-8"?>
<!-- CYA开发,SmartOrderDishes内容,VX:18712214828 -->
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity">
<!--    头部--><LinearLayoutandroid:layout_width="match_parent"android:layout_weight="1"android:layout_height="match_parent"android:gravity="top"android:orientation="horizontal"><TextViewandroid:layout_width="match_parent"android:layout_height="100dp"android:text="SmartOrderDishes"android:background="#609E9245"android:gravity="center|left"android:paddingLeft="30dp"android:textSize="20sp"android:textStyle="bold"android:letterSpacing="0.2"android:drawableStart="@mipmap/ic_launcher"/></LinearLayout>
<!--    显示模块--><LinearLayoutandroid:layout_width="match_parent"android:layout_weight="0.5"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"><TextViewandroid:layout_width="400dp"android:layout_height="match_parent"android:text="在连接ESP-01S WIFI后,等待LCD1602显示CanConnectServer。点击连接按钮,连接服务器"android:textSize="20dp"android:gravity="left"/></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"><Buttonandroid:onClick="Connect"android:layout_width="120dp"android:layout_height="60dp"android:layout_marginLeft="10dp"android:text="连接"/><Buttonandroid:onClick="OffConnect"android:layout_width="120dp"android:layout_height="60dp"android:layout_marginLeft="10dp"android:text="断开连接"/></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:paddingTop="50dp"><TextViewandroid:id="@+id/Show_Text"android:layout_width="wrap_content"android:layout_height="50dp"android:textSize="20sp"android:text="Wait Checking out!"android:gravity="center"/></LinearLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="1"android:gravity="center"android:orientation="horizontal"></LinearLayout>
</LinearLayout>

 2、主xml对应的java文件

此文件中,对socket连接和收发线程进行了使用,并且有两个按钮点击事件,和接收到服务器数据的弹窗和弹窗按钮点击事件。

package com.example.smartorderdishes;
/*
CYA开发,VX:18712214828
自动点餐系统安卓app:
1、主线程进行点击时间和线程侦听
2、手机连接ESP-01S的WIFI后点击连接即可连接ESP服务器。(通过8080端口和192.168.4.1默认服务器ip)
3、接收到数据后进行弹窗显示需要结算的桌面,和总金额。
4、弹窗中点击确定即可结算。ESP会受到数据包。*/
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";//主java文件TAGprivate SocketClient socketClient;//socket自定义库文件变量private TextView textView;//TextView标签变量@SuppressLint("MissingInflatedId")@Overrideprotected void onCreate(Bundle savedInstanceState) {//主java文件函数,只会运行一次super.onCreate(savedInstanceState);EdgeToEdge.enable(this);setContentView(R.layout.activity_main);ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);return insets;});socketClient = new SocketClient(this);//变量对象初始化textView = findViewById(R.id.Show_Text);//获取标签id// 设置数据接收回调// 连接成功后启动持续监听socketClient.setDataReceivedCallback(new SocketClient.DataReceivedCallback() {@Overridepublic void onDataReceived(String data) {runOnUiThread(() -> {byte[]  DataPacket = socketClient.hexStringToByteArray(data);int deskNum = ((DataPacket[1]&0xF0)/16)+1;int priceCount = (DataPacket[1]*256+DataPacket[2])&0x0FFF;showDialog(data);});}});}// 连接按钮点击事件public void Connect(View view) {// 连接到服务器(内部会自动启动接收循环)socketClient.connectToServer();}//断开连接按钮点击事件public void OffConnect(View view) {// 关闭连接socketClient.closeConnection();}// 显示弹窗private void showDialog(String data) {AlertDialog.Builder builder = new AlertDialog.Builder(this);//新建弹窗对象byte[]  DataPacket = socketClient.hexStringToByteArray(data);//传入的数据转化为字节数组int deskNum = ((DataPacket[1]&0xF0)/16)+1;//桌号获取int priceCount = (DataPacket[1]*256+DataPacket[2])&0x0FFF;//总金额获取builder.setTitle("桌号"+deskNum+",结算请求:");//弹窗标题builder.setMessage("共计总金额$" + priceCount+"是否结算!");//弹窗信息// 确定按钮builder.setPositiveButton("确认结算", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {//确认按钮点击事件Toast.makeText(MainActivity.this, "You clicked OK", Toast.LENGTH_SHORT).show();//发送十六进制数据String hexData = "EBAAFF90"; //发送结算成功数据包socketClient.sendHexData(hexData);textView.setText("桌号:" + deskNum+"结算,总金额$"+priceCount+"\n");//显示/*textView.setText("桌号:" + deskNum+"结算,总金额$"+priceCount+"\n"+"Data:"+data);*/}});// 取消按钮builder.setNegativeButton("取消结算", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Toast.makeText(MainActivity.this, "You clicked Cancel", Toast.LENGTH_SHORT).show();}});// 显示弹窗AlertDialog dialog = builder.create();dialog.show();}}

 3、socket连接服务器、侦听数据包和发送数据包线程,Java文件

package com.example.smartorderdishes;import android.content.Context;
import android.util.Log;
import android.widget.Toast;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class SocketClient {private static final String SERVER_IP = "192.168.4.1";//连接的指定IPprivate static final int SERVER_PORT = 8080;//连接服务器的指定端口private static final int CONNECTION_TIMEOUT = 5000;//连接超时时间 msprivate static final int READ_TIMEOUT = 5000; // 新增读取超时时间 msprivate Socket socket;//socket变量private BufferedOutputStream out;//输出缓冲区变量private BufferedInputStream in;//输入缓冲区变量private Context context;//private ExecutorService executorService;//单线程 用于连接服务器private ExecutorService receiverExecutor; // 独立线程池用于接收数据public SocketClient(Context context) {this.context = context;executorService = Executors.newSingleThreadExecutor();//单线程的执行器服务(Executor Service),用于管理和调度任务的执行receiverExecutor = Executors.newSingleThreadExecutor(); // 独立线程池 线程用于接收数据}// 连接服务器(修改后的代码)public void connectToServer() {executorService.execute(() -> {//线程提交不需要返回结果的任务try {//异常抛出socket = new Socket();//socket对象socket.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT), CONNECTION_TIMEOUT);//socket连接,指定地址、端口和超时时间socket.setSoTimeout(READ_TIMEOUT); // 设置读取超时out = new BufferedOutputStream(socket.getOutputStream());//发送缓冲区对象in = new BufferedInputStream(socket.getInputStream());//接收缓冲区对象runOnUiThread(() -> {//runOnUiThread() 是 Activity 类中的一个方法 ,用于在主线程执行代码Toast.makeText(context, "Connected to server", Toast.LENGTH_SHORT).show();Log.d("SocketClient", "Connected to server");});// 连接成功后启动接收循环startReceivingData();} catch (IOException e) {runOnUiThread(() -> {Toast.makeText(context, "Failed to connect: " + e.getMessage(), Toast.LENGTH_SHORT).show();Log.e("SocketClient", "Connection error: " + e.getMessage());});}});}// 发送十六进制数据public void sendHexData(String hexData) {executorService.execute(new Runnable() {@Overridepublic void run() {if (out != null && socket != null && !socket.isClosed()) {try {// 将十六进制字符串转换为字节数组byte[] data = hexStringToByteArray(hexData);out.write(data);//发送字节数组out.flush();//发送完毕后,关闭发送Log.d("SocketClient", "Sent (Hex): " + hexData);} catch (IOException e) {e.printStackTrace();runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(context, "Failed to send data: " + e.getMessage(), Toast.LENGTH_SHORT).show();}});}} else {runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(context, "Not connected to server", Toast.LENGTH_SHORT).show();}});}}});}// 接收数据包(0xEB 0xXX 0xXX 0x90)// 启动接收循环private void startReceivingData() {receiverExecutor.execute(() -> {//通过单线程执行器,所有提交的任务都会按顺序在一个单独的线程中执行。Log.d("SocketClient", "Starting receive loop");try {while (!Thread.currentThread().isInterrupted()//用于检查当前线程是否已被中断的方法&& socket != null//检查 Socket 对象是否已经被初始化且不为 null。这个检查通常用于确保在尝试使用 Socket 进行网络通信之前,它已经被正确创建和配置。&& !socket.isClosed()//检查 Socket 对象是否被关闭&& in != null) {//确保输入流(InputStream)对象已经被正确初始化且不为 null,避免潜在的 NullPointerExceptionbyte[] buffer = new byte[1024];//存储获取的数据int bytesRead;//存储获取的数据长度try {bytesRead = in.read(buffer); // 阻塞读取(但设置了超时),返回数组长度if (bytesRead == -1) {//未读取到数据Log.d("SocketClient", "Connection closed by server");break;}String hexResponse = byteArrayToHexString(buffer, bytesRead);//转字节数组换为字符串Log.d("SocketClient", "Received (Hex): " + hexResponse);if (isValidDataPacket(buffer, bytesRead)) {//判断是否符合数据包格式Log.d("SocketClient", "Valid packet received");// 触发回调if (dataReceivedCallback != null) {//回调接口变量是否为空dataReceivedCallback.onDataReceived(hexResponse);//回调不为空则运行回调函数,回调接收到的hex字符串}}} catch (SocketTimeoutException e) {Log.d("SocketClient", "Read timeout, retrying...");continue;} catch (IOException e) {Log.e("SocketClient", "Read error: " + e.getMessage());break;}}} finally {Log.d("SocketClient", "Exiting receive loop");}});}// 检查数据包是否符合 0xEB 0xXX 0xXX 0x90 格式private boolean isValidDataPacket(byte[] data, int length) {if (length < 4) {Log.d("SocketClient", "Invalid packet: length < 4");return false;}boolean isValid = (data[0] == (byte) 0xEB) && (data[3] == (byte) 0x90);Log.d("SocketClient", "Data validity: " + isValid);return isValid;}// 关闭连接public void closeConnection() {executorService.execute(new Runnable() {@Overridepublic void run() {try {if (out != null) out.close();if (in != null) in.close();if (socket != null) socket.close();//关闭socket连接Log.d("SocketClient", "Connection closed");} catch (IOException e) {e.printStackTrace();}}});}// 回调接口,用于接收数据/*onDataReceived 是一个常见的回调方法名称,通常用于在数据接收到时通知监听器或处理数据。这个方法一般定义在一个接口中,并由实现该接口的类提供具体的数据处理逻辑。*/public interface DataReceivedCallback {void onDataReceived(String data);}// 设置回调接口private DataReceivedCallback dataReceivedCallback;//回调接口变量,回调接口为自定义,在上面已定义public void setDataReceivedCallback(DataReceivedCallback callback) {this.dataReceivedCallback = callback;}// 在主线程中运行代码private void runOnUiThread(Runnable action) {new android.os.Handler(context.getMainLooper()).post(action);}// 将十六进制字符串转换为字节数组public byte[] hexStringToByteArray(String hex) {int len = hex.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)+ Character.digit(hex.charAt(i + 1), 16));}return data;}// 将字节数组转换为十六进制字符串private String byteArrayToHexString(byte[] bytes, int length) {StringBuilder hex = new StringBuilder();for (int i = 0; i < length; i++) {hex.append(String.format("%02X", bytes[i]));}return hex.toString();}}

 

 4、app获取网络权限文件,以及启动文件配置文件

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><!-- 配置网络权限 --><!-- 互联网访问 --><uses-permission android:name="android.permission.INTERNET" /> <!-- 访问网络状态 --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 访问wifi状态 --><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!-- 访问WiFi网络的信息 --><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><!-- 允许改变WiFi连接状态(如果需要的话) --><uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /><!-- 从Android 6.0(API level 23)开始,获取WiFi信息也需要位置权限 --><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /><!-- 或者使用粗略的位置权限 --><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><applicationandroid:allowBackup="true"android:dataExtractionRules="@xml/data_extraction_rules"android:fullBackupContent="@xml/backup_rules"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/Theme.SmartOrderDishes"tools:targetApi="31"><!-- 配置Activity可启动输出权限 --><activityandroid:name=".MainActivity"android:exported="true"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

二、效果

说明:

1、esp8266-01S开启AP模式的多连接的Station模式。设定端口为8080,默认ip应该是192.168.4.1,网络SSID(名称)为ESP-01S。这些里面目前是固定的,配置即ESP8266作为热点和服务器,手机连接ESP8266的WIFI,然后作为客户端手机连接到ESP8266的服务器,进行通信

2、手机连接ESP8266的wifi后。等待配置完毕,然后进行服务器连接,连接完成手机会有信息提醒。

3、连接完成后,esp8266给手机发送0xEB 0xXX 0xXX 0x90的数据包DATA[4](下标从0开始),其中DATA[1]的高4bit作为桌位,低12bit为总金额。

4、接收到数据后手机app进行弹窗,点击确定后手机app界面text改变。并且向ESP8266发送EBAAFF90(HEX)数据作为结账完成的标志数据包。

效果视频

智能点餐系统开发视频

 

代码详解 

 

 

 

其他代码问题(个人理解):

首先执行主线程mainactivity.java内容,创建UI和监听按钮动作。在onCreate创建的生命周期

(只执行一次,设置了数据接收回调的动作内容)。在socketclient.java中定义了回调函数,数据发送函数,数据接收函数,数据处理函数,类对象线程池创建等。

当mainactivity.java点击连接按钮时,触发Connect方法,进行服务器连接,在socketclient.java中的连接方法connectToServer启动了receiverExecutor线程。

receiverExecutor线程有while,会在while内持续运行,当

这些情况,线程才会结束,即意外断开服务器连接或者手动断开连接,线程才会退出,如果 in.read(buffer) 没有数据可读,线程会阻塞(挂起),直到有数据到达或超时。在接收到正确的数据包时,会触发回调,会在receiverExecutor运行mainactivity内的程序(想在主线程运行内容需要使用runOnUiThread())。

----------------------------------------------------------------------------------------

看一下AI的回答:

 

 

 

 

 

 

相关文章:

Android学习制作app(ESP8266-01S连接-简单制作)

一、理论 部分理论见arduino学习-CSDN博客和Android Studio安装配置_android studio gradle 配置-CSDN博客 以下直接上代码和效果视频&#xff0c;esp01S的收发硬件代码目前没有分享&#xff0c;但是可以通过另一个手机网络调试助手进行模拟。也可以直接根据我的代码进行改动…...

一文读懂 RAG:LLM 借助检索打开思路

一、引言 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;随着深度学习技术的飞速发展&#xff0c;大型语言模型&#xff08;LLMs&#xff09;展现出了强大的语言理解和生成能力。然而&#xff0c;LLMs也存在一些局限性&#xff0c;如容易产生幻觉、知识更新不及时…...

使用istio实现权重路由

istio概述 **概述&#xff1a;**Istio 是一个开源的 服务网格&#xff08;Service Mesh&#xff09;解决方案&#xff0c;主要用于管理、保护和监控微服务架构中的服务通信。它为微服务提供了基础设施层的控制功能&#xff0c;不需要更改应用程序的代码&#xff0c;从而解决服…...

DeepSeek发布新模型,遭遇大规模攻击,梁文锋回应证实为假,吴恩达盛赞DeepSeek!AI Weekly 1.27-2.2

&#x1f4e2;本周AI快讯 | 1分钟速览&#x1f680; 1️⃣ &#x1f5bc;️Janus-Pro-7B&#xff1a;DeepSeek发布7B开源多模态模型&#xff0c;视觉理解&生成能力超越DALL-E 3&#xff01; 2️⃣ &#x1f6a8;DeepSeek遭遇大规模攻击&#xff1a;DDoS暴力破解&#xff…...

20250202在Ubuntu22.04下使用Guvcview录像的时候降噪

20250202在Ubuntu22.04下使用Guvcview录像的时候降噪 2025/2/2 21:25 声卡&#xff1a;笔记本电脑的摄像头自带的【USB接口的】麦克风。没有外接3.5mm接口的耳机。 缘起&#xff1a;在安装Ubuntu18.04/20.04系统的笔记本电脑中直接使用Guvcview录像的时候底噪很大&#xff01; …...

直方图:摄影中的视觉数据指南

目录 一、直方图基础&#xff1a;揭开它的神秘面纱 二、解读直方图类型&#xff1a;亮度与色彩的密码 &#xff08;一&#xff09;亮度直方图 &#xff08;二&#xff09;RGB 直方图 三、拍摄中巧用直方图&#xff1a;优化曝光与效果 &#xff08;一&#xff09;精准判断曝…...

OpenGL学习笔记(七):Camera 摄像机(视图变换、LookAt矩阵、Camera类的实现)

文章目录 摄像机/观察空间/视图变换LookAt矩阵移动相机&#xff08;处理键盘输入&#xff09;移动速度欧拉角移动视角&#xff08;处理鼠标输入&#xff09;缩放场景&#xff08;处理滚轮输入&#xff09;Camera类 摄像机/观察空间/视图变换 在上一节变换中&#xff0c;我们讨…...

冲刺一区!挑战7天完成一篇趋势性分析GBD DAY1-7

Day1. 公开数据库的挖掘太火热了,其中GBD数据库的挖掘又十分的火爆.那我就来挑战一篇GBD、一篇关于趋势性分析的GBD&#xff01; GBD数据库挖掘是目前的四大刊常客&#xff0c;经常出现在顶级期刊上面。这个数据库亮点就是&#xff1a;可视化&#xff0c;统计学简单、而数据可…...

解锁数据结构密码:层次树与自引用树的设计艺术与API实践

1. 引言&#xff1a;为什么选择层次树和自引用树&#xff1f; 数据结构是编程中的基石之一&#xff0c;尤其是在处理复杂关系和层次化数据时&#xff0c;树形结构常常是最佳选择。层次树&#xff08;Hierarchical Tree&#xff09;和自引用树&#xff08;Self-referencing Tree…...

【AudioClassificationModelZoo-Pytorch】基于Pytorch的声音事件检测分类系统

源码&#xff1a;https://github.com/Shybert-AI/AudioClassificationModelZoo-Pytorch 模型测试表 模型网络结构batch_sizeFLOPs(G)Params(M)特征提取方式数据集类别数量模型验证集性能EcapaTdnn1280.486.1melUrbanSound8K10accuracy0.974, precision0.972 recall0.967, F1-s…...

ARM嵌入式学习--第十二天(WDOG,RTC)

--WDOG -介绍 WatchDog是为了能够防止程序跑飞而使用的一种硬件模块&#xff0c;如果你的程序没有跑飞&#xff0c;那么你的程序会定时的去喂看门狗&#xff1b;如果你的程序跑飞了&#xff0c;那么就不会再去喂狗了&#xff0c;如果超过了喂狗时间&#xff0c;那么狗就会自己…...

自动化构建-make/Makefile 【Linux基础开发工具】

文章目录 一、背景二、Makefile编译过程三、变量四、变量赋值1、""是最普通的等号2、“:” 表示直接赋值3、“?” 表示如果该变量没有被赋值&#xff0c;4、""和写代码是一样的&#xff0c; 五、预定义变量六、函数**通配符** 七、伪目标 .PHONY八、其他常…...

三天急速通关JavaWeb基础知识:Day 2 前端基础知识(计划有变,前端工程化部分暂时搁置)

三天急速通关JavaWeb基础知识&#xff1a;Day 2 前端基础知识 0 文章说明1 HTML1.1 介绍1.2 基本结构及语法1.3 常见标签2 CSS2.1 介绍2.2 引入方式2.3 选择器2.4 浮动 定位 盒子模型 3 JavaScript3.1 介绍3.2 组成3.3 基础语法 4 Ajax4.1 介绍4.2 示例 未完待续&#xff0c;前…...

Chapter2 Amplifiers, Source followers Cascodes

Chapter2 Amplifiers, Source followers & Cascodes MOS单管根据输入输出, 可分为CS放大器, source follower和cascode 三种结构. Single-transistor amplifiers 这一章学习模拟电路基本单元-单管放大器 单管运放由Common-Source加上DC电流源组成. Avgm*Rds, gm和rds和…...

14-9-3C++STL的set容器

set容器的pair对组——set容器set.equal range(elem) 1.返回容器中与elem相等的上下限的两个迭代器&#xff1b;上限是闭区间&#xff0c;下限是开区间&#xff0c;如[beg, end) 2.函数返回两个迭代器&#xff0c;而这两个迭代器被封装在pair中 pair< set<int>::ite…...

用Impala对存储在HDFS中的大规模数据集进行快速、实时的交互式SQL查询的具体步骤和关键代码

AWS EMR&#xff08;Elastic MapReduce&#xff09;中应用Impala的典型案例&#xff0c;主要体现在大型企业和数据密集型组织如何利用Impala对存储在Hadoop分布式文件系统&#xff08;HDFS&#xff09;中的大规模数据集进行快速、实时的交互式SQL查询。以下是一个具体的案例说明…...

如何确认Linux嵌入式系统的触摸屏对应的是哪个设备文件(/dev/input/event1)?如何查看系统中所有的输入设备?输入设备的设备文件有什么特点?

Linux嵌入式系统的输入设备的设备文件有什么特点&#xff1f; 在 Linux 中&#xff0c;所有的输入设备&#xff08;如键盘、鼠标、触摸屏等&#xff09;都会被内核识别为 输入事件设备&#xff0c;并在 /dev/input/ 目录下创建相应的 设备文件&#xff0c;通常是&#xff1a; …...

C++泛型编程指南08 auto decltype

文章目录 [TOC]第3章&#xff1a;auto占位符&#xff08;C11&#xff5e;C17&#xff09;3.1 auto关键字的重新定义3.2 类型推导规则 3.3 何时使用auto3.4 返回类型推导3.5 在Lambda表达式中使用auto3.6 非类型模板参数占位符 总结第4章 decltype说明符&#xff08;C11&#xf…...

php的使用及 phpstorm环境部署

php语法 环境搭建&#xff1a;在小皮中新建网站&#xff0c;注意先填写域名再点击选择根目录。 成功创建网站后&#xff0c;打开发现forbidden&#xff0c;因为新建的网站里是空的&#xff0c;需要新建index.php文件----> 在Phpstorm中左上角打开文件&#xff0c;打开那个文…...

人工智能学习(五)之机器学习逻辑回归算法

深入剖析机器学习逻辑回归算法 一、引言 在机器学习领域&#xff0c;逻辑回归是一种极为经典且应用广泛的算法。虽说名字里带有 “回归”&#xff0c;但它主要用于解决分类问题&#xff0c;在医学、金融、互联网等多个领域都发挥着关键作用。例如&#xff0c;在医学上辅助判断…...

Kubernetes学习之包管理工具(Helm)

一、基础知识 1.如果我们需要开发微服务架构的应用&#xff0c;组成应用的服务可能很多&#xff0c;使用原始的组织和管理方式就会非常臃肿和繁琐以及较难管理&#xff0c;此时我们需要一个更高层次的工具将这些配置组织起来。 2.helm架构&#xff1a; chart:一个应用的信息集合…...

数据结构课程设计(四)校园导航

4 校园导航 4.1 需求规格说明 【问题描述】 一个学校平面图&#xff0c;至少包括10个以上的场所&#xff0c;每个场所带有编号、坐标、名称、类别等信息&#xff0c;两个场所间可以有路径相通&#xff0c;路长&#xff08;耗时&#xff09;各有不同。要求读取该校园平面图&a…...

(done) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)

网页&#xff1a;https://pdos.csail.mit.edu/6.S081/2023/labs/thread.html (任务1教会了你如何用 C 语言调用汇编&#xff0c;编译后链接即可) 任务1&#xff1a;Uthread: switching between threads (完成) 在这个练习中&#xff0c;你将设计一个用户级线程系统中的上下文切…...

大年初六,风很大

北京的风在立春附近的几天突然大了&#xff0c;正在盘算着这个冬天可能就这样平庸的去了&#xff0c;没成想风来了。走在风中&#xff0c;穿着本应该是三九天穿的冬装&#xff0c;紧闭着嘴&#xff0c;缩着身子&#xff0c;感受着这冬天该有的低温。这是冬天该有的样子&#xf…...

【算法】回溯算法专题③ ——排列型回溯 python

目录 前置小试牛刀回归经典举一反三总结 前置 【算法】回溯算法专题① ——子集型回溯 python 【算法】回溯算法专题② ——组合型回溯 剪枝 python 小试牛刀 全排列 https://leetcode.cn/problems/permutations/description/ 给定一个不含重复数字的数组 nums &#xff0c;返…...

利用deepseek参与软件测试 基本架构如何 又该在什么环节接入deepseek

利用DeepSeek参与软件测试&#xff0c;可以考虑以下基本架构和接入环节&#xff1a; ### 基本架构 - **数据层** - **测试数据存储**&#xff1a;用于存放各种测试数据&#xff0c;包括正常输入数据、边界值数据、异常数据等&#xff0c;这些数据可以作为DeepSeek的输入&…...

99.20 金融难点通俗解释:中药配方比喻马科维茨资产组合模型(MPT)

目录 0. 承前1. 核心知识点拆解2. 中药搭配比喻方案分析2.1 比喻的合理性 3. 通俗易懂的解释3.1 以中药房为例3.2 配方原理 4. 实际应用举例4.1 基础配方示例4.2 效果说明 5. 注意事项5.1 个性化配置5.2 定期调整 6. 总结7. 代码实现 0. 承前 本文主旨&#xff1a; 本文通过中…...

为AI聊天工具添加一个知识系统 之79 详细设计之20 正则表达式 之7

本文要点 要点 “正则表达式” 本来是计算机科学计算机科学的一个概念。本项目将它推广&#xff08;扩张&#xff09;到认知科学的“认知范畴”概念&#xff0c; 聚合&#xff08;收敛&#xff09;到 神经科学 的“神经元”概念。 做法是&#xff1a;用reg 来系统化定义认知…...

[ Spring ] Spring Boot Mybatis++ 2025

文章目录 StructureMyBatis Controller AbilitiesConfigure Plugins and RepositoriesApply Plugins and Add DependenciesMyBatis Spring PropertiesMyBatis ApplicationMyBatis BeansMyBatis MapperMyBatis Query Builder Structure this blog introduce 3 ways using mybat…...

虚幻基础17:动画层接口

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 animation layer interface animation layer interface 动画层接口&#xff1a;动画图表的集。仅有名字。 添加到动画蓝图中&#xff0c;由动画蓝图实现动画图表。...

前缀和算法

文章目录 算法总览题目1371.每个元音包含偶数次的最长子字符串 算法总览 题目 1371.每个元音包含偶数次的最长子字符串 1371.每个元音包含偶数次的最长子字符串 参考博主的讲解 思路分析&#xff1a;就是得使用前缀和记录情况&#xff0c;dp[i][j]表示s[0] 到s[i] 中&…...

稀疏混合专家架构语言模型(MoE)

注&#xff1a;本文为 “稀疏混合专家架构语言模型&#xff08;MoE&#xff09;” 相关文章合辑。 手把手教你&#xff0c;从零开始实现一个稀疏混合专家架构语言模型&#xff08;MoE&#xff09; 机器之心 2024年02月11日 12:21 河南 选自huggingface 机器之心编译 机器之心…...

深入理解 `box-sizing: border-box;`:CSS 布局的利器

深入理解 box-sizing: border-box;&#xff1a;CSS 布局的利器 默认行为示例代码 使用 box-sizing: border-box;示例代码 全局应用 box-sizing: border-box;示例代码 实际应用场景1. 表单布局2. 网格布局 总结 在 CSS 中&#xff0c;box-sizing 属性决定了元素的总宽度和高度是…...

MySQL不适合创建索引的11种情况

文章目录 前言1. **数据量小的表**2. **频繁更新的列**3. **低选择性的列**4. **频繁插入和删除的表**5. **查询中很少使用的列**6. **大文本或BLOB列**7. **复合索引中未使用的前导列**8. **频繁进行批量插入的表**9. **查询返回大部分数据的表**10. **临时表**11. **列值频繁…...

shell呈现数据——在脚本中重定向

重定向输出 只需简单地重定向相应的文件描述符&#xff0c;就可以在脚本中用文件描述符STDOUT和STDERR在多个位置生成输出。在脚本中重定向输出的方法有两种。 临时重定向每一行。永久重定向脚本中的所有命令。 下面将具体展示这两种方法的工作原理。 1.临时重定向 如果你…...

vector容器(详解)

本文最后是模拟实现全部讲解&#xff0c;文章穿插有彩色字体&#xff0c;是我总结的技巧和关键 1.vector的介绍及使用 1.1 vector的介绍 https://cplusplus.com/reference/vector/vector/&#xff08;vector的介绍&#xff09; 了解 1. vector是表示可变大小数组的序列容器。…...

【初/高中生讲机器学习】0. 本专栏 “食用” 指南——写在一周年之际⭐

创建时间&#xff1a;2025-01-27 首发时间&#xff1a;2025-01-29 最后编辑时间&#xff1a;2025-01-29 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名高一学生&#xff0c;热爱计…...

SAP SD学习笔记28 - 请求计划(开票计划)之2 - Milestone请求(里程碑开票)

上一章讲了请求计划&#xff08;开票计划&#xff09;中的 定期请求。 SAP SD学习笔记27 - 请求计划(开票计划)之1 - 定期请求-CSDN博客 本章继续来讲请求计划&#xff08;开票计划&#xff09;的其他内容&#xff1a; Milestone请求(里程碑请求)。 目录 1&#xff0c;Miles…...

【PyTorch介绍】

PyTorch 是什么&#xff1f; PyTorch 是一个开源的深度学习框架&#xff0c;由 Facebook 的人工智能研究实验室&#xff08;FAIR&#xff09;开发和维护。它是一个基于 Python 的库&#xff0c;专为深度学习和人工智能研究设计&#xff0c;支持动态计算图&#xff08;dynamic …...

语言月赛 202412【正在联系教练退赛】题解(AC)

》》》点我查看「视频」详解》》》 [语言月赛 202412] 正在联系教练退赛 题目背景 在本题中&#xff0c;我们称一个字符串 y y y 是一个字符串 x x x 的子串&#xff0c;当且仅当从 x x x 的开头和结尾删去若干个&#xff08;可以为 0 0 0 个&#xff09;字符后剩余的字…...

【C++】B2122 单词翻转

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 &#x1f4af;一、我的做法代码实现&#xff1a;代码解析思路分析 &#x1f4af;二、老师的第一种做法代码实现&a…...

redis基本数据结构

基本数据结构 String String是Redis中最常见的数据存储类型&#xff1a; 其基本编码方式是RAW&#xff0c;基于简单动态字符串&#xff08;SDS&#xff09;实现&#xff0c;存储上限为512mb。 如果存储的SDS长度小于44字节&#xff0c;则会采用EMBSTR编码&#xff0c;此时ob…...

基于STM32景区环境监测系统的设计与实现(论文+源码)

1系统方案设计 根据系统功能的设计要求&#xff0c;展开基于STM32景区环境监测系统设计。如图2.1所示为系统总体设计框图。系统以STM32单片机作为系统主控模块&#xff0c;通过DHT11传感器、MQ传感器、声音传感器实时监测景区环境中的温湿度、空气质量以及噪音数据。系统监测环…...

使用冒泡排序模拟实现qsort函数

1.冒泡排序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int arr[] { 0,2,5,3,4,8,9,7,6,1 };int sz sizeof(arr) / sizeof(arr[0]);//冒泡排序一共排序 sz-1 趟for (int i 0; i < sz - 1; i){//标志位&#xff0c;如果有序&#xff0c;直接…...

探秘Linux IO虚拟化:virtio的奇幻之旅

在当今数字化时代&#xff0c;虚拟化技术早已成为推动计算机领域发展的重要力量。想象一下&#xff0c;一台物理主机上能同时运行多个相互隔离的虚拟机&#xff0c;每个虚拟机都仿佛拥有自己独立的硬件资源&#xff0c;这一切是如何实现的呢&#xff1f;今天&#xff0c;就让我…...

在React中使用redux

一、首先安装两个插件 1.Redux Toolkit 2.react-redux 第一步&#xff1a;创建模块counterStore 第二步&#xff1a;在store的入口文件进行子模块的导入组合 第三步&#xff1a;在index.js中进行store的全局注入 第四步&#xff1a;在组件中进行使用 第五步&#xff1a;在组件中…...

从 C 到 C++:理解结构体中字符串的存储与操作

对于刚入门 C/C 的程序员来说&#xff0c;字符串的存储和操作可能是个容易混淆的知识点。在 C 中&#xff0c;std::string 提供了非常友好的接口&#xff0c;我们可以轻松地在结构体中使用字符串类型&#xff0c;无需关注底层细节。然而&#xff0c;在 C 语言中&#xff0c;字符…...

2.3学习总结

图&#xff1a; 1.图的基本概念 2.图的存储和遍历 3.最小生成树 4.最短路径 5.拓扑排序和关键路径 一、图的基本概念 图的定义&#xff1a;不允许没有顶点&#xff0c;但边集可以为空 {无向图 {有向图&#xff1a;边弧&#xff0c;弧头&#xff08;有箭头&#xff09;…...

wordpress代码结构解析

WordPress 是一个基于 PHP 和 MySQL 的开源内容管理系统&#xff08;CMS&#xff09;&#xff0c;广泛用于构建网站和博客。要解析 WordPress 代码&#xff0c;首先需要了解其核心结构、主要文件和常用的函数。以下是 WordPress 代码解析的基本指南&#xff1a; --- ### 1. *…...

使用 Numpy 自定义数据集,使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测,对预测结果计算精确度和召回率及F1分数

1. 导入必要的库 首先&#xff0c;导入我们需要的库&#xff1a;Numpy、Pytorch 和相关工具包。 import numpy as np import torch import torch.nn as nn import torch.optim as optim from sklearn.metrics import accuracy_score, recall_score, f1_score2. 自定义数据集 …...