嵌入式C++、FreeRTOS、MySQL、Spring Boot和MQTT协议:智能零售系统详细流程介绍(代码示例)

项目概述

随着科技的发展,零售行业正经历着一场数字化转型。智能零售系统通过集成嵌入式技术和大数据分析,为商家提供了高效的运营管理工具。该系统的核心目标是提升顾客体验、优化库存管理、降低运营成本以及实现精准营销。

本项目将结合多种技术栈,包括嵌入式硬件、嵌入式软件、网络通信、后端服务器、数据库、大数据处理、数据分析、云平台和前端开发等,构建一个完整的智能零售系统。

系统设计

硬件设计

在硬件方面,智能零售系统主要由以下组件构成:

  • 微控制器:选择Arduino、Raspberry Pi或ESP32作为控制中心,负责数据采集和处理。
  • RFID读取器和标签:用于商品的自动识别和库存管理。
  • 摄像头模块:监控顾客行为,为后续的数据分析提供支持。
  • 重量传感器:用于监测商品重量,辅助识别商品。
  • 蓝牙/WiFi模块:实现设备间的无线通信。

软件设计

在软件方面,系统分为几个主要模块:

  1. 嵌入式软件:使用C/C++进行设备驱动和数据处理,使用FreeRTOS实现实时操作。
  2. 网络通信:采用MQTT协议进行设备间的消息传递,HTTP/HTTPS用于与后端服务器的交互。
  3. 后端服务器:使用Spring Boot(Java)或Django(Python)构建RESTful API,处理业务逻辑。
  4. 数据库:关系型数据库(如MySQL)用于存储用户和商品信息;NoSQL数据库(如MongoDB)用于存储非结构化数据;时序数据库(如InfluxDB)用于存储实时数据。
  5. 大数据处理:使用Apache Spark对大规模数据进行处理和分析。
  6. 数据分析和机器学习:使用Python的NumPy和Pandas库进行数据分析,使用TensorFlow或PyTorch进行模型训练和预测。
  7. 数据可视化:使用Tableau或D3.js进行数据展示和分析结果的可视化。

系统架构图

代码实现

下面是智能零售系统中嵌入式软件部分的示例代码,展示了如何使用Arduino读取RFID数据并通过MQTT发送到服务器。

代码片段:RFID读取模块

#include <SPI.h>
#include <MFRC522.h>
#include <WiFi.h>
#include <PubSubClient.h>

// WiFi和MQTT配置
const char* ssid = "your_SSID";
const char* password = "your_PASSWORD";
const char* mqtt_server = "mqtt.example.com";

WiFiClient espClient;
PubSubClient client(espClient);
MFRC522 rfid(SS_PIN, RST_PIN); // RFID引脚定义

void setup() {
    Serial.begin(115200);
    WiFi.begin(ssid, password);
    client.setServer(mqtt_server, 1883);
    
    SPI.begin();
    rfid.PCD_Init(); // 初始化RFID模块
}

void loop() {
    if (!client.connected()) {
        reconnect(); // 重新连接MQTT
    }
    client.loop();
    
    if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
        String rfidTag = "";
        for (byte i = 0; i < rfid.uid.size; i++) {
            rfidTag += String(rfid.uid.uidByte[i], HEX);
        }
        Serial.println("RFID Tag: " + rfidTag);
        client.publish("retail/rfid", rfidTag.c_str()); // 发布RFID数据
        delay(1000);
    }
}

代码说明

  1. WiFi和MQTT配置

    • const char* ssid 和 const char* password:WiFi网络的名称和密码。
    • const char* mqtt_server:MQTT服务器的地址。
  2. MQTT客户端初始化

    • 创建一个WiFiClient对象和一个PubSubClient对象,用于连接MQTT服务器。
  3. setup()函数

    • Serial.begin(115200):初始化串口通信,波特率设置为115200,方便调试输出。
    • WiFi.begin(ssid, password):连接到指定的WiFi网络。
    • client.setServer(mqtt_server, 1883):设置MQTT服务器的地址和端口(通常为1883)。
  4. RFID模块初始化

    • SPI.begin():初始化SPI总线,用于与RFID模块通信。
    • rfid.PCD_Init():初始化MFRC522 RFID模块。
  5. loop()函数

    • if (!client.connected()):检查MQTT客户端是否已连接。如果未连接,则调用reconnect()函数尝试重新连接。
    • client.loop():保持MQTT客户端的连接,并处理传入的消息。
    • if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()):检查是否有新的RFID卡片被检测到。如果检测到,读取卡片的UID。
    • String rfidTag = "";:初始化一个字符串,用于存储读取到的RFID标签值。
    • for (byte i = 0; i < rfid.uid.size; i++):遍历RFID标签的UID字节,并将其转换为十六进制字符串,存储到rfidTag变量中。
    • Serial.println("RFID Tag: " + rfidTag);:打印读取到的RFID标签值到串口,以便调试。
    • client.publish("retail/rfid", rfidTag.c_str());:将RFID标签值发布到指定的MQTT主题(在这里是retail/rfid),以供后端服务器或其他设备订阅。
    • delay(1000);:延迟1秒,避免重复读取同一张卡片。

