【智能家居】九、停车场车牌识别功能点(回调、解耦)

news2024/9/20 1:03:53

一、翔云 人工智能开放平台(车牌识别)
二、cJSON 库
三、实现代码
四、回调函数
五、人脸识别和车牌识别获取数据的区别
六、异步网络请求和同步网络请求的区别
七、解耦

一、翔云 人工智能开放平台(车牌识别)

翔云 人工智能开放平台(车牌识别)
在这里插入图片描述

API文档

在这里插入图片描述

返回的json数据格式

{
    "message": {
        "status": "0",
        "value": "识别完成"
    },
    "cardsinfo": [
        {
            "type": "19",
            "items": [
                {
                    "nID": null,
                    "index": null,
                    "desc": "车牌号",
                    "content": "粤A69L59"
                },
                {
                    "nID": null,
                    "index": null,
                    "desc": "车牌颜色",
                    "content": "蓝"
                },
                {
                    "nID": null,
                    "index": null,
                    "desc": "车牌颜色",
                    "content": "1"
                },
                {
                    "nID": null,
                    "index": null,
                    "desc": "车牌类型",
                    "content": "1"
                },
                {
                    "nID": null,
                    "index": null,
                    "desc": "整牌可信度",
                    "content": "86"
                },
                {
                    "nID": null,
                    "index": null,
                    "desc": "亮度评价",
                    "content": "233"
                },
                {
                    "nID": null,
                    "index": null,
                    "desc": "车牌运动方向",
                    "content": "0"
                },
                {
                    "nID": null,
                    "index": null,
                    "desc": "车牌位置(left_top_right_bottom)",
                    "content": "103_210_155_86"
                },
            ]
        }
    ]
}

二、cJSON 库

使用的是 cJSON 库,先确保已经安装该库或者将其包含在你的项目中。以下是一种使用 cJSON 库的方法:

  1. 下载 cJSON 库:

    • 你可以从 cJSON 的 GitHub 仓库下载源代码:cjson GitHub Repository。

    • 或者使用 git 进行克隆:

      git clone https://github.com/DaveGamble/cJSON.git
      
  2. 将 cJSON 库包含到你的项目中:

    • 将 cJSON 目录中的源代码文件(cJSON.ccJSON.h)复制到你的项目中,或者将整个 cJSON 目录拷贝到你的项目目录。
  3. 修改 Makefile 或编译配置文件:

    • 如果你使用 Makefile 进行编译,确保在 Makefile 中添加 cJSON 的源文件。示例 Makefile 可能如下:

      CC = gcc
      CFLAGS = -Wall -I/path/to/cJSON
      LDFLAGS = -lm
      SOURCES = your_source_file.c cJSON.c
      EXECUTABLE = your_executable_name
      
      all:
          $(CC) $(CFLAGS) $(SOURCES) -o $(EXECUTABLE) $(LDFLAGS)
      
    • 如果你使用其他构建工具,确保配置文件中包含 cJSON 的源文件并添加正确的头文件路径。

  4. 编译你的项目:

    • 在终端中进入你的项目目录,运行 make 或者你的构建工具指令。
  5. 链接 cJSON 库:

    • 在你的源文件中添加 #include "cJSON.h" 来包含 cJSON 头文件。

    • 编译时需要链接 cJSON 库。确保在编译命令中包含 cJSON 的源文件。

    • 在上面提供的代码示例中,已经包含了 #include <cjson/cJSON.h>,并且在编译时需要链接 cJSON 库。

以上步骤可能因你的项目和构建系统而异。请根据你的项目结构和构建工具的要求进行相应的修改。

三、实现代码

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cjson/cJSON.h>

// 定义bool类型和常量
typedef unsigned int bool; // 数据类型别名用typedef
#define true 1
#define false 0

char PlateInfo[1024] = {'\0'}; // 全局变量,用来接收从JSON处理后返回车牌的数据

// 封装提取键值对的函数
char *getJsonValueByKey(cJSON *root, const char *key)
{
        cJSON *item = cJSON_GetObjectItem(root, key);
        if (cJSON_IsString(item)) {
                return strdup(item->valuestring); // 使用 strdup 复制字符串
        }
        else {
                return NULL;
        }
}

