和 chatgpt 聊了一会儿分布式锁 redis/zookeeper distributed lock

前言

最近的 chatGPT 很火爆,听说取代程序员指日可待。

于是和 TA 聊了一会儿分布式锁,我的感受是,超过大部分程序员的水平。

在这里插入图片描述

Q1: 谈一谈 java 通过 redis 实现分布式 锁

chatGPT:

Java通过Redis实现分布式锁,是在多个Java应用程序之间实现同步的一种方式。通过Redis的原子性和高性能,实现了分布式锁的可靠性和高效性。具体实现步骤如下:获取Redis连接:在Java应用程序中,使用Java Redis客户端连接到Redis数据库。创建锁:Java应用程序向Redis数据库中写入一条记录,作为锁。设置过期时间:为了避免死锁,需要为锁设置一个过期时间。判断是否获取到锁:Java应用程序从Redis数据库中读取锁记录,判断当前是否已经有其他应用程序获取到了锁。如果没有,则当前应用程序获取到了锁,可以执行需要同步的操作。释放锁:Java应用程序在同步操作完成后,从Redis数据库中删除锁记录,释放锁。在实现分布式锁时,需要注意以下几点:锁的名字应该是唯一的,并且易于识别和管理。设置过期时间是为了避免锁一直被占用而无法释放。应该采用原子性操作来实现锁,以避免出现多个线程同时访问锁而导致的并发问题。需要考虑锁的持有时间,避免出现死锁的情况。总之,通过Redis实现分布式锁可以很好地解决多个Java应用程序之间同步的问题。Java应用程序可以通过Redis实现高效、可靠的分布式锁,提高分布式应用程序的性能和可靠性。

我们针对过期时间附加两个小问题。

Q1.1 谈一谈 redis 分布式锁中,锁的过期时间应该设置多久才合理呢

chatGPT:

在 Redis 分布式锁中,锁的过期时间的设置需要考虑到两个方面的因素:锁的超时时间和业务处理时间。如果锁的超时时间设置过短,那么在高并发的情况下,可能会出现多个进程同时获取到锁的情况,从而导致锁失效,出现并发问题。因此,通常建议将锁的过期时间设置为稍微长一些,可以考虑设置为 30 秒到 1 分钟左右。另外,还需要考虑业务处理时间。如果业务处理时间很长,而锁的过期时间很短,那么在业务处理期间锁失效,就会导致其他进程在锁被释放前获取到锁,从而导致并发问题。因此,需要根据业务处理时间来合理地设置锁的过期时间,通常建议将锁的过期时间设置为业务处理时间的两倍以上。需要注意的是,锁的过期时间设置过长也会带来风险,例如当获取锁的进程崩溃或被终止时,其他进程无法获取到锁,从而导致死锁问题。因此,在设置锁的过期时间时需要综合考虑以上因素,找到一个合理的平衡点。

Q1.2 如果系统正常业务 30秒处理完成,但是系统受到了攻击,导致处理时间变慢。这个时候,分布式锁的过期时间要怎么设置才合理呢?要求一定不能出错,涉及到金额

chatGPT:

如果系统受到攻击导致处理时间变慢,那么锁的过期时间要根据实际情况进行设置。通常建议将锁的过期时间设置为业务处理时间的两倍以上,但是如果系统受到攻击,处理时间远远超过了正常的业务处理时间,那么在这种情况下,就需要将锁的过期时间适当延长,以确保在极端情况下锁不会过早失效。具体来说,可以考虑以下两种方案:动态调整锁的过期时间:当系统受到攻击时,动态调整锁的过期时间。可以根据当前的业务处理时间来决定过期时间的长度,如果业务处理时间变长,就将过期时间适当延长。采用异步处理的方式:将耗时较长的操作改为异步处理,从而避免阻塞主线程,减少对分布式锁的占用时间。在这种情况下,可以将锁的过期时间设置为正常的业务处理时间的两倍左右。需要注意的是,在设置锁的过期时间时,一定要根据实际情况进行合理的设置。如果过期时间设置过短,会导致锁失效,出现并发问题;如果过期时间设置过长,会带来死锁的风险。因此,在设置锁的过期时间时,需要综合考虑业务处理时间和系统稳定性等因素,找到一个合理的平衡点。同时,在实际应用中,也可以结合监控系统和预警机制,及时发现和处理系统异常情况,保障系统的稳定性和安全性。