后端服务器

1. 使用Spring Boot构建RESTful API

Spring Boot是一个用于快速开发Java应用程序的框架,非常适合构建RESTful API。以下是使用Spring Boot构建简单的用户和商品管理API的示例。

代码示例:Spring Boot RESTful API

1. 项目结构

src
└── main
    ├── java
    │   └── com
    │       └── example
    │           ├── controller
    │           │   └── UserController.java
    │           ├── model
    │           │   └── User.java
    │           ├── repository
    │           │   └── UserRepository.java
    │           └── Application.java
    └── resources
        └── application.properties

2. 应用程序主入口

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3. 用户模型

package com.example.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String username;
    private String email;

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

4. 用户存储库

package com.example.repository;

import com.example.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
}

5. 用户控制器

package com.example.controller;

import com.example.model.User;
import com.example.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userRepository.findById(id)
            .map(user -> ResponseEntity.ok().body(user))
            .orElse(ResponseEntity.notFound().build());
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userRepository.deleteById(id);
        return ResponseEntity.noContent().build();
    }
}

6. 配置文件

src/main/resources/application.properties中,配置数据库连接信息:

spring.datasource.url=jdbc:mysql://localhost:3306/retail_db
spring.datasource.username=root
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

2. 使用Django构建RESTful API

Django是一个强大的Python Web框架,使用Django REST framework可以快速构建RESTful API。

代码示例:Django RESTful API 

1. 环境准备

首先,确保你已经安装Django和Django REST framework。可以使用以下命令安装:

pip install django djangorestframework

2. 创建Django项目和应用

使用以下命令创建Django项目和应用:

django-admin startproject myproject
cd myproject
django-admin startapp myapp

3. 配置项目

myproject/settings.py中,添加myapprest_frameworkINSTALLED_APPS

INSTALLED_APPS = [
    ...
    'rest_framework',
    'myapp',
]

4. 用户模型

myapp/models.py中定义用户模型:

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=100)
    email = models.EmailField()

    def __str__(self):
        return self.username

5. 数据迁移

运行以下命令以生成数据库迁移文件并应用迁移:

python manage.py makemigrations
python manage.py migrate

6. 创建序列化器

myapp/serializers.py中创建序列化器:

from rest_framework import serializers
from .models import User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'  # 或者列出具体字段 ['id', 'username', 'email']

7. 创建视图

myapp/views.py中创建视图:

from rest_framework import generics
from .models import User
from .serializers import UserSerializer

class UserListCreate(generics.ListCreateAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

class UserDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

8. 配置路由

myproject/urls.py中配置路由:

from django.contrib import admin
from django.urls import path
from myapp.views import UserListCreate, UserDetail

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/users/', UserListCreate.as_view(), name='user-list-create'),
    path('api/users/<int:pk>/', UserDetail.as_view(), name='user-detail'),
]

9. 启动开发服务器

在命令行中运行以下命令启动Django开发服务器:

python manage.py runserver

现在,你可以通过访问以下URL来测试API:

  • 获取用户列表GET http://127.0.0.1:8000/api/users/
  • 创建新用户POST http://127.0.0.1:8000/api/users/
  • 获取单个用户GET http://127.0.0.1:8000/api/users/<id>/
  • 更新用户PUT http://127.0.0.1:8000/api/users/<id>/
  • 删除用户DELETE http://127.0.0.1:8000/api/users/<id>/

数据库设计

在智能零售系统中,我们将使用多种数据库来满足不同的数据存储需求:

  1. 关系型数据库(MySQL)

    • 用于存储用户信息、商品信息和订单信息。
    • 例如,User表、Product表和Order表。
  2. NoSQL数据库(MongoDB)

    • 用于存储非结构化数据,例如用户行为日志、商品评论等。
    • 适合快速变化的数据模型。
  3. 时序数据库(InfluxDB)

    • 用于存储实时数据,如销售数据、库存变化等。
    • 适合处理高频率和时间序列的数据。