// 修改处理JSON数据的函数,使其返回提取的数据
char *processJsonData(const char *jsonString)
{
        char *plateNumber = NULL;
        char *plateContent = NULL;

        // 使用 cJSON 解析 JSON 数据
        cJSON *root = cJSON_Parse(jsonString);
        if (root == NULL)
        {
                fprintf(stderr, "Error parsing JSON data\n");
                return NULL;
        }

        // 获取 "cardsinfo" 数组
        cJSON *cardsinfoArray = cJSON_GetObjectItem(root, "cardsinfo");
        if (cJSON_IsArray(cardsinfoArray) && cJSON_GetArraySize(cardsinfoArray) > 0)
        {
                cJSON *firstCard = cJSON_GetArrayItem(cardsinfoArray, 0);

                // 获取 "items" 数组
                cJSON *itemsArray = cJSON_GetObjectItem(firstCard, "items");
                if (cJSON_IsArray(itemsArray) && cJSON_GetArraySize(itemsArray) > 0)
                {
                        // 提取车牌号
                        plateNumber = getJsonValueByKey(itemsArray, "desc");
                        plateContent = getJsonValueByKey(itemsArray, "content");
                }
        }

        // 释放 cJSON 对象
        cJSON_Delete(root);

        // 返回提取的数据
        PlateInfo = (plateNumber != NULL && plateContent != NULL) ? plateContent : NULL;
        return PlateInfo;
}

// 根据文档,接口调用方法为post请求
bool postUrl()
{
        CURL *curl;
        CURLcode res;

        // 根据翔云平台的接口要求  分开定义,然后字符串拼接
        char *img = getBase64FromFile("/home/orangepi/smart_home/test/car.jpg"); // 图片base64流
        char *key = "JFD5c1iBh9LVqPkkZMxxxx";
        char *secret = "76f444813fc945bd9543e4d7e086xxxx";
        int typeId = 19;
        char *format = "json";

        int len = strlen(key) + strlen(secret) + strlen(img) + 128; // 分配空间不够会>导致栈溢出
        char* postString = (char*)malloc(len);
        memset(postString, '\0', len);//因为postString是一个指针,不能用sizeof来计算其指向的大小

        // 字符串拼接
        sprintf(postString, "img=%s&key=%s&secret=%s&typeId=%d&format=%s", img, key, secret, typeId, format);

        curl = curl_easy_init();
        if (curl)
        {
                // 指定post传输内容,get请求将URL和postString一次性发送
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);
                // 指定url
                curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/recogliu.do");
                // 回调函数读取返回值
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);

                // 执行请求
                res = curl_easy_perform(curl);
                if (res != CURLE_OK) {
                        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
                        // 处理错误
                        return false;
                }

                // 处理返回的JSON数据
                processJsonData(PlateInfo);

                // 清理资源
                curl_easy_cleanup(curl);
        }
        // 释放动态分配的内存
        free(img);
        free(postString);

        return true;
}

int main(void)
{
        postUrl();

        // 在这里,你可以直接使用 PlateInfo 来获取 OCR 后台返回的车牌信息
        printf("车牌号是%d", PlateInfo);

        return 0;
}

四、回调函数

回调函数是指在某个特定事件发生时由一个函数调用另一个函数的机制。回调函数通常是作为函数参数传递给其他函数的,以便在特定的事件发生时被调用。这种机制提供了一种灵活的方式,允许在运行时动态指定某个特定事件发生时需要执行的代码。

一般来说,回调函数有以下几个作用:

  1. 事件处理: 用于处理异步事件,如网络请求完成、用户输入等。当事件发生时,系统调用预先注册的回调函数,执行特定的处理逻辑。

  2. 定制行为: 允许用户或开发者提供自定义的行为,以便在某个算法、库或框架中插入自定义的逻辑。这提供了一种扩展和定制代码的方式。

  3. 模块解耦: 回调函数允许将一个模块的实现细节与另一个模块进行解耦。例如,一个库可以提供一个接口,允许用户提供一个回调函数,从而在不修改库源代码的情况下改变其行为。

