SpringBoot快速整合canal1.1.5(TCP模式)

SpringBoot快速整合canal1.1.5(TCP模式)

安装并配置MySQL主从⭐
  • 1:Docker安装MySQL8.0.28
docker pull mysql:8.0.28
  • 2:创建目录:
mkdir -p /usr/local/mysql8/data
mkdir -p /usr/local/mysql8/log
mkdir -p /usr/local/mysql8/my.conf.d
chmod -R 777 /usr/local/mysql8/
  • 3:编写my.cnf文件:
vi /usr/local/mysql8/my.conf.d/my.cnf

内容如下:(注意:把binlog-do-db的值修改成你需要canal监听的数据库名称,如果需要监听多个数据库,一定要在下面写多个binlog-do-db,而不是用“,”分隔)

[client]
# 默认字符集
# default_character_set=utf8
[mysqld]
server-id=138
# 开启二进制日志功能
log-bin=mysql-slave-bin
# binlog 记录内容的方式,记录被操作的每一行
binlog_format = ROW
# ------- >>>>指定监听的数据库(防止监听所有数据库)<<<<<----------
binlog-do-db=security-jwt-db
# 忽略大小写
lower_case_table_names=1
pid-file= /var/run/mysqld/mysqld.pid
socket= /var/run/mysqld/mysqld.sock
# 数据库数据存放目录
datadir= /var/lib/mysql
secure-file-priv= NULL
skip-symbolic-links=0
# 最大链接数
max_connections=200
# 最大失败次数
max_connect_errors=10
# 默认时区
default-time_zone='+8:00'
character-set-client-handshake=FALSE
character_set_server=utf8mb4
# default-character-set=utf8
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'
# 默认使用‘mysql_native_password’插件认证
default_authentication_plugin=mysql_native_password
  • 4:启动MySQL容器:
docker run \--name mysql8.0.28 \--privileged=true \--restart=always \-it -p 3308:3306 \-v /usr/local/mysql8/data:/var/lib/mysql \-v /usr/local/mysql8/log:/var/log/mysql \-v /usr/local/mysql8/my.conf.d/my.cnf:/etc/mysql/my.cnf \-e MYSQL_ROOT_PASSWORD=123456 \-d mysql:8.0.28
  • 5:查看mysql容器是否启动成功:
[root@centos7-sql my.conf.d]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
ca41de7447ab   mysql:8.0.28   "docker-entrypoint.s…"   12 seconds ago   Up 11 seconds   33060/tcp, 0.0.0.0:3308->3306/tcp, :::3308->3306/tcp   mysql8.0.28
  • 6:修改密码连接模式(mysql8.0版本都要进行修改):
docker exec -it mysql /bin/bash
mysql -uroot -p'123456'
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
  • 7:在MySQL中创建一个canal用户,专门用作数据同步:
create user 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal';GRANT all privileges ON *.* TO 'canal'@'%';FLUSH PRIVILEGES;
  • 8:退出并重启MySQL容器:
docker restart mysql
docker安装canal1.1.5(版本要对应)⭐
  • 1:拉取canal1.1.5镜像:
docker pull canal/canal-server:v1.1.5
  • 2:运行canal容器:
docker run -p 11111:11111 --name canal \
-e canal.destinations=example \
-e canal.instance.master.address=192.168.184.123:3308  \
-e canal.instance.dbUsername=canal  \
-e canal.instance.dbPassword=canal  \
-e canal.instance.connectionCharset=UTF-8 \
-e canal.instance.tsdb.enable=true \
-e canal.instance.gtidon=false  \
-e canal.instance.filter.regex=security-jwt-db\\..* \
-d canal/canal-server:v1.1.5

核心说明:(只有下面的6个参数才需要我们手动根据自己情况配置,其他可以不用变)

  • -p 11111:11111:这是canal的默认监听端口
  • -e canal.instance.master.address=192.168.184.123:3308数据库地址和端口(一定要设置成你的MySQL对外暴露的IP和端口号才行)
  • -e canal.instance.dbUsername=canal:数据库中canal用户的用户名(也就是我们之前单独创建的用户)
  • -e canal.instance.dbPassword=canal :数据库中canal用户的密码(也就是我们之前单独创建的用户)
  • -e canal.instance.filter.regex=security-jwt-db\\..*:要监听的表名称(我们这个配置的意思是:监听security-jwt-db数据库下的所有表)
  • --network:输入我们刚刚创建好的自定义网络,让canal也加入到和MySQL同一个网络中去。