说的倒也算不错,让他给一下代码。

Q2: 给出具体的代码实现

下面是Java通过Redis实现分布式锁的代码示例:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;public class RedisLock {private Jedis jedis;private String lockKey;private String lockValue;private int expireTime;public RedisLock(Jedis jedis, String lockKey, String lockValue, int expireTime) {this.jedis = jedis;this.lockKey = lockKey;this.lockValue = lockValue;this.expireTime = expireTime;}public boolean acquire() {SetParams setParams = new SetParams();setParams.nx();setParams.ex(expireTime);String result = jedis.set(lockKey, lockValue, setParams);if ("OK".equals(result)) {return true;}return false;}public boolean release() {String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(luaScript, 1, lockKey, lockValue);if ("1".equals(result.toString())) {return true;}return false;}
}

chatGPT 的解释:

在上面的代码中,我们定义了一个RedisLock类,用于封装获取和释放锁的操作。其中,acquire()方法用于获取锁,release()方法用于释放锁。在获取锁时,我们使用Redis的set()方法设置一个键值对,并使用NX(不存在则创建)和EX(过期时间)两个参数来保证锁的原子性和可靠性。如果set()方法返回的结果为"OK",则表示获取到了锁,可以执行同步操作。在释放锁时,我们使用Redis的eval()方法执行一个Lua脚本,判断当前锁的值是否为当前线程所持有的值。如果是,则调用Redis的del()方法删除该键值对,释放锁。需要注意的是,在使用Redis实现分布式锁时,我们需要确保获取和释放锁的操作是原子性的。同时,我们也需要考虑锁的过期时间,避免出现死锁的情况。

诚然,这个代码写的作为入门是够用了。

1) 但是还是有一些改进空间,比如 expireTime/lockKey/lockValue 应该作为方法的参数。

其实 AI 无论怎么发展,我们还是需要知道底层的原理,不然都不知道如何改进

对于程序员如此,对于画师也是如此。

2)这个是单点的算法,我们问一下如何解决。

Q3:如果 redis 是多个节点,存在主节点重启,上面的方法存在什么问题?

chatGPT:

