【面试深度解析】字节后端日常实习一面这么问吗?

🌈🌈🌈🌈🌈🌈🌈🌈
欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!

在我后台回复 「资料」 可领取编程高频电子书
在我后台回复「面试」可领取硬核面试笔记

文章导读地址:点击查看文章导读!

感谢你的关注!

🍁🍁🍁🍁🍁🍁🍁🍁

前言:
🚀 春招季即将来临,你准备好迎接挑战了吗? 🌟

🎯 【30天面试冲刺计划】 —— 专为大厂面试量身定制!

🔥 加入我们,一起解锁面试新高度! 🔥

🌈 你将获得:

深入解析:每日精选大厂面试真题,从面试官视角出发,剖析问题背后的考察点。
实战演练:模拟面试场景,教你如何巧妙应对,展现最佳自我。
全面覆盖:涵盖技术、算法、数据结构、系统设计等多维度面试话题。
独家秘籍:分享面试技巧,助你轻松应对各种棘手问题。
🔗 关注我,开启你的春招逆袭之旅! 🌠

在这里插入图片描述

文章目录

  • 字节后端日常实习一面这么问吗
    • 题目分析
      • 1、前端发送请求到后端的过程
      • 2、网关 Gateway 作用,怎么解决跨域问题?
      • 3、Redission 中分布式锁的实现
      • 4、线程池中队列满的策略
      • 5、ConcurrentHashMap 了解吗?
      • 6、轻量级、重量级锁
      • 7、怎么实现锁?
      • 8、where 多条件查询,是否走索引?
      • 9、如何将同姓名记录拼到同一行?
      • 10、字符串拼接

字节后端日常实习一面这么问吗

题目分析

1、前端发送请求到后端的过程

这个问题还是比较开放的,我自己感觉主要有两个重点:TCP、Spring MVC

接下来,先说一下整体的流程:

从前端发送请求到后端的整个流程,前端点击按钮发送 HTTP 请求,那么会先和后端服务 建立 TCP 连接,建立连接之后,前端就可以向后端继续发送数据了,后端收到请求之后,通过 Spring MVC 来对请求进行处理

接下来说一下 Spring MVC 处理的流程,它会先去拿到 HTTP 请求的 url,根据 url 找到对应的处理器,通过对应的处理器处理之后,返回 JSON 数据给前端,前端就拿到了后端的数据,再将数据渲染到页面中

扩展

那么接下来,既然你说了 TCPSpring MVC,那么这两个点是很有可能被面试官深入下去问的

其中 TCP 三次握手、四次挥手肯定是要了解吧,Spring MVC 具体执行的流程也要了解一下吧(这个我也不太清楚现在面试的频繁不频繁了,有知道的小伙伴可以讨论一下)

这里先说一下 TCP,三次握手、四次挥手的流程肯定要知道,为什么不能两次挥手这个问题怎么回答呢?

可以直接假设两次挥手,如果 client 发送的第一个 SYN 包并没有丢失,只是在网络中滞留,以致于延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文,但 server 收到此失效报文后,就误认为是 client 再次发出的一个新的连接,于是向 client 发出 SYN+ACK 包,如果不采用三次握手,只要 server 发出 SYN+ACK 包,就建立连接,会导致 client 没有发出建立连接的请求,因此不会理会 server 的 SYN+ACK 包,但是 server 却以为新的连接建立好了,并一直等待 client 发送数据,导致资源被浪费。

其实还有一种说法就是,经过了三次握手,客户端和服务端才可以确保自己的收发能力都是正常的。

**为什么不四次握手?**因为三次握手就可以建立通信了,没必要四次握手,增加额外开销。

再说一下 Spring MVC 的执行流程,其实一句话就是通过 url 找到对应的处理器,执行对应的处理器即可(也就是 Controller),我也画了一张流程图,看着复杂,其实就是找到对应的 Handler 再执行,这里是通过 HandlerAdpter 来执行对应的 Handler

在这里插入图片描述

这里通过 Adapter 来执行 Handler 就使用了 适配器模式,那么适配器模式有什么好处呢?

让相互之间不兼容的类可以一起工作,客户端可以调用适配器的方法来适配不同的逻辑,这里举个例子:

如下,AdvancedMediaPlayer 是用来被适配的类,可以看到被适配的类中有两个不同的方法,要在不同的情况下调用不同的方法,那么就创建了 MediaPlayerAdapter 适配器类,定义一个 play() 方法,根据传入的类型不同,调用不同的方法,那么如果后来增加被适配的类,那么我们只需要在适配器中添加一个 if 条件即可完成扩展,这就是适配器模式的优势