大数据处理

在智能零售系统中,使用Apache Spark来处理和分析大规模数据。以下是Spark的基本使用示例。

Spark数据处理示例

from pyspark.sql import SparkSession

# 创建Spark会话
spark = SparkSession.builder \
    .appName("RetailDataProcessing") \
    .getOrCreate()

# 读取CSV数据
df = spark.read.csv("sales_data.csv", header=True, inferSchema=True)
# 查看数据框的前几行
df.show()

# 打印数据框的结构
df.printSchema()

# 选择和重命名列
df_selected = df.select(
    df["order_id"].alias("Order ID"),
    df["product_id"].alias("Product ID"),
    df["quantity"].alias("Quantity"),
    df["price"].alias("Price"),
    df["timestamp"].alias("Timestamp")
)

# 计算总销售额
df_total_sales = df_selected.withColumn("Total Sales", df_selected["Quantity"] * df_selected["Price"])

# 按产品ID汇总总销售额
df_sales_by_product = df_total_sales.groupBy("Product ID").agg({"Total Sales": "sum"}).withColumnRenamed("sum(Total Sales)", "Total Sales")

# 按时间段汇总销售额(假设timestamp列是时间戳格式)
from pyspark.sql.functions import window

df_sales_by_time = df_total_sales.groupBy(
    window(df_total_sales["Timestamp"], "1 hour")  # 每小时汇总
).agg({"Total Sales": "sum"}).withColumnRenamed("sum(Total Sales)", "Total Sales")

# 显示结果
df_sales_by_product.show()
df_sales_by_time.show()

# 数据写入(保存处理后的数据到新的CSV文件)
df_sales_by_product.write.csv("output/sales_by_product.csv", header=True)
df_sales_by_time.write.csv("output/sales_by_time.csv", header=True)

# 关闭Spark会话
spark.stop()

代码说明

  1. 查看数据框的前几行

    • df.show():显示数据框的前20行,方便快速查看数据内容。
  2. 打印数据框的结构

    • df.printSchema():打印数据框的结构,包括每一列的名称和数据类型。
  3. 选择和重命名列

    • df.select(...):选择需要的列,并使用alias方法重命名列,方便后续处理。
  4. 计算总销售额

    • df_total_sales:使用withColumn方法添加一个新列"Total Sales",通过计算"Quantity"和"Price"的乘积。
  5. 按产品ID汇总总销售额

    • df_sales_by_product:使用groupByagg方法按"Product ID"进行分组,并计算每个产品的总销售额。
  6. 按时间段汇总销售额

    • window(df_total_sales["Timestamp"], "1 hour"):使用窗口函数按小时对销售额进行汇总。
    • agg({"Total Sales": "sum"}):对每个时间段的销售额进行求和。
  7. 显示结果

    • 使用show()方法展示按产品和时间汇总的销售额数据。
  8. 数据写入

    • write.csv(...):将处理后的数据保存到新的CSV文件中,方便后续使用或分析。
  9. 关闭Spark会话

    • spark.stop():结束Spark会话,释放资源。

数据分析和机器学习

在智能零售系统中,我们可以使用Python的NumPy和Pandas库进行数据分析,并使用TensorFlow或PyTorch进行机器学习模型的训练和预测。

数据分析示例

以下是使用Pandas进行简单数据分析的示例:

import pandas as pd

# 读取CSV文件
df = pd.read_csv("sales_data.csv")

# 查看数据的基本信息
print(df.info())

# 计算总销售额
df['Total Sales'] = df['Quantity'] * df['Price']
total_sales = df['Total Sales'].sum()
print(f"总销售额: {total_sales}")

# 按产品ID汇总总销售额
sales_by_product = df.groupby('product_id')['Total Sales'].sum().reset_index()
print(sales_by_product)

# 可视化(使用Matplotlib或Seaborn库)
import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(10, 6))
sns.barplot(x='product_id', y='Total Sales', data=sales_by_product)
plt.title('按产品ID汇总的总销售额')
plt.xlabel('产品ID')
plt.ylabel('总销售额')
plt.show()