运用场景包括但不限于:

  1. 图形用户界面(GUI)编程: 处理按钮点击、菜单选择等用户操作时,通过回调函数来执行相应的处理逻辑。

  2. 事件驱动编程: 处理异步事件,如文件读写完成、网络请求完成等,通过注册回调函数来响应这些事件。

  3. 定时器: 在定时器到期时,执行预定的回调函数。

  4. 数据结构的遍历: 在遍历数据结构时,可以使用回调函数来定义对每个元素的处理逻辑。

  5. 框架和库设计: 提供可扩展性,允许开发者通过注册回调函数来扩展和定制框架或库的行为。

回调函数在编程中是一种强大而灵活的技术,可以使代码更模块化、可复用和可扩展。

demo

在这个例子中,我们实现了一个简单的计算器,用户可以选择不同的操作,而计算器会执行相应的操作并通过回调函数返回结果。

#include <stdio.h>

// 回调函数的定义
typedef int (*OperationCallback)(int, int);

// 加法回调函数
int add(int a, int b) {
    return a + b;
}

// 减法回调函数
int subtract(int a, int b) {
    return a - b;
}

// 乘法回调函数
int multiply(int a, int b) {
    return a * b;
}

// 除法回调函数
int divide(int a, int b) {
    if (b != 0) {
        return a / b;
    } else {
        printf("Error: Division by zero\n");
        return 0;
    }
}

// 计算器函数,接受两个操作数和一个回调函数
int calculator(int a, int b, OperationCallback callback) {
    return callback(a, b);
}

int main() {
    int num1, num2;

    printf("Enter two numbers: ");
    scanf("%d %d", &num1, &num2);

    // 提供不同的操作选项
    printf("Select operation:\n");
    printf("1. Addition\n");
    printf("2. Subtraction\n");
    printf("3. Multiplication\n");
    printf("4. Division\n");

    int choice;
    scanf("%d", &choice);

    // 定义回调函数指针
    OperationCallback callback;

    // 根据用户选择设置回调函数
    switch (choice) {
        case 1:
            callback = add;
            break;
        case 2:
            callback = subtract;
            break;
        case 3:
            callback = multiply;
            break;
        case 4:
            callback = divide;
            break;
        default:
            printf("Invalid choice\n");
            return 1;
    }

    // 使用回调函数计算并输出结果
    int result = calculator(num1, num2, callback);
    printf("Result: %d\n", result);

    return 0;
}

在这个示例中,定义了四个不同的回调函数(加法、减法、乘法、除法),然后通过 calculator 函数接受两个操作数和一个回调函数,根据用户的选择调用相应的回调函数。这样就可以在运行时指定不同的操作而无需修改主计算器逻辑。这展示了回调函数的灵活性和可扩展性。

五、人脸识别和车牌识别获取数据的区别

  1. 使用的回调函数是为了在执行 CURL 请求时,通过 CURLOPT_WRITEFUNCTION 选项来指定一个回调函数,将从网络获取的数据写入到 PlateInfo 全局变量中。这样,你可以在请求执行完成后读取 PlateInfo 中的数据,以获取 OCR 后台返回的信息。

  2. 通过 cJSON 库解析 JSON 数据,然后提取了车牌号的信息,将其存储在 PlateInfo 全局变量中。这样,你不再需要回调函数,因为 processJsonData 直接对返回的 JSON 数据进行解析,并将车牌号信息存储在全局变量中。
    两者的区别在于数据获取的时机和方式:

  3. 使用回调函数:

    • 时机: 在执行 CURL 请求时,当从网络获取到数据时,回调函数会被调用。
    • 方式: 通过 CURLOPT_WRITEFUNCTION 选项,你可以指定一个回调函数,该函数将在每次有新数据到达时被调用。在这个回调函数中,你将数据写入到全局变量 PlateInfo 中。这是因为 CURL 在执行请求时是异步的,即它不会等待所有数据都被接收完毕才返回,而是在接收到一部分数据后就触发回调函数。
  4. 不使用回调函数:

    • 时机: 在 CURL 请求执行完成后,你调用 curl_easy_perform 完成请求,并在请求执行完成后直接调用 processJsonData 处理返回的 JSON 数据。
    • 方式: processJsonData 函数直接对返回的 JSON 数据进行解析,并将车牌号信息存储在全局变量 PlateInfo 中。这里是在同步的程序流程中进行的数据处理,而不需要回调函数。