public interface MediaPlayer {
    void play(String audioType, String fileName);
}
// 被适配的类
public class AdvancedMediaPlayer {
    public void playMp4(String fileName) {
        System.out.println("Playing MP4 file: " + fileName);
    }

    public void playVlc(String fileName) {
        System.out.println("Playing VLC file: " + fileName);
    }
}
// 适配器
public class MediaPlayerAdapter implements MediaPlayer {
    private AdvancedMediaPlayer advancedMediaPlayer;

    public MediaPlayerAdapter(AdvancedMediaPlayer advancedMediaPlayer) {
        this.advancedMediaPlayer = advancedMediaPlayer;
    }

    @Override
    public void play(String audioType, String fileName) {
        if ("mp4".equals(audioType)) {
            advancedMediaPlayer.playMp4(fileName);
        } else if ("vlc".equals(audioType)) {
            advancedMediaPlayer.playVlc(fileName);
        } else {
            throw new IllegalArgumentException("Unsupported media type: " + audioType);
        }
    }
}

2、网关 Gateway 作用,怎么解决跨域问题?

网关的作用一般包含以下几个:

  • 对请求进行路由,路由到不同的机器中,还有动态路由功能,即新增了几台服务,那么网关可以感知到服务的变化,动态进行路由
  • 负载均衡,将请求分散到提供相同服务的多个机器上去
  • 限流熔断,为了保护后端服务,对请求进行限流和熔断
  • 认证授权,对请求进行认证授权操作

跨域问题(Cross-Origin Resource Sharing,CORS)是指当一个Web应用尝试从与它所在的源(协议、域名和端口)不同的源(服务器)请求资源时遇到的问题,浏览器出于安全考虑会阻止跨域请求,但是如果服务器允许的话,就不阻止

那么我们作为后端,了解一下后端如何解决跨域问题,通过注解 @CrossOrigin 指定 CORS 策略,origins = "*" 表示允许所有源进行跨域请求,如下

@RestController
public class HelloController {
    // 允许所有源的跨域请求
    @CrossOrigin(origins = "*")
    @GetMapping("/hello")
    public String hello() {
        return "...";
    }
}

3、Redission 中分布式锁的实现

这里面试官应该是想要考察你知不知道 Redission 底层如何进行加锁

Redission 中获取锁逻辑:

在 Redission 中加锁,通过一系列调用会到达下边这个方法

他的可重入锁的原理也就是使用 hash 结构来存储锁,key 表示锁是否存在,如果已经存在,表示需要重复访问同一把锁,会将 value + 1,即每次重入一次 value 就加 1,退出一次 value 就减 1

比如执行以下加锁命令:

RLock lock = redisson.getLock("lock");
lock.lock();

加锁最终会走到下边这个方法,在执行 lua 脚本时有三个参数分别为:

  • KEYS[1] : 锁名称,也就是上边的 “lock”
  • ARGV[1]: 锁失效时间,默认 30 s
  • ARGV[2]: 格式为id + “:” + threadId:锁的小key,值为 c023afb1-afaa-402a-b23e-a21a82abec9d:1

这里讲解下边这个 lua 脚本的执行流程:

  1. 先去判断 KEYS[1] 这个哈希结构是否存在

  2. 如果不存在,通过 hset 去创建一个哈希结构,并放入一个 k-v 对

    这个哈希表名为锁的名称,也就是 “lock”,key 为 ARGV[2],也就是 c023afb1-afaa-402a-b23e-a21a82abec9d:1, value 为 1

  3. 通过 pexpire 设置 key 的过期时间,pexpire 的过期时间单位是毫秒,expire 单位是秒

  4. 如果这个哈希结构存在,去判断这个 key 是否存在

  5. 如果这个 key 存在,表示之前已经被当前线程加过锁了,再去重入加锁即可,也就是通过 hincrby 给这个 key 的值加 1 即可,并且设置过期时间

<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
    internalLockLeaseTime = unit.toMillis(leaseTime);

    return commandExecutor.evalWriteAsync(getName(), LongCodec.INSTANCE, command,
              "if (redis.call('exists', KEYS[1]) == 0) then " +
                  "redis.call('hset', KEYS[1], ARGV[2], 1); " +
                  "redis.call('pexpire', KEYS[1], ARGV[1]); " +
                  "return nil; " +
              "end; " +
              "if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
                  "redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
                  "redis.call('pexpire', KEYS[1], ARGV[1]); " +
                  "return nil; " +
              "end; " +
              "return redis.call('pttl', KEYS[1]);",
                Collections.<Object>singletonList(getName()), internalLockLeaseTime, getLockName(threadId));
}