代码说明

  1. 查看数据的基本信息

    • print(df.info()):打印DataFrame的基本信息,包括数据类型、非空值数量和内存使用情况。这对于了解数据集结构和数据质量很有帮助。
  2. 计算总销售额

    • df['Total Sales'] = df['Quantity'] * df['Price']:创建一个新列"Total Sales",通过将"Quantity"(数量)和"Price"(价格)相乘得到每一条记录的总销售额。
    • total_sales = df['Total Sales'].sum():计算"Total Sales"列的总和,以获取所有销售的总额。
    • print(f"总销售额: {total_sales}"):打印总销售额。
  3. 按产品ID汇总总销售额

    • sales_by_product = df.groupby('product_id')['Total Sales'].sum().reset_index()
      • df.groupby('product_id'):按照"product_id"(产品ID)对数据进行分组。
      • ['Total Sales'].sum():对每个产品ID计算其总销售额。
      • reset_index():将结果转换为DataFrame格式,便于后续处理和查看。
    • print(sales_by_product):打印按产品ID汇总的总销售额。
  4. 可视化(使用Matplotlib或Seaborn库)

    • import matplotlib.pyplot as plt:导入Matplotlib库,以便用于绘图。
    • import seaborn as sns:导入Seaborn库,提供更美观的图形样式。
    • plt.figure(figsize=(10, 6)):设置绘图区域的大小为10x6英寸。
    • sns.barplot(x='product_id', y='Total Sales', data=sales_by_product)
      • sns.barplot(...):创建柱状图,x轴为"product_id",y轴为"Total Sales",数据来源于sales_by_product
    • plt.title('按产品ID汇总的总销售额'):设置图形标题。
    • plt.xlabel('产品ID'):设置x轴标签。
    • plt.ylabel('总销售额'):设置y轴标签。
    • plt.show():显示绘制的图形。

数据可视化

在智能零售系统中,数据可视化是一个重要的环节。使用可视化工具可以帮助我们更好地理解数据,识别趋势和模式。我们可以使用如Tableau、Power BI、D3.js等工具进行数据可视化。这里展示一个使用D3.js进行简单数据可视化的示例。

D3.js 数据可视化示例

下面是一个简单的D3.js示例,用于展示按产品ID汇总的总销售额。

HTML结构

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>产品销售额可视化</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        .bar {
            fill: steelblue;
        }
        .bar:hover {
            fill: orange;
        }
        .axis--x path {
            display: none;
        }
    </style>
</head>
<body>
    <svg width="600" height="400"></svg>
    <script>
        // 数据(通常从后端API获取)
        const data = [
            { product_id: 'P1', total_sales: 5000 },
            { product_id: 'P2', total_sales: 7000 },
            { product_id: 'P3', total_sales: 3000 },
            { product_id: 'P4', total_sales: 9000 }
        ];

        const svg = d3.select("svg");
        const margin = { top: 20, right: 30, bottom: 40, left: 40 };
        const width = +svg.attr("width") - margin.left - margin.right;
        const height = +svg.attr("height") - margin.top - margin.bottom;
        const g = svg.append("g").attr("transform", `translate(${margin.left},${margin.top})`);

        const x = d3.scaleBand()
            .domain(data.map(d => d.product_id))
            .range([0, width])
            .padding(0.1);
        const y = d3.scaleLinear()
            .domain([0, d3.max(data, d => d.total_sales)])
            .range([height, 0]);

        // 创建X轴
        g.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", `translate(0,${height})`)
            .call(d3.axisBottom(x));

        // 创建Y轴
        g.append("g")
            .attr("class", "axis axis--y")
            .call(d3.axisLeft(y));

        // 绘制条形图
        g.selectAll(".bar")
            .data(data)
            .enter().append("rect")
            .attr("class", "bar")
            .attr("x", d => x(d.product_id))
            .attr("y", d => y(d.total_sales))
            .attr("width", x.bandwidth())
            .attr("height", d => height - y(d.total_sales));
    </script>
</body>
</html>