总的来说,使用回调函数适用于异步的网络请求场景,它允许在数据到达时立即处理,而不必等到整个请求完成。而不使用回调函数,则适用于在请求执行完成后立即处理数据的同步场景。在你的具体应用场景中,选择使用回调函数还是不使用回调函数取决于你对程序执行时机的要求。

回调函数的概念和使用在编程中是一种通用的机制,它可以应用在不同的场景,包括处理用户输入、异步操作、模块解耦、事件驱动编程等。
使用回调函数的主要目的是演示其基本概念和应用,而并非专门与 XML 或 JSON 直接相关。然而,回调函数在处理异步操作、事件处理等场景时,常常与数据格式如 JSON 或 XML 一起使用,以更灵活地处理和解析数据。
具体到 XML 和 JSON,它们是用于表示和传输结构化数据的两种不同格式。XML 使用标签来表示数据结构,而 JSON 使用键值对。在网络通信、数据传输等场景中,你可能会遇到需要通过回调函数处理异步获取的 JSON 或 XML 数据的情况。这时,你可以使用回调函数来定义在数据到达时的处理逻辑。

总体而言,回调函数是一种通用的编程概念,而 XML 和 JSON 则是数据格式,它们可以在不同的上下文中结合使用。

六、异步网络请求和同步网络请求的区别

使用回调函数适用于异步的网络请求场景,它允许在数据到达时立即处理,而不必等到整个请求完成。而不使用回调函数,则适用于在请求执行完成后立即处理数据的同步场景。
异步和同步是两种不同的执行模型,用于描述程序中任务的执行方式。

  1. 同步(Synchronous):

    • 在同步模型中,任务按照固定的顺序顺序执行,一个任务的执行会阻塞后续任务的执行,直到当前任务完成。这意味着程序会按照严格的步骤执行,每一步都需要等待前一步完成。
    • 同步操作通常是阻塞的,即程序会等待一个任务完成后再执行下一个任务。这样的模型在代码中通常表现为顺序执行的结构,例如函数调用。
  2. 异步(Asynchronous):

    • 在异步模型中,任务的执行不按照固定的顺序进行,一个任务的开始不会等待前一个任务的完成。程序可以在等待某个任务完成的同时继续执行其他任务。
    • 异步操作通常是非阻塞的,即程序可以继续执行其他任务而不必等待当前任务完成。这样的模型在代码中通常表现为回调函数或事件处理,允许在某个事件发生时执行相应的操作。

异步网络请求和同步网络请求的区别:

  • 同步网络请求:

    • 在发起一个网络请求后,程序会阻塞等待服务器响应。这意味着程序会停止执行,直到请求完成并得到响应。
    • 如果网络连接较慢或服务器响应时间较长,程序可能会在等待中花费较长时间,造成用户体验下降。
  • 异步网络请求:

    • 在发起一个网络请求后,程序不会等待响应。相反,它可以继续执行其他任务。
    • 当请求完成并获得响应时,通过回调函数或其他机制执行相应的操作。这种方式允许程序在等待网络响应的同时继续执行其他操作,提高了程序的并发性和响应速度。

应用于编程中的例子:

// 同步网络请求的例子
int syncHttpRequest() {
    // 发起网络请求
    // 等待服务器响应
    // 处理响应数据
    return 0;
}

// 异步网络请求的例子
void asyncHttpRequest(void (*callback)(int)) {
    // 发起网络请求
    // 不等待服务器响应,继续执行其他任务
    // 请求完成后,执行回调函数处理响应数据
    int responseData = 42; // 模拟响应数据
    callback(responseData);
}