表名称监听支持的语法:

mysql 数据解析关注的表,Perl正则表达式.
多个正则之间以逗号(,)分隔,转义符需要双斜杠(\\) 
常见例子:
1.  所有表:.*   or  .*\\..*
2.  canal schema下所有表: canal\\..*
3.  canal下的以canal打头的表:canal\\.canal.*
4.  canal schema下的一张表:canal.test1
5.  多个规则组合使用然后以逗号隔开:canal\\..*,mysql.test1,mysql.test2 
整合SpringBoot项目⭐
  • 1:导入依赖:(这个依赖并不是alibaba官方的,而是由其他人帮我们整合了SpringBoot项目,我们只需要去导入这个依赖,再做一些简单的配置即可,非常方便!)
    • 注意:canal-spring-boot-starter的1.2.1-RELEASE版本匹配的是canal的1.1.5版本(canal的新版本没有去试过,不知道有没有问题)
<!--        springboot整合canal1.1.5(因为canal-spring-boot-starter的1.2.1-RELEASE版本匹配的是canal的1.1.5版本) --><dependency><groupId>top.javatool</groupId><artifactId>canal-spring-boot-starter</artifactId><version>1.2.1-RELEASE</version></dependency>
  • 2:配置canal:(application.yml)
    • destination:也就是我们安装canal时执行的docker run … canal中配置的-e canal.destinations的参数内容。
    • server:配置canal所在服务器ip+端口号(默认是11111),记得修改成自己的ip地址
#配置alibaba-canal
canal:destination: example # canal数据同步的目的地。也就是我们安装canal时配置的exampleserver: 192.168.184.123:11111 # canal的地址(canal所在服务器ip+端口号(默认是11111))
# 解决canal-spring-boot-starter一直输出日志
logging:level:top.javatool.canal.client: warn
  • 3:编写实体类(这个类也就是我们要监听操作的实体类)