4、线程池中队列满的策略

这里考察的就是线程池中的 拒绝策略 有那些了,有 4 种拒绝策略,默认策略是直接抛出异常,我觉得面试官也并不是让你把 4 种拒绝策略都给一字不差的背出来,考察的是如果任务队列满了之后,对于接下来的任务要如何处理?

那么最简单的肯定就是有新任务进入的话,直接抛出异常就好了

  • AbortPolicy :直接抛出异常,默认策略

其他三种策略是怎么做的呢?

  • CallerRunsPolicy:用调用者所在的线程来执行任务
  • DiscardOldestPolicy:丢弃阻塞队列里最老的任务,也就是队列里靠前的任务
  • DiscardPolicy :当前任务直接丢弃

可以看到,要么将老任务丢弃,要么将当前任务丢弃,要么线程池不执行,通过当前调用者的线程执行

扩展

其实我们 自己也可以定义拒绝策略,这个作为扩展点

比如有这样一个业务场景,任务队列满了,但是我们不能把任务丢弃掉,是必须要执行的

那么就可以定义一个拒绝策略,将任务异步持久化到磁盘中去,再通过定时任务将任务取出来进行执行

这里异步持久化到磁盘也就是存储到 MySQL 中,给任务标记一个状态(未提交、已提交、已完成),执行完成的话,就给任务状态更改标记

5、ConcurrentHashMap 了解吗?

考察并发安全的 HashMap 框架

那么这里要了解 ConcurrentHashMap 是如何去加锁来保证线程安全的

ConcurrentHashMap 在 JDK1.7 之前使用的是分段锁,这种锁开销比较大,并且锁的粒度也比较大,因此在 1.8 进行了优化

ConcurrentHashMap在 JDK1.8 中是通过 CAS + synchronized 来实现线程安全的,锁的粒度为单个节点,它的结构和 HashMap 一样:数组 + 链表 + 红黑树

在将节点往数组中存放的时候(没有哈希冲突),通过 CAS 操作进行存放

如果节点在数组中存放的位置有元素了,发生哈希冲突,则通过 synchronized 锁住这个位置上的第一个元素

那么面试官可能会问 ConcurrentHashMap 向数组中存放元素的流程,这里我给写一下(主要看一下插入元素时,在什么时候加锁了):

  1. 根据 key 计算出在数组中存放的索引
  2. 判断数组是否初始化过了
  3. 如果没有初始化,先对数组进行初始化操作,通过 CAS 操作设置数组的长度,如果设置成功,说明当前线程抢到了锁,当前线程对数组进行初始化
  4. 如果已经初始化过了,判断当前 key 在数组中的位置上是否已经存在元素了(是否哈希冲突)
  5. 如果当前位置上没有元素,则通过 CAS 将要插入的节点放到当前位置上
  6. 如果当前位置上有元素,则对已经存在的这个元素通过 synchronized 加锁,再去遍历链表,通过将元素插到链表尾

扩展

什么时候链表转为红黑树呢?

当链表长度大于 8 并且数组长达大于 64 时,才会将链表转为红黑树

6、轻量级、重量级锁

这里说的就是 JDK 在 1.6 中引入的对 synchronized 锁的优化,之前 synchronized 一直都是重量级锁,性能开销比较高

JDK 1.6 引入了偏向锁和轻量级锁

那么 synchronized 锁共有 4 种状态:无锁、偏向锁、轻量级锁、重量级锁

下边说一下锁的状态是如何进行升级的:

  1. 当线程第一次竞争到锁,拿到的就是偏向锁,此时不存在其他线程的竞争

    偏向锁的性能是很高的,他会偏向第一个访问锁的线程,持有偏向锁的线程不需要触发同步,连 CAS 操作都不需要

    JDK15 中标记了偏向锁为废弃状态,因为维护的开销比较大

  2. 如果有线程竞争的话,并且竞争不太激烈的情况下,偏向锁升级为轻量级锁,也就是通过 CAS 自旋来竞争

  3. 当 CAS 自旋达到一定次数,就会升级为重量级锁

这几种锁的状态存储在了对象头的 Mark Word 中,并且还指向了持有当前对象锁的线程

synchronized 加锁流程如下:

在这里插入图片描述

扩展