如果 Redis 是多个节点,存在主节点重启,上面的代码实现可能会出现如下问题:主节点重启后,由于获取锁和释放锁的操作不在同一个节点上,可能会导致锁的失效或者其他线程获取到该锁,从而导致数据不一致的情况。如果Redis的主从复制模式中,主节点重启后从节点升为主节点,那么原来的锁信息将无法被获取和释放。为了解决这些问题,可以考虑使用Redis的RedLock算法。RedLock算法是由Redis的创始人Salvatore Sanfilippo提出的一种分布式锁方案,可以在多个节点之间协作实现可靠的分布式锁。具体来说,RedLock算法使用多个Redis节点组成一个集群,获取锁和释放锁的操作在多个节点上执行,并且需要满足以下条件:获取锁时,至少在大部分(如5个节点中的3个)节点上获取到锁才算成功获取到锁。释放锁时,需要向所有节点发送释放锁的请求,只有大部分节点(如5个节点中的3个)成功释放锁才算成功释放锁。通过这样的方式,可以在多个节点之间协作实现可靠的分布式锁,避免出现单点故障和数据不一致的情况。以下是使用Java代码实现RedLock算法的示例:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.params.SetParams;import java.util.ArrayList;
import java.util.List;public class RedisRedLock {private List<Jedis> jedisList;private String lockKey;private String lockValue;private int expireTime;private int quorum;public RedisRedLock(List<Jedis> jedisList, String lockKey, String lockValue, int expireTime) {this.jedisList = jedisList;this.lockKey = lockKey;this.lockValue = lockValue;this.expireTime = expireTime;this.quorum = jedisList.size() / 2 + 1;}public boolean acquire() {int count = 0;long startMillis = System.currentTimeMillis();while ((System.currentTimeMillis() - startMillis) < expireTime) {for (Jedis jedis : jedisList) {SetParams setParams = new SetParams();setParams.nx();setParams.ex(expireTime);String result = jedis.set(lockKey, lockValue, setParams);if ("OK".equals(result)) {count++;}if (count >= quorum) {return true;}}}return false;}public boolean release() {boolean success = true;for (Jedis jedis : jedisList) {String luaScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(luaScript, 1, lockKey, lockValue);if(!(result instanceof Long) || (Long) result != 1)) {success = false;}}return success;
}
在上述示例代码中,RedisRedLock类表示了一个RedLock分布式锁,包括多个Redis节点、锁的名称、锁的值、锁的过期时间等属性,以及获取锁和释放锁的方法。在获取锁时,需要循环遍历多个Redis节点,使用NX(不存在则创建)命令尝试在Redis中创建一个新的key-value对,并设置过期时间。只有当大部分节点(如5个节点中的3个)都成功获取到锁时,才算获取锁成功。在释放锁时,需要向所有节点发送释放锁的请求,使用Lua脚本来判断当前锁是否为当前线程持有,如果是则释放锁,否则返回0表示锁已被其他线程持有。需要注意的是,使用RedLock算法可以提高分布式锁的可靠性和稳定性,但是并不能完全避免分布式锁的问题。例如,当Redis节点之间的网络延迟较大时,可能会导致某些节点无法及时获取到锁信息,从而出现数据不一致的情况。因此,在使用RedLock算法时,需要仔细评估应用场景和业务需求,权衡分布式锁的可靠性和性能,以便选择最适合的方案。

当然,redlock 也并非是完美的,可以参考下面的文章:

redis 分布式锁设计 redis lock

Q4: RedLock 存在什么缺点?如何解决

chatGPT:

RedLock算法虽然可以提高分布式锁的可靠性和稳定性,但仍然存在一些缺点和局限性,如下所述:可能存在网络分区问题:在Redis集群节点之间的网络延迟较大或出现网络分区时,可能会导致某些节点无法及时获取到锁信息,从而出现数据不一致的情况。Redis节点故障问题:如果一个或多个Redis节点发生故障或宕机,可能会导致某些节点无法正常工作,从而影响分布式锁的可用性和性能。同时获取锁的线程数量问题:RedLock算法中要求大部分节点都需要获取到锁才能认为获取成功,但是如果同时有大量线程请求获取锁,可能会导致节点的处理能力不足,从而导致获取锁的时间过长。针对上述缺点和局限性,可以采取以下措施进行解决:使用多个Redis集群:为了避免网络分区和节点故障等问题,可以使用多个Redis集群进行分布式锁的实现,从而提高可用性和稳定性。采用自适应锁超时时间:针对同时获取锁的线程数量问题,可以根据实际情况采用自适应的锁超时时间,避免获取锁的时间过长。使用其他分布式锁方案:RedLock算法虽然具有一定的优势,但并不是适用于所有场景。根据实际需求,可以选择其他分布式锁方案,如基于ZooKeeper实现的分布式锁等。

Q5: java 语言,使用 zookeeper 如何实现分布式锁

chatGPT:

在Java语言中,可以使用ZooKeeper实现分布式锁,具体步骤如下:创建ZooKeeper客户端连接:使用ZooKeeper提供的Java API创建一个ZooKeeper客户端连接,用于访问ZooKeeper服务。创建锁节点:在ZooKeeper中创建一个顺序临时节点,表示当前请求获取锁的节点。如果创建成功,则表示当前节点获取到了锁,否则需要等待。监听前一个节点的删除事件:当前节点创建完成后,需要监听前一个节点的删除事件,一旦前一个节点被删除,说明前一个节点已经释放了锁,当前节点可以获取到锁。释放锁:释放锁时需要删除当前节点。以下是一段基于ZooKeeper实现分布式锁的Java代码示例:
public class DistributedLock {private ZooKeeper zooKeeper;private String lockPath;private String lockName;private String currentNodePath;private String previousNodePath;public DistributedLock(ZooKeeper zooKeeper, String lockPath, String lockName) {this.zooKeeper = zooKeeper;this.lockPath = lockPath;this.lockName = lockName;}public void lock() throws Exception {// 创建锁节点currentNodePath = zooKeeper.create(lockPath + "/" + lockName + "-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);// 获取锁节点的序号int currentNodeSeqNum = Integer.parseInt(currentNodePath.substring(currentNodePath.lastIndexOf('-') + 1));// 获取锁节点的父节点下的所有子节点List<String> children = zooKeeper.getChildren(lockPath, false);// 对子节点进行排序Collections.sort(children);// 获取当前节点在子节点列表中的位置int currentNodeIndex = children.indexOf(currentNodePath.substring(lockPath.length() + 1));// 如果当前节点是第一个节点,则获取锁成功if (currentNodeIndex == 0) {return;}// 获取前一个节点的路径previousNodePath = lockPath + "/" + children.get(currentNodeIndex - 1);// 监听前一个节点的删除事件Stat stat = zooKeeper.exists(previousNodePath, new Watcher() {@Overridepublic void process(WatchedEvent event) {try {lock();} catch (Exception e) {e.printStackTrace();}}});// 如果前一个节点已经不存在,则重新获取锁if (stat == null) {lock();} else {synchronized (this) {wait();}}}public void unlock() throws Exception {zooKeeper.delete(currentNodePath, -1);}
}
在这个示例代码中,我们首先创建了一个ZooKeeper客户端连接,然后定义了一个DistributedLock类来实现分布式锁,其中lockPath表示锁节点的路径,lockName表示锁节点的名称。在lock()方法中,我们首先创建了一个顺序临时节点,然后获取锁节点的序号和当前节点在子节点列表中的位置,如果当前节点是第一个节点,则获取锁成功;

有一说一,对于基本不会使用 zookeeper 的开发者而言,上面的代码作为入门还是不错的。

但是最后我们还是需要理解原理,作为学习路上的良师益友,chatGPT 是当之无愧的。

Q6:zookeeper 是 AP 还是 CP?如果是 CP,那么出现服务不可用怎么办?

他推荐我们使用 zk,我们就问一下 cp 的问题。

chatGPT:

ZooKeeper是一个CP系统,即在网络分区的情况下,系统优先保证一致性,而可能牺牲可用性。在ZooKeeper集群中,一旦发生网络分区,可能会导致部分节点无法连接到主节点,这时候这部分节点就会成为不可用状态。对于这种情况,可以采取以下措施:保证集群的健康状态:在使用ZooKeeper的过程中,需要对集群进行定期的监控,确保每个节点的健康状态,及时发现故障。使用重试机制:如果某个节点无法连接到主节点,可以采用重试机制,等待一段时间后再次尝试连接,如果仍然失败,可以通过切换到备用节点来保证服务的可用性。合理设置超时时间:在使用ZooKeeper时,需要设置合理的超时时间,以便在出现网络分区等异常情况时,能够及时检测并作出相应的处理。总之,在使用ZooKeeper实现分布式锁时,需要考虑到网络分区等异常情况,采取相应的措施来保证服务的可用性和一致性。

Q7: redis 和 zookeeper 实现分布式锁,你总结一下二者的利弊,对比一下。详细的表格

感觉聊的差不多了,我们让 chatGPT 出一个对比的表格。

chatGPT:

下面是Redis和ZooKeeper实现分布式锁的利弊对比表格:
特点RedisZooKeeper
数据结构Redis使用字符串数据类型存储锁信息ZooKeeper使用ZNode节点存储锁信息
实现方式Redis使用单节点或者Redis集群实现分布式锁ZooKeeper使用ZooKeeper集群实现分布式锁
性能Redis读写速度较快,适用于高并发场景ZooKeeper在写入数据时需要进行同步操作,写入速度相对较慢
可靠性Redis的主从复制和Sentinel保证了Redis集群的高可用性ZooKeeper采用了Paxos算法保证了集群的数据一致性和高可用性
稳定性Redis的稳定性较好,不易出现死锁和脑裂等问题ZooKeeper在网络分区时可能出现脑裂问题,需要进行特殊处理
开发难度Redis的API简单易用,易于开发和维护ZooKeeper的API较为复杂,需要一定的开发经验和技术储备
功能扩展Redis支持多种数据结构和数据操作,具有更强的功能扩展性ZooKeeper主要用于分布式协调和服务发现等场景,功能相对局限
总的来说,Redis适合处理高并发、读写频繁的场景,而ZooKeeper则更适合处理数据一致性和高可用性要求较高的场景。在开发实践中,需要根据具体的业务需求和系统特点选择合适的分布式锁实现方式。

Q8: 你建议使用哪一种方式呢

chatGPT:

建议根据具体业务场景和系统架构选择合适的分布式锁实现方式。如果业务场景中主要是处理高并发请求,读写操作较为频繁,且对数据一致性要求不是特别高,可以优先考虑Redis实现分布式锁。如果系统对数据一致性和高可用性要求较高,可以考虑使用ZooKeeper实现分布式锁。同时,如果系统中同时使用了Redis和ZooKeeper,可以考虑综合使用两者实现更为灵活和可靠的分布式锁方案。

他说到了结合二者,怎么个结合法?

Q9:综合使用两者实现是什么意思?展开说一说

chatGPT:

综合使用Redis和ZooKeeper实现分布式锁,主要是将两者的优势结合起来,达到更好的性能和可靠性。一种常见的方式是,使用Redis实现分布式锁的快速获取和释放,同时使用ZooKeeper实现分布式锁的可靠性和数据一致性。具体实现方式是:使用Redis的SETNX命令获取锁,如果获取成功,则表示获取到了分布式锁;否则,等待一段时间再次尝试获取锁。获取到锁之后,设置锁的过期时间,并在Redis中记录当前线程持有锁的标识,用于后续释放锁时进行验证。在业务逻辑执行完成后,使用Lua脚本或Redis的事务机制,保证释放锁的原子性。释放锁时,首先验证当前线程持有锁的标识,如果匹配,则使用Redis的DEL命令删除锁的标识,释放锁。同时,将锁的释放同步到ZooKeeper中。在释放锁时,使用ZooKeeper的分布式锁机制,确保同一时刻只有一个线程可以修改锁的状态,避免多个线程同时释放锁的问题。综合使用Redis和ZooKeeper实现分布式锁,既可以保证锁的获取和释放的高效性,又可以确保分布式锁的数据一致性和高可用性,是一种比较优秀的分布式锁实现方案。

Q10: 这样不会导致复杂性变高吗?如果二者不一致怎么办

chatGPT:

综合使用Redis和ZooKeeper实现分布式锁的确会增加一定的复杂性,需要更多的编码工作和配置调整,但是它能够更好地满足分布式锁的可靠性和高可用性要求,确保分布式锁的正确性和稳定性。在使用Redis和ZooKeeper时,确实存在二者之间的数据一致性问题,例如锁在Redis中已经被释放,但在ZooKeeper中还未被删除,或者锁在ZooKeeper中已经被释放,但在Redis中还未被删除。如果发生这种情况,就会导致分布式锁的状态不一致,可能会造成一些问题。为了避免这种情况,可以采用以下几种方式:尽可能减少使用两种不同的分布式锁实现,如果可以,最好使用Redis或ZooKeeper其中一种实现分布式锁,而不是两者同时使用。在代码实现时,加入检查分布式锁状态的逻辑,确保Redis和ZooKeeper中的分布式锁状态一致,例如在释放分布式锁时,先检查Redis中的锁是否已经被删除,再去ZooKeeper中删除锁的状态。使用心跳机制定期同步两种分布式锁实现之间的状态,例如每隔一段时间,在Redis中设置一个带有过期时间的key,同时在ZooKeeper中创建一个持久化节点,表示分布式锁的状态,每次检查分布式锁状态时,都先在Redis中检查是否过期,如果过期则到ZooKeeper中检查分布式锁状态。

小结

chatGPT 其实比一般的博文质量要高不少,而且可以不停地提问拓展,对于知识的学习和拓展很有帮助。

但是需要我们有一定的辨别能力,因为他可能会胡说八道,而且死不悔改。

AI 不会取代人,只有会说用 AI 的人取代不会使用 AI 的人

我是老马,期待与你的下次重逢。

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

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

相关文章

kafka会丢消息的时刻

十家面试&#xff0c;有八家会问的问题:“kafka会不会丢消息呢”。 有些情况下消息可能会消失。这可能是由于配置错误或误解Kafka的内部原理所致。本文将解释数据丢失可能发生的情况 Provider(Publisher):确认的时候 当消息被发送到发布者时&#xff0c;发布者等待来自代理的…

宕机了,Redis 如何避免数据丢失?

程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 8 分钟。 来自&#xff1a;juejin.cn/post/7193597571305046071 前言AOF 日志是如何实现的写后日志的优势与风险日志的写回策略日志的重写 重写的作用重写的过程RDB快照的原理混合 AOF/RDB总结 前言 如果…

硬件大熊原创合集(2023/02更新)

技术2月份更新篇章&#xff1a; 问了ChatGPT几个硬件问题 智能开关保险丝选型&安规要求 智能墙壁开关电源篇——AC-DC概述 这个月花了很多的精力在梳理产品的技术架构&#xff0c;过程中总会发现很多自己尚且模棱两可的知识点&#xff0c;这让人有一种摸索的越多&#xff0…

足球、篮球、乒乓球的动作识别通用方案开源

北京冬奥会即将开幕&#xff0c;全民健身如火如荼。2020年夏季奥运会有46项体育项目&#xff0c;2022年冬奥会有15项体育项目&#xff0c;丰富的项目涉及的姿势标准也各有区别。运动员如何科学地进行体育锻炼、准确矫正健身动作&#xff1f;教练员如何借助技术提供更智能化的训…

电商导购CPS,淘宝联盟如何跟单实现用户和订单绑定

前言 大家好&#xff0c;我是小悟 做过自媒体的小伙伴都知道&#xff0c;不管是发图文还是发短视频&#xff0c;直播也好&#xff0c;可以带货。在你的内容里面挂上商品&#xff0c;你自己都不需要囤货&#xff0c;如果用户通过这个商品下单成交了&#xff0c;自媒体平台就会…

高考英语口语测试软件,练习英语口语的app有哪些

随着国际化的发展&#xff0c;英语越来越普遍。英语中口语也是很重要的成分之一。也是跟老外交流或者英语考试的重要考点之一。我们有很多方法锻炼口语。什么方法最快捷最有效方便&#xff1f;下面我们看看几款最受欢迎的英语口语练习app。 练习口语的app 1、口语侠 一款非常实…

几个常见的语音交互平台的简介和比较

1.概述 最近做了两个与语音识别相关的项目&#xff0c;两个项目的主要任务虽然都是语音识别&#xff0c;或者更确切的说是关键字识别&#xff0c;但开发的平台不同&#xff0c; 一个是windows下的&#xff0c;另一个是android平台的&#xff0c;于是也就选用了不同的语音识别平…

Chatbot UI老外在用的gpt网页版 搭建方法分享!

新建了一个网站 https://ai.weoknow.com/ 每天给大家更新可用的国内可用chatGPT资源 Chatbot UI 高仿ChatGPT官网&#xff0c;中文还支持贼好&#xff0c;界面美观度间距还需要打磨。是老外做的吗&#xff1f; ​ 环境部署 更新环境 apt update -y && apt upg…

小米多模网关通过telnet刷入改版固件,完美接入HASS

一、环境介绍 宿主机&#xff1a;树莓派3B Raspbian系统 HA安装方式&#xff1a;HASS系统使用hass.io一键脚本进行安装 多模网关&#xff1a;ZNDMWG03LM&#xff08;软件版本v1.4.5_0012&#xff09; 2、为什么要刷固件 A 、因为要把该多模网关接入到homeassistant&#xf…

国际交流学术英文写作hnu(仅供参考)

本文仅供参考&#xff0c;希望同学们继续加油&#xff01;

用letax写毕业论文-- 中英文封面

一、中文封面&#xff1a; 中文封面主要是 姓名、专业、指导教师、培养单位 这几项对齐这里比较麻烦&#xff0c; 我是用 tabular 来描述这个部分&#xff0c;然后字数不够的补空格 i.e. \hspace*{0.67em}. 具体实现代码如下&#xff1a; 二、 英文封面 英文封面跟中文封面类…

新手请看这里,如何撰写一篇英文论文

第一次写英文论文&#xff0c;无论是期刊论文、还是会议论文&#xff0c;都是很苦很累的一件事情。 查找文献、阅读文献&#xff0c;当然&#xff0c;主要都得是英文的&#xff0c;再加上真正动手撰写&#xff0c;这些环节都在考验我们的英文阅读和写作能力。 在科研这条路上…

【中英文论文写作——图片和表格】

1. 前言 前期讲了论文头部和正文&#xff0c;接下来分享论文写作之图片和表格&#xff0c;属于锦上添花部分&#xff01; 2. 图片和表格要求 图标要求&#xff1a;专业性&#xff0c;美观性&#xff0c;简洁性 Chart Suggestions: A Thought Starter (Andrew Abela) 3. 软件推…

ChatGPT能够帮留学生完成毕业论文写作吗?

ChatGPT采用交互式对话界面&#xff0c;根据用户输入的指令以近似人类交流的方式作出回应&#xff0c;自问世以来一直令世人为之惊叹。目前&#xff0c;ChatGPT已成为有史以来用户增长速度最快的应用程序。 与此同时&#xff0c;研究人员对学术写作的关注程度与日俱增。人工智能…

【论文写作】——设置中英文字体

打开文件 点击选项 选择高级 取消中文字体也应用于西文的勾选 然后选中全文&#xff0c;设置中文字体为宋体&#xff0c;设置英文字体为times new Roman。

谷歌学术中英文网址

之前用谷歌学术的时候一直用的是https://scholar.google.com/这个网址&#xff0c;这个是谷歌学术的国外版比较适合生成外文期刊格式的参考文献&#xff0c;如下图所示&#xff1a;   但国内写文献参考格式的时候大多是采用GPT格式&#xff0c;这个在谷歌学术国外版是直接生…

一个典型的语音识别系统

一个典型的语音识别系统 标签&#xff1a; 语音识别 2015-01-05 16:56 3966人阅读 评论(0) 收藏 举报 分类&#xff1a; 自然语言识别研究&#xff08;9&#xff09; 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 一、语音识别技术 转载请表…

语音识别系列1:语音识别Speech recognition综述

目录 1 什么是语声识别VOICE RECOGNITION&#xff1f; 2 语声识别&#xff08;VOICE RECOGNITION&#xff09;和语音识别(SPEECH RECOGNITION)有什么区别&#xff1f; 3 语声识别&#xff08;VOICE RECOGNITION&#xff09;系统的类型 4 语音识别系统的类型 5 语音识别简…

语音识别-特征提取 (一)

一&#xff0e;语音的产生简介 1.1 发音器官 人体的语音是由人体的发音器官在大脑的控制下做生理运动产生的。人体发音器官由三部分组成&#xff1a;肺和气管、喉、声道。 肺是语音产生的能源所在。气管连接着肺和喉&#xff0c;是肺与声道的联系通道。喉是由一个软骨和肌肉组…

分享本周所学——人工智能语音识别模型CTC、RNN-T、LAS详解

本人是一名人工智能初学者&#xff0c;最近一周学了一下AI语音识别的原理和三种比较早期的语音识别的人工智能模型&#xff0c;就想把自己学到的这些东西都分享给大家&#xff0c;一方面想用浅显易懂的语言让大家对这几个模型有所了解&#xff0c;另一方面也想让大家能够避免我…