@TableName(value="sys_oper_log")
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Builder
public class OperationLog implements Serializable {private static final long serialVersionUID = 1L;@TableId("id")@JsonSerialize(using = ToStringSerializer.class) //解决雪花算法生成的id过长导致前端js精度丢失问题(也就是js拿到的数据和后端不一致问题)@ApiModelProperty(name = "id",value = "主键")@ExcelProperty("id")private Long id;@TableField("username")@ApiModelProperty("执行操作的用户名")@ExcelProperty("执行操作的用户名")private String username;@TableField("type")@ApiModelProperty("操作类型")@ExcelProperty("操作类型")private String type;@TableField("uri")@ApiModelProperty("访问的接口uri")@ExcelProperty("访问的接口uri")private String uri;@TableField("time")@ApiModelProperty("访问接口耗时")@ExcelProperty("访问接口耗时")private String time;@TableField("ip")@ApiModelProperty("执行操作的用户的ip")@ExcelProperty("执行操作的用户的ip")private String ip;@TableField("address")@ApiModelProperty("执行操作的用户的ip对应的地址")@ExcelProperty("执行操作的用户的ip对应的地址")private String address;@TableField("browser")@ApiModelProperty("执行操作的用户所使用的浏览器")@ExcelProperty("执行操作的用户所使用的浏览器")private String browser;@TableField("os")@ApiModelProperty("执行操作的用户所使用的操作系统")@ExcelProperty("执行操作的用户所使用的操作系统")private String os;@TableField("oper_time")@ApiModelProperty("操作时间")@ExcelProperty(value = "操作时间",converter = LocalDateTimeConverter.class)private LocalDateTime operTime;@TableLogic//逻辑删除@TableField("del_flag")@ApiModelProperty("删除标志(0代表未删除,1代表已删除)")@ExcelProperty(value = "删除标志",converter = DelFlagConverter.class)private Integer delFlag;}
  • 4:创建一个中转类(也就是说我们报错的原因是OperationLog类中的LocalDateTime属性,这个时候我们可以创建一个新的类,其他字段不变,把这个LocalDateTime日期类变成String就可以解决这个bug)
    • 原因:(这是由于canal+SpringBoot中的StringConvertUtil类的源码的问题):
      • 可以看到下面的源码没有对LocalDateTime转LocalDatetime进行处理,而是把LocalDateTime转为String类型进行返回(问题出在type.equals(java.sql.Date.class) ? parseDate(columnValue) : columnValue),而columnValue是String类型,所以我们可以用String类型去接收LocalDateTime类型。
package com.boot.entity;import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.boot.converter.DelFlagConverter;
import com.boot.converter.LocalDateTimeConverter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import javax.persistence.Column;
import java.io.Serializable;
import java.time.LocalDateTime;/*** 操作日志canal中转类。解决OperationLog类中的LocalDatetime类型的字段无法被canal接收导致报错** @author youzhengjie* @date 2022/10/30 21:16:54*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@Builder
public class OperationLogCanal implements Serializable {private static final long serialVersionUID = 1L;private Long id;private String username;private String type;private String uri;private String time;private String ip;private String address;private String browser;private String os;//canal+springboot当属性名和数据库字段不一致时,要用@Column去指定数据库字段名,否则会接收不到canal数据@Column(name = "oper_time")private String operTime;//canal+springboot当属性名和数据库字段不一致时,要用@Column去指定数据库字段名,否则会接收不到canal数据@Column(name = "del_flag")private Integer delFlag;}
  • 5:OperationLogService
package com.boot.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.boot.entity.OperationLog;import java.util.List;/*** 操作日志服务** @author youzhengjie* @date 2022/10/21 23:32:14*/
public interface OperationLogService extends IService<OperationLog> {long selectAllOperationLogCount();/*** 添加操作日志到elasticsearch** @param operationLog 操作日志* @return boolean*/boolean addOperationLogToEs(OperationLog operationLog);/*** 根据id删除elasticsearch中的操作日志** @param id id* @return boolean*/boolean deleteOperationLogToEs(Long id);/*** 更新elasticsearch中的操作日志** @param operationLog 操作日志* @return boolean*/boolean updateOperationLogToEs(OperationLog operationLog);}
  • 6:OperationLogServiceImpl
package com.boot.service.impl;import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.boot.entity.OperationLog;
import com.boot.mapper.OperationLogMapper;
import com.boot.service.OperationLogService;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.client.core.CountResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** 操作日志服务impl** @author youzhengjie* @date 2022/10/21 23:42:49*/
@Service
@Slf4j
public class OperationLogServiceImpl extends ServiceImpl<OperationLogMapper, OperationLog> implements OperationLogService {@Autowiredprivate OperationLogMapper operationLogMapper;@Autowiredprivate RestHighLevelClient restHighLevelClient;/*** 操作日志的es索引*/private static final String OPER_LOG_INDEX="operation-log-index";@Overridepublic boolean addOperationLogToEs(OperationLog operationLog) {try {IndexRequest indexRequest = new IndexRequest(OPER_LOG_INDEX);indexRequest.id(operationLog.getId().toString());Map<String, Object> sources = new ConcurrentHashMap<>();sources.put("username", operationLog.getUsername());sources.put("type", operationLog.getType());sources.put("uri", operationLog.getUri());sources.put("time", operationLog.getTime());sources.put("ip", operationLog.getIp());sources.put("address",operationLog.getAddress());sources.put("browser", operationLog.getBrowser());sources.put("os", operationLog.getOs());sources.put("operTime", operationLog.getOperTime());sources.put("delFlag", operationLog.getDelFlag());indexRequest.source(sources);restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);return true;}catch (Exception e){e.printStackTrace();return false;}}@Overridepublic boolean deleteOperationLogToEs(Long id) {try {DeleteRequest deleteRequest = new DeleteRequest(OPER_LOG_INDEX);deleteRequest.id(id.toString());restHighLevelClient.delete(deleteRequest,RequestOptions.DEFAULT);return true;}catch (Exception e) {e.printStackTrace();return false;}}@Overridepublic boolean updateOperationLogToEs(OperationLog operationLog) {try {//将operationLog封装成MapMap<String,Object> operationLogMap=new ConcurrentHashMap<>();//将operationLog拷贝到Map中BeanUtil.copyProperties(operationLog,operationLogMap);//把map中的id去掉operationLogMap.remove("id");String idStr = operationLog.getId().toString();UpdateRequest updateRequest = new UpdateRequest(OPER_LOG_INDEX,idStr);updateRequest.doc(operationLogMap);restHighLevelClient.update(updateRequest,RequestOptions.DEFAULT);return true;}catch (Exception e){e.printStackTrace();return false;}}}
  • 7:创建一个canal监听类(非常核心),指定监听一个表(这里我监听的是sys_oper_log表):
package com.boot.canal;import cn.hutool.core.bean.BeanUtil;
import com.boot.entity.OperationLog;
import com.boot.entity.OperationLogCanal;
import com.boot.service.OperationLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;/*** 操作日志canal处理器** @author youzhengjie* @date 2022/10/30 15:19:09*/
@CanalTable("sys_oper_log") //@CanalTable("sys_oper_log"):指定canal监听的表名为sys_oper_log
@Component
@Slf4j
public class OperationLogCanalHandle implements EntryHandler<OperationLogCanal> {@Autowiredprivate OperationLogService operationLogService;@Overridepublic void insert(OperationLogCanal operationLogCanal) {//编写mysql和缓存同步的逻辑(例如JVM本地缓存、Redis分布式缓存、es等)OperationLog operationLog = new OperationLog();//bean拷贝BeanUtil.copyProperties(operationLogCanal,operationLog);//同步到es中operationLogService.addOperationLogToEs(operationLog);log.warn("OperationLogCanalHandle->insert->开始同步->"+operationLog);}/*** 更新** @param before 之前* @param after  之后*/@Overridepublic void update(OperationLogCanal before, OperationLogCanal after) {//编写mysql和缓存同步的逻辑(例如JVM本地缓存、Redis分布式缓存、es等)OperationLog operationLog = new OperationLog();//注意:要拷贝after对象,这个对象是修改之后的对象BeanUtil.copyProperties(after,operationLog);//同步esoperationLogService.updateOperationLogToEs(operationLog);log.warn("OperationLogCanalHandle->update->开始同步->"+operationLog);}@Overridepublic void delete(OperationLogCanal operationLogCanal) {//编写mysql和缓存同步的逻辑(例如JVM本地缓存、Redis分布式缓存、es等)Long id = operationLogCanal.getId();//同步esoperationLogService.deleteOperationLogToEs(id);log.warn("OperationLogCanalHandle->delete->开始同步->"+id);}
}

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

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

相关文章

STL源码剖析系列:其一、list

一、基本用法 list的基本用法比较简单&#xff0c;可以参考站长严长生的教程&#xff1a; C list&#xff08;STL list&#xff09;容器完全攻略&#xff08;超级详细&#xff09; 下面重点介绍list源码。 二、

Web3 React项目Dapp获取智能合约对象

上文Web3 整理React项目 导入Web3 并获取区块链信息中&#xff0c;我们在react搭建的dapp中简单拿到了我们区块链中的账号授权信息 那 我们继续 先终端运行 ganache -d将ganache环境起起来 然后 我们运行 dapp 拿到授权列表 回到上文结束的一个状态 然后 我们发布一下自己的…

ArcGIS统计各种土地利用类型的总面积

如下图为研究区多个村的土地利用现状图,现在需统计每种类型的面积总和,以及每个行政村内各种土地利用类型的总面积。本文通过案例的形式,讲解ArcGIS中两种常用的分类统计面积的工具,建议收藏。 文章目录 1. 加载土地利用数据2. 常规属性汇总统计3. 汇总统计数据1. 加载土地…

软件安利——火绒安全

近年来&#xff0c;以优化、驱动、管理为目标所打造的软件屡见不鲜&#xff0c;大同小异的电脑管家相继走入了公众的视野。然而&#xff0c;在这日益急功近利的社会氛围驱动之下&#xff0c;真正坚持初心、优先考虑用户体验的电脑管家逐渐湮没在了浪潮之中。无论是鲁大师&#…

【C++】string类

STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 为什么学习string类&#xff1f; 1、C语言中的字符串 C语言中&#xff0c;字符串是以\0结尾…

Star History 九月开源精选 |开源 GitHub Copilot 替代

虽然大火了近一年&#xff0c;但是截至目前 AI 唯一破圈的场景是帮助写代码&#xff08;谷歌云旗下的 DORA 年度报告也给 AI 泼了盆冷水&#xff09;。不过对于软件开发来说&#xff0c;生成式人工智能绝对已经是新的标配。 本期 Star History 收集了一些开源 GitHub Copilot …

【用python实现一个压缩文件的解压】

1.想用python实现一个压缩文件的解压 在Python中&#xff0c;可以使用内置的zipfile模块来解压缩文件。以下是一个简单的示例代码&#xff0c;用于解压缩一个zip文件&#xff1a; import zipfile# 指定要解压的zip文件路径 zip_path example.zip# 指定解压后的文件存放目录 …

Python中的Scrapy库

Python中的Scrapy库是一个高效的爬虫框架&#xff0c;用于创建和实现异步的网络爬虫。它提供了一个API来简化爬取网站数据的过程&#xff0c;从而节省开发人员的时间和精力。本篇博客文章将详细介绍Scrapy库的使用和API&#xff0c;并提供相应的代码注释&#xff0c;帮助读者更…

实现多平台兼容性:开发同城外卖小程序的技术策略

在移动互联网时代&#xff0c;外卖行业的快速崛起改变了人们点餐的方式。随着小程序的兴起&#xff0c;开发同城外卖小程序成为了许多企业的重要战略。然而&#xff0c;小程序的多平台兼容性成为了一项关键挑战。本文将探讨如何实现多平台兼容性&#xff0c;以开发高效且用户友…

Scrum master的职责

首先&#xff0c;Scrum master负责建立Scrum团队。同时Scrum master要帮助团队&#xff08;甚至大到公司&#xff09;中的每个成员理解Scrum理论和实践。 Scrum master还需要有很强的软技能&#xff0c;用于指导Scrum团队。Scrum master要对Scrum团队的成功负责任&#xff0c;…

保姆级安装Jdk,Tomact,Mysql在linux中并且部署项目

&#x1f31f;在这里&#xff0c;我要推荐给大家我的专栏《Linux》。&#x1f3af;&#x1f3af; &#x1f680;无论你是编程小白&#xff0c;还是有一定基础的程序员&#xff0c;这个专栏都能满足你的需求。我会用最简单易懂的语言&#xff0c;带你走进代码的世界&#xff0c;…

Ansible初认识

1、简介 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主机。比…

【好书推荐】ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践

前言 计算机技术的发展和互联网的普及&#xff0c;使信息处理和传输变得更加高效&#xff0c;极大地改变了金融、商业、教育、娱乐等领域的运作方式。数据分析、人工智能和云计算等新兴技术&#xff0c;也在不断地影响和改变着各个行业。 如今&#xff0c;我们正在见证人工智能…

使用MobaXterm向linux窗口化传输文件

使用MobaXterm向linux窗口化传输文件 之前上大学的时候&#xff0c;经常是XSheel配合Xftp使用&#xff0c;Xftp可以窗口化的往linux服务器传输文件&#xff0c;但是有一个问题&#xff0c;就是Xftp是收费的。 后来工作之后师兄给推荐了一个免费的&#xff0c;又好用的类似于Xf…

JavaScript重难点整理

1. 数据类型&#xff1a; - 原始类型&#xff1a;数字、字符串、布尔值、null、undefined。 let num 10;let str "Hello";let bool true;let n null;let u undefined;- 引用类型&#xff1a;对象、数组、函数。 let obj { name: "John", age: 25 };l…

基于PyTorch的共享单车使用数量预测研究

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、预测模型的实现3.1数据的获取和预处理3.2划分数据集3.3构建神经网络 二、PyTorch框架三 原理2.1前馈神经网络2.1.1 BP神经网络 四 预测效果验证4.1小批量梯度下降4.2批量梯度下降4.3随机梯度下降 五 结 论目录…

信息安全与网络安全的关系

前言 说说信息安全与网络安全的关系 如果你对网络安全入门感兴趣&#xff0c;那么你需要的话可以点击这里&#x1f449;【入门&进阶全套282G学习资源包免费分享&#xff01;】 一、包含和被包含的关系 信息安全包括网络安全&#xff0c;信息安全还包括操作系统安全&…

12.2 一文读懂i2c-tools工具(i2cdetect、i2cdump、i2ctransfer)

本文主要内容: 1 i2c-tools介绍 2 安装i2c-tools工具 2.1命令行安装 2.2 源码编译安装 2.3 yocto安装 3 i2cdetect 详细示例讲解 4 i2cdump 详细示例讲解 5 i2ctransfer详细示例讲解 6 i2cget详细示例讲解 7 i2cset 详细示例讲解 一 i2c-tools介绍 简介 i2c-tools,主要用来…

NLP 快速入门

文章目录 前言NLP 历史回顾NLP任务语料的标注AI语料标注师岗位职责 TransformersHugging Face模型中文文本分类使用 NLTK 进行文本分类 参考链接开源NLP 前言 学习NLP&#xff0c;解决两个问题&#xff1a; 如何使用别人训练好的模型&#xff1f;如何基于别人的模型&#xff…

1. 一文快速学懂常用工具——Git(上)

本章讲解知识点 什么是Git?为什么要使用版本控制工具?版本控制工具的前世今生本专栏适合于软件开发刚入职的学生或人士,有一定的编程基础,帮助大家快速掌握工作中必会的工具和指令。本专栏针对面试题答案进行了优化,尽量做到好记、言简意赅。如专栏内容有错漏,欢迎在评论…