偏向锁在 JDK 15 之后就被废弃掉了,因为偏向锁增加了维护开销太高,并且偏向锁在一个线程一直访问的时候性能很高,但是大多数情况下会有多个线程来竞争,那么此时偏向锁的性能就会下降,因此逐渐废弃掉

Java 团队更推荐使用轻量级锁或者重量级锁:

  • 如果竞争不激烈的话,并且每个线程对锁持有时间较短的情况下,可以使用轻量级锁,也就是 CAS 自旋等待获取锁
  • 如果竞争激烈的情况下,或者每个线程持有锁的时间很长,如果还是用 CAS 自旋会导致大量线程在空转,大量占用 CPU 资源,因此要使用重量级锁

7、怎么实现锁?

我个人理解,可能面试官是要问锁的实现原理,因为毕竟上边已经说到 synchronized 锁的优化了,肯定会继续深入 synchronized 继续说,这里就说一下 CAS 和 synchronized 的底层原理怎么实现的

CAS 如何加锁?

CAS 操作主要涉及 3 个操作数:

  1. V:要写的内存地址
  2. E:预期值
  3. N:新写入的值

CAS 底层加锁的逻辑就是当内存地址的值等于预期值时,将该内存地址的值写为新的值,那么当多个线程来通过 CAS 操作时,肯定只有第一个线程可以操作成功

synchronized 如何加锁?

synchronized 是基于两个 JVM 指令来实现的:monitorentermonitorexit

那么在这两个 JVM 指令中的代码就是被上了锁的,这一段代码就只有当前加锁的线程可以执行,从而保证线程之间的同步操作

另外一种可能

那么还有可能是问 Java 并发包下的 ReentrantLock 是如何实现加锁的,这里也来说一下

使用 ReentrantLock 来加锁时,要先构造一个 ReentrantLock 实例对象,再调用 lock 方法加锁,如果该锁没有被其他线程持有,则加锁成功

如果该锁被其他线程持有,当前线程会阻塞,那么就会把当前线程封装成为一个 Node 节点,加入到 AQS 队列中进行等待,当获取锁的线程释放锁之后,会从 AQS 队列中唤醒一个线程,AQS 队列如下:

在这里插入图片描述

ReentrantLock 还可以支持重入,如果锁重入的话,它里边会有一个属性 state 值进行加 1 操作记录,退出的话,会给 state 值减 1

如果 ReentrantLock 是公平锁的话,队列中的节点会按照顺序去抢占锁,如果是非公平锁,则可以直接抢占锁,不需要按顺序

如果 ReentrantLock 加锁成功的话,主要会修改两个地方:

  • 修改 ReentrantLock 同步状态 state,修改为 1,表示被上了锁
  • 修改 ReentrantLock 锁的持有线程为当前线程,表示当前线程持有了这把锁

如果是释放锁的话,也是修改同步状态 state = 0 和持有当前锁的线程为 null 接口

这里贴出来一个简单用法:

public class Counter {
    private int count = 0;
    private final ReentrantLock lock = new ReentrantLock(true); // 创建一个公平锁

    public void increment() {
        // 尝试获取锁
        lock.lock();
        try {
            // 在锁的保护下执行操作
            count++;
            System.out.println("Incrementing counter to " + count);
        } finally {
            // 无论操作是否成功,都要释放锁
            lock.unlock();
        }
    }
    public static void main(String[] args) {
        Counter counter = new Counter();
        // 创建多个线程来操作计数器
        Thread t1 = new Thread(() -> counter.increment());
        Thread t2 = new Thread(() -> counter.increment());
        // 启动线程
        t1.start();
        t2.start();
    }
}

8、where 多条件查询,是否走索引?

这个就是 MySQL 中的基础了,要你判断是不是走索引,根据最左前缀原则判断即可

这里讲一下最左前缀原则

最左前缀原则:规定了联合索引在何种查询中才能生效。

规则如下:

  • 如果想使用联合索引,联合索引的最左边的列必须作为过滤条件,否则联合索引不生效

如下图:

在这里插入图片描述

假如索引为:(name, age, position)
select * from employee where name = 'Bill' and age = 31;
select * from employee where age = 30 and position = 'dev';
select * from employee where position = 'manager';

索引的顺序是:name、age、position,因此对于上边三条 sql 语句,只有第一条 sql 语句走了联合索引

第二条语句将索引中的第一个 name 给跳过了,因此不走索引

第三条语句将索引中的前两个 name、age 给跳过了,因此不走索引