代码说明

  1. 引入D3.js库

    • 使用<script src="https://d3js.org/d3.v7.min.js"></script>引入D3.js库,以便使用其功能。
  2. 设置SVG区域

    • <svg width="600" height="400"></svg>:创建一个SVG元素,设置其宽度和高度为600x400像素。
  3. JavaScript代码

    • const data = [...]:定义一个包含产品ID和总销售额的数组。通常,这些数据会通过调用后端API获取,但在这个示例中我们使用静态数据。
  4. 创建SVG画布

    • const svg = d3.select("svg");:选择SVG元素。
    • 定义marginwidthheight,并创建一个新的组(g),以便在指定的坐标系中绘制图形。
  5. 定义坐标比例

    • X轴比例

      const x = d3.scaleBand()
          .domain(data.map(d => d.product_id))
          .range([0, width])
          .padding(0.1);
      
      • 使用d3.scaleBand()创建一个带状比例尺,设置X轴的域为产品ID。
      • range([0, width])表示带状图宽度在0到指定宽度之间。
      • padding(0.1)设置带状图之间的间隔。
    • Y轴比例

      const y = d3.scaleLinear()
          .domain([0, d3.max(data, d => d.total_sales)])
          .range([height, 0]);
      
      • 使用d3.scaleLinear()创建一个线性比例尺,Y轴的域为0到数据中的最大销售额。
      • range([height, 0])将Y轴的值反转,以便在SVG坐标系中适当绘制。
  6. 创建X轴和Y轴

    • 创建X轴:
      g.append("g")
          .attr("class", "axis axis--x")
          .attr("transform", `translate(0,${height})`)
          .call(d3.axisBottom(x));
      
    • 创建Y轴:
      g.append("g")
          .attr("class", "axis axis--y")
          .call(d3.axisLeft(y));
      
    • 这两段代码分别为X轴和Y轴添加坐标轴线和刻度。

项目总结

本项目展示了一个智能零售系统的基本构架,结合了嵌入式技术和大数据分析。通过使用RFID技术识别商品、实时数据传输和分析,我们能够优化库存管理、提高顾客体验和实现精准营销。

这个系统的成功实施需要多种技术的协同工作,包括硬件设计、嵌入式软件开发、网络通信、后端开发、数据存储与处理等。通过不断迭代和优化,智能零售系统将为商家带来更高的效率和收益。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

tree组件实现折叠与展开功能(方式1 - expandedTree计算属性)

本示例节选自vue3最新开源组件实战教程大纲&#xff08;持续更新中&#xff09;的tree组件开发部分。考察响应式对象列表封装和computed计算属性的使用&#xff0c;以及数组reduce方法实现结构化树拍平处理的核心逻辑。 实现思路 第一种方式&#xff1a;每次折叠或展开后触发…

【LeetCode】对称二叉树

目录 一、题目二、解法完整代码 一、题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#…

洗地机哪个牌子好性价比高又实惠?四款洗地机好洗地机的品牌推荐

在追求家居清洁效率与成本效益并重的今天&#xff0c;选择一款性价比高且实惠的洗地机显得尤为重要。市场上洗地机品牌琳琅满目&#xff0c;至于洗地机哪个牌子好性价比高又实惠成为很多人心中的疑问。为此&#xff0c;我们精心搜集并推荐四款洗地机好洗地机的品牌&#xff0c;…

数据结构之跳表SkipList、ConcurrentSkipListMap

概述 SkipList&#xff0c;跳表&#xff0c;跳跃表&#xff0c;在LevelDB和Lucene中都广为使用。跳表被广泛地运用到各种缓存实现当中&#xff0c;跳跃表使用概率均衡技术而不是使用强制性均衡&#xff0c;因此对于插入和删除结点比传统上的平衡树算法更为简洁高效。 Skip lis…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(七)-广播远程识别码(Broadcast Remote ID)

目录 引言 5.5 广播远程识别码&#xff08;Broadcast Remote ID&#xff09; 5.5.1 使用PC5的广播远程识别码 5.5.2 使用MBS的广播远程识别码 引言 3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及…

达梦数据库DM8-索引篇

目录 一、前景二、名词三、语法1、命令方式创建索引1.1 创建索引空间1.2.1 创建普通索引并指定索引数据空间1.2.2 另一种没验证&#xff0c;官方写法1.3 复合索引1.4 唯一索引1.5 位图索引1.6 函数索引 2、创建表时候创建索引3、可视化方式创建索引3.1 打开DM管理工具3.2 找到要…

appium2.0 执行脚本遇到的问题

遇到的问题&#xff1a; appium 上的日志信息&#xff1a; 配置信息 方法一 之前用1.0的时候 地址默认加的 /wd/hub 在appium2.0上&#xff0c; 服务器默认路径是 / 如果要用/wd/hub 需要通过启动服务时设置基本路径 appium --base-path/wd/hub 这样就能正常执行了 方法二…

利用request + BeautifulSoup 模块批量爬取内容,实现批量获取书名对应的豆瓣评分