// 示例回调函数
void handleResponse(int data) {
    // 处理响应数据
    printf("Received response: %d\n", data);
}

int main() {
    // 同步网络请求
    int result = syncHttpRequest();
    printf("Result of synchronous request: %d\n", result);

    // 异步网络请求
    asyncHttpRequest(handleResponse);
    printf("Continuing with other tasks...\n");

    // 程序继续执行其他任务,不用等待异步请求完成

    return 0;
}

在这个例子中,syncHttpRequest 是一个同步的网络请求函数,会阻塞程序直到请求完成。而 asyncHttpRequest 是一个异步的网络请求函数,它不会等待响应,而是通过回调函数的方式在请求完成后处理响应数据。这允许程序在等待网络响应的同时继续执行其他任务。

七、解耦

解耦(Decoupling)是指将一个系统的各个部分(或模块、组件)设计得相对独立,降低它们之间的依赖性,使得一个部分的修改不会直接影响到其他部分。这样的设计能够提高系统的灵活性、可维护性和可扩展性。

在软件开发中,解耦通常有以下几个方面的含义:

  1. 模块解耦: 将系统划分为相对独立的模块,每个模块负责一个明确的功能,模块之间通过接口进行通信。这样,修改一个模块的实现不会对其他模块产生影响,从而提高了代码的可维护性。

  2. 组件解耦: 将系统划分为独立的组件,每个组件可以独立开发、测试、部署和升级。组件之间通过定义良好的接口进行通信,使得它们可以被替换或升级而不影响系统的其他部分。

  3. 时间解耦: 尽量避免在时间上的依赖关系。即,一个操作的完成不依赖于其他操作的执行顺序。这样,系统更具弹性,能够适应不同的执行时序。

  4. 数据解耦: 降低模块或组件之间的数据依赖,通过定义良好的接口,使得数据的变化不会对其他部分造成影响。这有助于降低系统的耦合度。

解耦的优势包括:

  • 可维护性: 模块化和组件化的设计使得系统更容易理解和维护。修改一个模块的实现不会影响其他部分。
  • 可扩展性: 可以更容易地添加新的功能或组件,而不必修改现有的代码。
  • 灵活性: 系统的不同部分可以独立开发、测试、部署和维护,提高了灵活性。
  • 可测试性: 独立的模块或组件更容易进行单元测试,从而提高系统的可测试性。

在编程中,回调函数是一种常见的解耦机制。通过将某一功能的实现通过回调函数传递给其他模块或组件,可以使它们之间解耦。当某一事件发生时,执行相应的回调函数,而不需要直接依赖于特定的模块或组件的实现。

理解解耦的概念可以从以下几个方面入手:

  1. 独立性: 解耦的核心思想是使系统的各个部分相对独立,一个部分的修改不应该直接影响其他部分。这意味着每个模块、组件或功能都应该尽可能独立,有自己清晰的职责和接口。

  2. 依赖降低: 解耦的目标之一是降低模块之间的依赖关系。模块之间的耦合越低,修改其中一个模块时对其他模块的影响就越小。这有助于系统更容易扩展、维护和修改。

  3. 接口定义: 定义清晰的接口是解耦的关键。一个模块通过接口与其他模块通信,而不直接访问其内部实现。这样,当一个模块的内部实现发生变化时,只需要保持接口不变,其他模块就不会受到影响。

  4. 模块化和组件化设计: 将系统划分为独立的、相对自治的模块或组件。每个模块负责特定的功能,模块之间通过定义的接口进行通信。这样的设计使得系统更容易被理解、维护和扩展。

  5. 单一职责原则: 每个模块、类或组件应该具有单一职责,即它只负责一个明确的功能。这有助于确保每个部分都是相对独立的,修改一个功能时不会牵扯到其他不相关的功能。

  6. 事件驱动编程: 在某些情况下,使用事件驱动的方式可以帮助解耦。模块之间通过事件进行通信,而不是直接调用对方的方法。当一个事件发生时,相应的处理逻辑被触发,而不需要知道具体的实现。

  7. 依赖注入: 通过依赖注入的方式,将一个模块所需要的依赖通过参数传递给它,而不是在模块内部直接创建依赖。这有助于减少模块对特定实现的依赖,提高了灵活性和可替换性。