为什么联合索引需要遵循最左前缀原则呢?

因为索引的排序是根据第一个索引、第二个索引依次排序的,假如我们单独使用第二个索引 age 而不使用第一个索引 name 的话,我们去查询age为30的数据,会发现age为30的数据散落在链表中,并不是有序的,所以使用联合索引需要遵循最左前缀原则。

9、如何将同姓名记录拼到同一行?

应该是考察 sql 的使用把,group by 和 group_concat

group_concat 将多个值拼接在一起

这里写一个例子,对下边这个 user 表:

在这里插入图片描述

sql 语句:

select name, group_concat(money separator ',') as records
from user 
group by money;

10、字符串拼接

这个就是 Java 基础的东西了

字符串拼接可以通过 +StringBuilder 两种方式来进行拼接

而使用 + 进行字符串拼接,其实底层还是使用 StringBuilder 来拼接的,但是如果在循环中,使用 + 进行字符串拼接,会导致创建很多 StringBuilder 对象,因此如果需要字符串拼接,推荐还是直接使用 StringBuilder

再说一下 StringBuilder 和 StringBuffer 的区别(StringBuffer 可以保证线程安全):

  • 单线程操作字符串缓冲区下操作大量数据使用 StringBuilder
  • 多线程操作字符串缓冲区下操作大量数据使用 StringBuffer

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

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

相关文章

上门回收小程序,打造回收新模式

近年来&#xff0c;我国一直秉持着环保绿色的发展理念&#xff0c;为了减少资源浪费&#xff0c;旧物回收成为了人们处理废弃物品的方式。目前&#xff0c;我国回收市场规模大约能达到3.58亿元&#xff0c;在我国经济的稳定增长和环保意识的提高下&#xff0c;回收市场规模还将…

力扣每日一题 --- 972. 相等的有理数

本题中的一个难点是怎么判断是否相等&#xff0c;如果自己写判断的话是不是很麻烦&#xff0c;判断整数之后再去判断小数部分&#xff0c;那么我们这题的另一个难点就要登场了&#xff0c;第一个难点让本题的情况变得复杂&#xff0c;第二个难点让本题变得很难想到怎么判断&…

网络安全B模块(笔记详解)- 内存取证

1.从内存文件中获取用户admin的密码并破解,将该密码作为flag值提交(密码长度为6个字符); 2.获取内存文件中系统的IP地址,将IP地址作为flag值提交; 3.获取内存文件中系统的主机名,将主机名作为flag值提交; 4.内存文件的系统中存在挖矿进程,将矿池的IP地址作为flag值提…

qml:FocusInput、TextInput 键盘输入

有2个输入框&#xff0c;默认焦点在第一个输入框&#xff0c;按Tab键可以在两个输入框之间来回切换。 FocusInput.qml import QtQuickFocusScope { //显式创建焦点范围width: 200height: 40x: 20y: 20property alias text: input.textproperty alias input: inputRectangle…

DNA序列修正*