文章目录 代码代码解释控制台输出结果 代码 #-*- coding:utf-8 -*- from bs4 import BeautifulSoup import requests, time, jsonheaders {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.39…

初识godot游戏引擎并安装

简介 Godot是一款自由开源、由社区驱动的2D和3D游戏引擎。游戏开发虽复杂&#xff0c;却蕴含一定的通用规律&#xff0c;正是为了简化这些通用化的工作&#xff0c;游戏引擎应运而生。Godot引擎作为一款功能丰富的跨平台游戏引擎&#xff0c;通过统一的界面支持创建2D和3D游戏。…

jmeter-beanshell学习11-从文件获取指定数据

参数文件里的参数可能过段时间就不能用了&#xff0c;需要用新的参数。如果有多个交易&#xff0c;读不同的参数文件&#xff0c;但是数据还是一套&#xff0c;就要改多个参数文件。或者只想执行参数文件的某一行数据&#xff0c;又不想调整参数文件顺序。 第一个问题目前想到…

Transformer 翻译

Attention Is All You Need Ashish Vaswani∗ Google Brain avaswanigoogle.com Noam Shazeer∗ Google Brain noamgoogle.com Niki Parmar∗ Google Research nikipgoogle.com Jakob Uszkoreit∗ Google Research uszgoogle.com Llion Jones∗ Google Research lliongoogle.c…

mysql字符类型字段设置默认值为当前时间

-- 2024-07-22 10:22:20 select (DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)); ALTER TABLE tablename MODIFY COLUNN CREATE_DATE varchar (23) DEFAULT(DATE_FORMAT(CURRENT_TIMESTAMP, %Y-%m-%d %H:%i:%s)) COMMENT "创建日期;

力扣最热一百题——2.字母异位词分组

目录 题目链接&#xff1a;49. 字母异位词分组 - 力扣&#xff08;LeetCode&#xff09; 题目 示例 提示 解法一&#xff1a;哈希表排序 思路 代码实现 解法二&#xff1a;记录字母出现的次数哈希表 思路 代码实现 总结 话不多说直接上题目。 题目链接&#xff1a;…

spring MVC 简单案例(3)我的书架管理系统

一、创建项目 最后修改以下 spring 版本 为 2.7.17 Java 版本为 8 同时在 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instanc…

[Python库](3) Arrow库

目录 1.简介 2.安装 3.函数 3.1.获取当前UTC时间( 世界协调时时间 ) 3.2.格式化日期 3.3.创建Arrow对象 3.4.时间改变 3.5.获取时间戳 3.6.时区改变 4.小结 1.简介 Arrow库是一个Python库&#xff0c;提供了一套用于处理日期和时间的API。Arrow库特别适合在需要进行大…

【算法专题】双指针算法之611. 有效三角形的个数(力扣)

欢迎来到CILMY23的博客 &#x1f3c6;本篇主题为&#xff1a;双指针算法之611. 有效三角形的个数&#xff08;力扣&#xff09; &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Li…

web安全之跨站脚本攻击xss

定义: 后果 比如黑客可以通过恶意代码,拿到用户的cookie就可以去登陆了 分类 存储型 攻击者把恶意脚本存储在目标网站的数据库中(没有过滤直接保存)&#xff0c;当用户访问这个页面时&#xff0c;恶意脚本会从数据库中被读取并在用户浏览器中执行。比如在那些允许用户评论的…

Android APP 基于RecyclerView框架工程(知识体系积累)

说明&#xff1a;这个简单的基于RecyclerView的框架作用在于自己可以将平时积累的一些有效demo整合起来&#xff08;比如音视频编解码的、opengles的以及其他也去方向的、随着项目增多&#xff0c;工程量的增加&#xff0c;后期想高效的分析和查找并不容易&#xff09;&#xf…

java题目之评委打分

public class Main5 {public static void main(String[] args) {//在唱歌比赛中&#xff0c;有6名评委打分&#xff0c;分数范围是[0-100]之间的整数//选手的最后得分为&#xff1a;去掉最高分&#xff0c;最低分后的4个评委的平均分&#xff0c;请完成上述过程中并计算选手的得…

python实现责任链模式

把多个处理方法串成一个list。下一个list的节点是上一个list的属性。 每个节点都有判断是否能处理当前数据的方法。能处理&#xff0c;则直接处理&#xff0c;不能处理则调用下一个节点&#xff08;也就是当前节点的属性&#xff09;来进行处理。 Python 实现责任链模式&#…