通过在实际编程中应用这些原则和技术,你可以逐渐培养对解耦概念的理解。在设计和修改系统时,考虑模块之间的独立性、依赖关系、接口设计等因素,以实现更加灵活、可维护和可扩展的代码结构。

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

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

相关文章

vxe-table 右键菜单+权限控制(v3)

1.menu-config 是用于配置右键菜单的属性。通过 menu-config 属性&#xff0c;定义右键菜单的内容、显示方式和样式。 通过 menu-config 属性配置了右键菜单&#xff0c;其中的 options 属性定义了右键菜单的选项。用户在表格中右键点击时&#xff0c;将会弹出包含这些选项的自…

数据库系统原理与实践 笔记 #12

文章目录 数据库系统原理与实践 笔记 #12事务管理和并发控制与恢复(续)并发控制SQL-92中的并发级别基于锁的协议基于锁的协议的隐患锁的授予封锁协议两阶段封锁协议多粒度粒度层次的例子意向锁类型相容性矩阵多粒度封锁模式基于时间戳的协议基于时间戳协议的正确性基于有效性检…

mysql:用SHOW CREATE TABLE tbl_name查看创建表的SQL语句

https://dev.mysql.com/doc/refman/8.2/en/show-create-table.html 可以用SHOW CREATE TABLE tbl_name查看创建表的SQL语句。 例如&#xff0c;SHOW CREATE TABLE test_table;表示查询创建test_table表的SQL语句&#xff1a;

关于电动机智能综合保护器在煤矿内的应用分析-安科瑞 蒋静

摘要 &#xff1a;介绍了矿用电动机智能综合保护器系统的总体结构&#xff0c;采用直接将交流信号整流、滤波、调理、采样的方式变为微控制器能够识别的直流信号&#xff0c;通过对微控制器采集到的直流信号编程判断来实现对电动机的相关保护控制、故障显示与报警以及与上位机的…

Jmeter性能测试:ForEach控制器的用法解析(含视频讲解)

引言 最近我在进行JMeter性能测试时遇到了一些问题&#xff0c;特别是在使用ForEach控制器时感到有点棘手。 但是经过不断地摸索和实践&#xff0c;终于成功地掌握了这个神奇的工具&#xff0c;提高了我的测试效率。因此&#xff0c;今天我想和大家分享我的经验&#xff0c;让…

优思学院|如何建立公司运营指标体系?如何推行六西格玛改进运营指标?

关键绩效指标 (KPI) 是测量您团队或组织朝重要商业目标进展表现如何的量化指标&#xff0c;组织会在多个层面使用 KPI&#xff0c;这视乎您想要追踪何指标而定&#xff0c;您可以设定全组织的、特定团队的、或甚至是个人 KPI。 良好的KPI能让公司管理者掌握组织的营运是否进度…

【(较大规模)作业车间调度JSP】通过OR-Tools的区间变量建模求解的效率对比实验

文章目录 问题描述Python调用OR-Tools建模求解&#xff08;实验一&#xff09;1. 声明问题的模型2. 创建区间变量3. 创建约束条件4. 求解模型5. 基于 plotly 展示甘特图 不同场景下的求解效率对比实验二&#xff1a;工件的工序数有差异实验三&#xff1a;消除工件的加工时长差异…

php实现个性化域名(短网址)和个性化登录模版的解决方案

在PHP中&#xff0c;个性化域名通常指的是根据用户或业务需求动态生成具有特定规律的子域名。实现个性化域名的方法主要依赖于服务器配置和路由规则。下面是一些基本的步骤和考虑因素&#xff0c;以帮助你了解如何个性化域名&#xff0c;并了解这样做的好处。 如何实现个性化域…

Cohort Analysis是什么

Cohort Analysis 什么是Cohort Analysis Cohort Analysis 可以翻译成 群体分析 或 分组分析&#xff0c;其实是一种通过细分来研究数据的方法。如下表就是一个从每日新增维度细分的 Cohort Analysis 表格。 第一列是分组的维度&#xff0c;下表以用户新增的日期作为细分的维…