题目 import java.util.HashMap; import java.util.Map; import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();sc.nextLine();char[] sq1 sc.next().toCharArray();sc.nextLine(…

低代码(Low-Code)技术简化开发难度,快速搭建应用

目录 一、低代码技术定义 二、低代码技术优势 1.提高企业的工作效率 2.降低企业的开发成本 3.提高应用程序和业务流程的质量 三、稳定性和生产率的最佳实践 三、最后 随着数字化时代的到来&#xff0c;低代码&#xff08;Low-Code&#xff09;技术已经成为了企业数字化转…

科技、文化与旅游的融合创新:智慧文旅的未来之路

在当今社会&#xff0c;科技、文化与旅游的融合已经成为文旅产业转型升级的重要趋势。这种融合不仅有助于提升文旅产业的核心竞争力&#xff0c;更有助于推动产业的数字化转型和可持续发展。 本文将深入探讨科技、文化与旅游的融合创新&#xff0c;以及智慧文旅场景的解决方案…

使用 Swift 代码优化项目编译速度

引言 软件的性能是评价一个软件质量的重要指标&#xff0c;尤其在今天这个时代&#xff0c;性能已成为大型项目不可或缺的考虑因素之一。对于用户量极大的软件&#xff0c;如网银系统、在线购物商城等&#xff0c;更是必须保证其高效稳定的性能。在这种背景下&#xff0c;优化…

【MySQL·8.0·源码】subquery 子查询处理分析(一)

引言 在 SQL 中&#xff0c;子查询属于 Nested Query 的一种形式&#xff0c;根据 Kim 的分类[1]&#xff0c;Nested Query 即嵌套查询是一种 SQL-like 形式的查询语句嵌套在另一 SQL 中&#xff0c;SQL-like 的嵌套子句可以出现在 SELECT、FROM 和 WHERE 子句的任意位置。 在…

C++: vector

目录 1.vector的介绍 2.vector常用的接口 1.vector构造 2.迭代器iterator的使用 3.vector空间增长 4.vector的增删改查 3.vector模拟实现 如果在reverse时使用memcpy会怎么样&#xff1f; 1.vector的介绍 C中的vector是一个动态数组容器&#xff0c;可以存储任意类型的…

【算法分析与设计】二叉树的层序遍历

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;算法分析与设计 ⛺️稳中求进&#xff0c;晒太阳 题目 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xf…

Python 自动化办公:一键批量生成 PPT

Stata and Python 数据分析 一、导读 在实际工作中&#xff0c;经常需要批量处理Office文件&#xff0c;比如需要制作一个几十页的PPT进行产品介绍时&#xff0c;一页一页地制作不仅麻烦而且格式可能不统一。那么有什么办法可以一键生成PPT呢&#xff1f;Python提供的pptx 包…

Simulink|光伏并网逆变器低电压穿越仿真模型

目录 主要内容 模型研究 1.模型总览 2.boost模块 3.Inverter模块 4.控制模块 5.信号模块 结果一览 下载链接 主要内容 该模型为光伏逆变器低电压穿越仿真模型&#xff0c;采用boost加NPC拓扑结构&#xff0c;基于MATLAB/Simulink建模仿真。模型具备中点平衡…

灭火图 - 故障发现和定位的入口

通过深入分析和解决企业在可观测性和稳定性保障方面的挑战&#xff0c;Flashcat 提出了“灭火图”这一关键概念。 灭火图以服务/模块/基础组件/基础设施等为维度&#xff0c;以聚合的视角实时度量某个特定维度的可用性&#xff08;典型指标包括时延、流量、错误、饱和度&#x…

���恒峰|配网行波型故障预警定位装置:电力系统的守护神

&#xfffd;&#xfffd;&#xfffd;在电力系统中&#xff0c;设备的正常运行对于保障供电至关重要。而配网行波型故障预警定位装置就是电力系统的守护神&#xff0c;它能够实时监测设备状态&#xff0c;提前发现故障&#xff0c;确保电力供应的稳定。本文将详细介绍配网行波…

Gradle 笔记

Gradle依赖管理&#xff08;基于Kotlin DSL&#xff09; **注意&#xff1a;**如果不是工作原因或是编写安卓项目必须要用Gradle&#xff0c;建议学习Maven即可&#xff0c;Gradle的学习成本相比Maven高很多&#xff0c;而且学了有没有用还是另一回事&#xff0c;所以&#xff…

【网络】传输层TCP协议

目录 一、概述 2.1 运输层的作用引出 2.2 传输控制协议TCP 简介 2.3 TCP最主要的特点 2.4 TCP连接 二、TCP报文段的首部格式 三、TCP的运输连接管理 3.1 TCP的连接建立(三次握手) 3.2 为什么是三次握手&#xff1f; 3.3 为何两次握手不可以呢&#xff1f; 3.4 TCP的…

【KD】2023 NeurIPS Does Graph Distillation See Like Vision Dataset Counterpart?

简介 在大规模图数据集上进行GNN训练是一个艰巨的挑战。特别是在增量学习和图结构搜索这些经常需要重复训练的场景中,训练图模型不仅消耗大量时间,还对显存和计算能力提出了严峻要求。最近,图数据集蒸馏/图压缩(Graph Dataset Distillation / Graph Condensation)方法…

Harmony 鸿蒙驱动开发

驱动开发 驱动模型介绍 HDF&#xff08;Hardware Driver Foundation&#xff09;框架以组件化的驱动模型作为核心设计思路&#xff0c;为开发者提供更精细化的驱动管理&#xff0c;让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个Host&#xff08;设备容器&#…

阿里巴巴开源联邦学习框架FederatedScope

5月5日&#xff0c;阿里巴巴达摩院发布新型联邦学习框架FederatedScope&#xff0c;声称可以在不共享训练数据的情况下开发机器学习算法&#xff0c;从而保护隐私。&#xff0c;其源代码现已在Apache 2.0许可下发布在GitHub上。 介绍 该平台被描述为一个全面的联邦学习框架&a…