Docker安装与使用

Docker 1.初识Docker Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题&#xff1f; Docker允许开发中将应用、依赖、函数库、配置一起打包&#xff0c;形成可移植镜像Docker应用运行在容器中&#xff0c;使用沙箱机制&#xff0c;相互隔离 Docker…

“未来医疗揭秘:机器学习+多组学数据,开启生物医学新纪元“

在当今的数字化时代&#xff0c;科技正在不断地改变着我们的生活&#xff0c;同时也为医疗领域带来了巨大的变革。随着机器学习的快速发展&#xff0c;以及多组学数据在生物医学中的应用&#xff0c;我们正开启一个全新的医疗纪元。这个纪元以精准诊断、个性化治疗和高效康复为…

体验即营销,如何用体验家实现高效的线索细分?

什么是线索细分&#xff1f; 线索细分&#xff0c;指的是将收集而来的线索根据用户行为、特征等信息划分成若干个小组&#xff0c;从而方便市场、运营等部门开展更精细化的营销动作。 为什么要进行线索细分&#xff1f; 不同的客户为企业带来的价值不同。许多情况下&#xff0c…

智能无人零售:革新零售消费体验的未来

智能无人零售&#xff1a;革新零售消费体验的未来 在当今数字化时代&#xff0c;智能无人零售正以惊人的速度改变着我们的购物方式和消费体验。这一新兴领域的发展&#xff0c;为消费者带来了前所未有的便利和个性化选择。 智能无人零售是指利用先进的智能技术和自动化系统&…

(十六)Flask之蓝图

蓝图 Flask蓝图&#xff08;Blueprint&#xff09;是Flask框架中用于组织和管理路由、视图函数以及静态文件的一种机制。它提供了一种将应用程序拆分为更小、可重用组件的方式&#xff0c;使得项目结构更清晰&#xff0c;代码更易于维护。 使用Flask蓝图&#xff0c;可以将相…

git强制回滚,远程强制更新,git pull强制更新

注意&#xff1a;这里是强制回滚&#xff0c;回滚后&#xff0c;之后历史的就没有了&#xff0c;慎用。 本地强制回滚 强制回滚到上一个版本 git reset --hard HEAD^强制回滚上上个版本 git reset --hard HEAD^^git log查看版本 git log --prettyonelinegit log --prettyf…

系列十、SpringBoot + MyBatis + Redis实现分布式缓存(基于注解方式)

一、概述 上篇文章 系列九、SpringBoot MyBatis Redis实现分布式缓存 介绍了基于xml方式实现分布式缓存的效果&#xff0c;当前大家使用的技术栈基本是springboot各种框架的组合&#xff0c;而springboot显著的一个特点就是去xml配置&#xff0c;那么在无xml配置的情形下&…

Java实现选择排序及其动图演示

选择排序是一种简单直观的排序算法。它的基本思想是每次从未排序的元素中选出最小&#xff08;或最大&#xff09;的元素&#xff0c;然后将其放到已排序的序列的末尾。具体步骤如下&#xff1a; 首先&#xff0c;找到未排序序列中的最小&#xff08;或最大&#xff09;元素&a…

关于代码质量度量和分析的一些总结

最近团队做CMMI3认证&#xff0c;这期间涉及到了代码质量度量。花了点时间做了总结&#xff0c;分享给大家。 先看一张整体的图&#xff0c;然后逐个指标展开说明。 一、单元测试覆盖率 单元测试覆盖率&#xff08;Coverage&#xff09;是一个度量单元测试覆盖了多少代码的指标…

Ubuntu系统关闭防火墙的正确方式

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

调用Win10隐藏的语音包

起因 在做一个文本转语音的Demo的时候&#xff0c;遇到了语音包无法正确被Unity识别的问题。明明电脑上安装了语音包但是代码就是识别不出来 原因 具体也不是非常清楚&#xff0c;但是如果语言包是在的话&#xff0c;大概率是Win10系统隐藏了。 确定语言包 首先查看%windi…