Lombok 的正确使用姿势

2023-11-07

在 Java 开发领域中,Lombok 插件已经成为一个非常流行的代码库。该插件让 Java 开发更加便捷、高效,因此提高了开发者的生产力。

1.Lombok 是什么

Lombok 是一款 Java 开发工具,它可以通过注解来帮助程序员在编译时自动生成 Java 代码,从而简化 Java 开发过程。具体来说他会通过解析注解,然后在编译时生成代码来实现 Java 代码的功能增强。

Lombok 插件产生的主要原因是 Java 语言臃肿的语法,需要大量的样板代码,以及冗长臃肿的 getter 和 setter 方法。当你的模型层非常大时,手动编写所有这些代码会变得非常繁琐和无聊。因此,Lombok 插件为我们自动生成 Java 代码并帮助优化 Java 开发过程,提高效率。

2.安装 Lombok

打开 IDEA 设置页面:

在插件页面搜索“Lombok”安装即可:

注意:使用 Lombok 必须要在 IDE 中安装 Lombok 插件,以使得 IDE 能正确识别和使用 Lombok 注解。

3.Spring Boot 集成 Lombok

为了使用 Lombok 插件,我们需要在项目中设置依赖。下面是一个使用 Maven 添加 Lombok 的 pom.xml 文件的例子:

<!--Lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

注意:SpringBoot 2.1.x 版本后无需指定 Lombok 版本,SpringBoot 在 spring-boot-dependencies 中已经内置了该依赖进行管理。

4.使用 Lombok

4.1 注解一览表

以下是 Lombok 提供的一些主要注解及其功能:

注解 功能
@Getter 为字段生成 getter 方法
@Setter 为字段生成 setter 方法
@Data 为字段生成 getter 和 setter 方法,还包括 equals, hashCode, toString 方法
@ToString 为类生成 toString 方法
@EqualsAndHashCode 为类生成 equals 和 hashCode 方法
@NoArgsConstructor 为类生成无参构造器
@AllArgsConstructor 为类生成包含所有字段的构造器
@RequiredArgsConstructor 为类生成包含必须字段(final 和带有 @NonNull 注解的字段)的构造器
@Value 为类生成只读属性(final),包括 getter, equals, hashCode, toString 方法
@Builder 为类实现 Builder 模式
@SneakyThrows 用于方法上,可以让方法抛出被检查的异常,而不需要显式地在方法上使用 throws 关键字
@Slf4j 在类中添加一个名为 ‘log’ 的 SLF4J 日志器对象
@Cleanup 自动管理资源,用于自动调用 close 方法释放资源
@NonNull 用于检查方法或构造器的参数是否为 null,如果为 null 就会抛出 NullPointerException
@Delegate 自动生成委托(delegate)方法,用来将调用转发到指定的字段或方法
@With 为字段生成返回更新了某个字段值的新对象的方法
@SuperBuilder 用于更复杂的继承情况下的 Builder 模式
@Synchronized Lombok 提供的同步锁,用于方法,将会同步在一个私有的字段上,如果是静态方法,则同步在一个私有的静态字段上
val 定义一个局部变量并立即为其赋值,这个变量为 final 类型,不能被修改

4.2 部分使用介绍

上述注释大多数使用看功能描述基本都能理解,下面挑出一些不太容易理解的进行使用说明。

@Getter(lazy=true)

@Getter(lazy=true) 为字段生成延迟初始化的 getter 方法。这个 getter 方法在第一次被调用时初始化字段,并将结果缓存。一般用于需要获取的某一个属性比较消耗资源时,便可以通过该注解添加 lazy=true 属性实现懒加载,这会生成 Double Check Lock 样板代码对属性进行懒加载。

在 Java 中,“double check lock”(双重检查锁)模式是一种常用的多线程并发编程技巧,主要用于延迟初始化并确保只有一个线程能够初始化资源。当你在 Lombok 中使用 @Getter(lazy=true) 注解时,Lombok 就会生成对应的双重检查锁的代码。这样可以确保字段的延迟初始化,在多线程环境中也能保证线程安全,而且只会初始化一次。

import lombok.Getter;

public class LazyGetterExample {

    // 使用双重检查锁对方法进行加锁,确保只有一个线程可以执行 expensive() 方法(懒加载)
    @Getter(lazy = true)
    private final Double cached = expensive();

    private Double expensive() {
        // 模拟一个耗时的操作
        Double result = null;
        for (int i = 0; i < 1000000; i++) {
            result = Math.atan(i) * Math.tan(i);
        }
        return result;
    }

    public static void main(String[] args) {
        LazyGetterExample example = new LazyGetterExample();
        System.out.println(example.getCached());
    }
}

编译后的代码会是如下这样的:

import java.util.concurrent.atomic.AtomicReference;

public class LazyGetterExample {
    private final AtomicReference<Object> cached = new AtomicReference();

    public LazyGetterExample() {
    }

    private Double expensive() {
        Double result = null;

        for(int i = 0; i < 1000000; ++i) {
            result = Math.atan((double)i) * Math.tan((double)i);
        }

        return result;
    }

    public static void main(String[] args) {
        LazyGetterExample example = new LazyGetterExample();
        System.out.println(example.getCached());
    }

    public Double getCached() {
        Object value = this.cached.get();
        if (value == null) {
            synchronized(this.cached) {
                value = this.cached.get();
                if (value == null) {
                    Double actualValue = this.expensive();
                    value = actualValue == null ? this.cached : actualValue;
                    this.cached.set(value);
                }
            }
        }

        return (Double)((Double)(value == this.cached ? null : value));
    }
}

@Value

@Value 为类生成只读属性,即所有字段都是 final,包括 getter 方法、equalshashCodetoString 方法。此时此类相当于 final 类,无法被继承,其属性也会变成 final 属性。

@Value
public class ValueExample {
    private String name;
    private int age;

    public static void main(String[] args) {
        // 只能使用全参构造器
        ValueExample example = new ValueExample("张三", 18);
        // 可以直接获取属性值
        System.out.println(example.getName());
        System.out.println(example.getAge());

        // 不能修改属性值
        // example.setName("李四");
        // example.setAge(20);
    }
}

编译后的代码会是如下这样的:

public final class ValueExample {
    private final String name;
    private final int age;

    public static void main(String[] args) {
        ValueExample example = new ValueExample("张三", 18);
        System.out.println(example.getName());
        System.out.println(example.getAge());
    }

    public ValueExample(final String name, final int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return this.name;
    }

    public int getAge() {
        return this.age;
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof ValueExample)) {
            return false;
        } else {
            ValueExample other = (ValueExample)o;
            if (this.getAge() != other.getAge()) {
                return false;
            } else {
                Object this$name = this.getName();
                Object other$name = other.getName();
                if (this$name == null) {
                    if (other$name != null) {
                        return false;
                    }
                } else if (!this$name.equals(other$name)) {
                    return false;
                }

                return true;
            }
        }
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        result = result * 59 + this.getAge();
        Object $name = this.getName();
        result = result * 59 + ($name == null ? 43 : $name.hashCode());
        return result;
    }

    public String toString() {
        return "ValueExample(name=" + this.getName() + ", age=" + this.getAge() + ")";
    }
}

@Builder

@Builder 为类实现 Builder 设计模式(建造者模式),通常用于链式构造复杂对象。

import lombok.Builder;
import lombok.ToString;

@ToString
@Builder
public class BuilderExample {
    private String name;
    private int age;

    public static void main(String[] args) {
        BuilderExample example = BuilderExample.builder().name("张三").age(18).build();
        System.out.println(example);
    }
}

编译后的代码会是如下这样的:

public class BuilderExample {
    private String name;
    private int age;

    public static void main(String[] args) {
        BuilderExample example = builder().name("张三").age(18).build();
        System.out.println(example);
    }

    BuilderExample(final String name, final int age) {
        this.name = name;
        this.age = age;
    }

    public static BuilderExampleBuilder builder() {
        return new BuilderExampleBuilder();
    }

    public String toString() {
        return "BuilderExample(name=" + this.name + ", age=" + this.age + ")";
    }

    public static class BuilderExampleBuilder {
        private String name;
        private int age;

        BuilderExampleBuilder() {
        }

        public BuilderExampleBuilder name(final String name) {
            this.name = name;
            return this;
        }

        public BuilderExampleBuilder age(final int age) {
            this.age = age;
            return this;
        }

        public BuilderExample build() {
            return new BuilderExample(this.name, this.age);
        }

        public String toString() {
            return "BuilderExample.BuilderExampleBuilder(name=" + this.name + ", age=" + this.age + ")";
        }
    }
}

@SuperBuilder

@SneakyThrows

@SneakyThrows 用于方法上,可以让方法抛出被检查的异常,而不需要显式地在方法上使用 throws 关键字抛出异常。

import lombok.SneakyThrows;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class SneakyThrowsExample {
    // 自动抛出异常,不需要手动 try catch
    @SneakyThrows(UnsupportedEncodingException.class)
    public String sneakyMethod(){
        return URLEncoder.encode("Example", "Unsupported Encoding");
    }
    
    public static void main(String[] args) {
        SneakyThrowsExample example = new SneakyThrowsExample();
        System.out.println(example.sneakyMethod());
    }
}

编译后的代码会是如下这样的:

public class SneakyThrowsExample {
    public SneakyThrowsExample() {
    }

    public String sneakyMethod() {
        try {
            return URLEncoder.encode("Example", "Unsupported Encoding");
        } catch (UnsupportedEncodingException var2) {
            throw var2;
        }
    }

    public static void main(String[] args) {
        SneakyThrowsExample example = new SneakyThrowsExample();
        System.out.println(example.sneakyMethod());
    }
}

@Slf4j

使用 Lombok 生成日志对象时,根据使用日志实现的不同,有多种注解可以使用。比如 @Log@Log4j@Log4j2@Slf4j 等。以 @Slf4j 为例,它会在类中添加一个名为 ‘log’ 的 SLF4J 日志器对象。

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Slf4jExample {
    public static void main(String[] args) {
        log.info("Hello World");
        log.error("Hello World");
        log.debug("Hello World");
        log.warn("Hello World");
    }
}

编译后的代码会是如下这样的:

public class Slf4jExample {
    private static final Logger log = LoggerFactory.getLogger(Slf4jExample.class);

    public Slf4jExample() {
    }

    public static void main(String[] args) {
        log.info("Hello World");
        log.error("Hello World");
        log.debug("Hello World");
        log.warn("Hello World");
    }
}

@Cleanup

@Cleanup 用于自动管理资源,用于自动调用 close() 方法释放资源,避免了手动释放。

public class CleanupExample {
    public static void main(String[] args) throws IOException {
        @Cleanup InputStream in = Files.newInputStream(Paths.get("file.txt"));
    }
}

编译后的代码会是如下这样的:

public class CleanupExample {
    public CleanupExample() {
    }

    public static void main(String[] args) throws IOException {
        InputStream in = new FileInputStream("/file.txt");
        if (Collections.singletonList(in).get(0) != null) {
            in.close();
        }
    }
}

@NonNull

@NonNull 用于检查方法或构造器的参数是否为 null,如果为 null 就会抛出 NullPointerException,一般用来做非空判断。

public class NonNullExample {
    public String nonNullMethod(@NonNull String string){
        return string;
    }
    
    public static void main(String[] args) {
        NonNullExample example = new NonNullExample();
        example.nonNullMethod(null);
    }
}

编译后的代码会是如下这样的:

public class NonNullExample {
    public NonNullExample() {
    }

    public String nonNullMethod(@NonNull String string) {
        if (string == null) {
            throw new NullPointerException("string is marked non-null but is null");
        } else {
            return string;
        }
    }

    public static void main(String[] args) {
        NonNullExample example = new NonNullExample();
        example.nonNullMethod((String)null);
    }
}

@With

@With 用于为字段生成返回更新了某个字段值的新对象的方法。简单来说,它可以实现对原对象进行克隆,并改变其一个属性,使用时需要指定全参构造方法。

import lombok.AllArgsConstructor;
import lombok.With;

@With
@AllArgsConstructor
public class WithExample {
    private String name;
    private int age;

    public static void main(String[] args) {
        // 实例化一个对象
        WithExample example = new WithExample("javgo", 18);
        System.out.println(example);

        // 使用 withName 方法修改 name 属性
        WithExample withExample = example.withName("javgo2");
        System.out.println(withExample);
    }
}

编译后的代码会是如下这样的:

public class WithExample {
    private String name;
    private int age;

    public static void main(String[] args) {
        WithExample example = new WithExample("javgo", 18);
        System.out.println(example);
        WithExample withExample = example.withName("javgo2");
        System.out.println(withExample);
    }

    public WithExample withName(final String name) {
        return this.name == name ? this : new WithExample(name, this.age);
    }

    public WithExample withAge(final int age) {
        return this.age == age ? this : new WithExample(this.name, age);
    }

    public WithExample(final String name, final int age) {
        this.name = name;
        this.age = age;
    }
}

@Synchronized

当我们在多个线程中访问同一资源时,往往会出现线程安全问题,往往我们会使用 synchronized 关键字修饰方法来实现同步访问。而 @Synchronized 是 Lombok 提供的同步锁,用于方法,将会同步在一个私有的字段上,如果是静态方法,则同步在一个私有的静态字段上。

import lombok.Synchronized;

public class SynchronizedExample {
    private final Object readLock = new Object();

    @Synchronized
    public void syncMethod(){
        // do something
    }

    @Synchronized("readLock")
    public void customLockMethod() {
        // do something
    }

    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();

        // 两个方法都会被锁定
        example.syncMethod(); // 锁定的是 this, 即 SynchronizedExample 对象
        example.customLockMethod(); // 锁定的是 readLock,即 SynchronizedExample.readLock 对象
    }
}

编译后的代码会是如下这样的:

public class SynchronizedExample {
    private final Object $lock = new Object[0];
    private final Object readLock = new Object();

    public SynchronizedExample() {
    }

    public void syncMethod() {
        synchronized(this.$lock) {
            ;
        }
    }

    public void customLockMethod() {
        synchronized(this.readLock) {
            ;
        }
    }

    public static void main(String[] args) {
        SynchronizedExample example = new SynchronizedExample();
        example.syncMethod();
        example.customLockMethod();
    }
}

val

val 用于定义一个任意类型的局部变量并立即为其赋值,这个变量为 final 类型,不能被修改。

import lombok.val;
import java.util.ArrayList;

public class ValExample {
    public static void main(String[] args) {
        val example = new ArrayList<String>();
        example.add("Hello, World!");
    }
}

编译后的代码会是如下这样的:

public class ValExample {
    public ValExample() {
    }

    public static void main(String[] args) {
        ArrayList<String> example = new ArrayList();
        example.add("Hello, World!");
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lombok 的正确使用姿势 的相关文章

  • Criteria eager fetch-joined 集合以避免 n+1 选择

    假设 Item 和 Bid 是实体 一个 Item 有多个 Bid 它们被映射到休眠在典型的父子关系中
  • 在游戏框架中编写功能测试的正确方法

    在为基于 play1 2 4 的 web 应用程序编写功能测试时 我对如何正确编码感到有点困惑 困惑在于所涉及的事务边界 我在某处读到每个测试都有自己的事务 在我的应用程序中 用户可以登录并向购物车添加一些商品 然后他可以提供一个地址 以便
  • Java:BufferedInputStream 的 available() 方法存在问题

    我正在处理以下代码 用于将大文件拆分为一组较小的文件 FileInputStream input new FileInputStream this fileToSplit BufferedInputStream iBuff new Buff
  • Java - 了解 PrintWriter 和刷新的需要

    好吧 首先我对所有代码表示歉意 但我觉得代码太多总比代码不够好 我正在制作一个简单的聊天客户端和印刷机 尤其是我正在努力解决的问题 使用现在的代码 它将与服务器类交互 并且完美地打印我想要打印的内容 但是 当我删除 writer flush
  • SimpleDateFormat 无法正确处理 DD

    我正在尝试获得这样的格式 2013 06 15 17 45 我在代码中执行以下操作 Date d new Date SimpleDateFormat ft new SimpleDateFormat YYYY MM DD HH mm Stri
  • 使用用户名进行 Java LDAP 身份验证

    好吧 这让我发疯 我正在尝试使用 Java 创建 LDAP 身份验证 如果我在 SECURITY PRINCIPAL 中使用我的名字和姓氏 一切都很好 这是我的代码 try Hashtable
  • 使用 Thymeleaf 时我们应该删除 HTML 属性吗?

    我正在研究 Thymeleaf 发现几乎所有示例中都有 Thymeleaf 的标签值以及标准 HTML 值 例如 这些
  • Hibernate、MySQL 视图和 hibernate.hbm2ddl.auto = 验证

    我可以在 Hibernate 中使用 MySQL 视图 将它们视为表 即 该实体与为表创建的实体没有什么不同 但是 当 Hibernate 设置为验证模型时 我的应用程序将不会部署 因为它找不到视图 因为它假设它是一个表 是否可以在启用部署
  • 读取 Nashorn JO4 和 NativeArray

    Java调用代码 import jdk nashorn api scripting myCustomHashMap dataStore new myCustomHashMap ScriptEngineManager sem new Scri
  • Android 防火墙与 VpnService

    我正在尝试使用 BS 项目的 VpnService 为 Android 实现一个简单的防火墙 我选择 VpnService 因为它将在非 root 设备上运行 它将记录连接并让您过滤连接 基于IP 有一个应用程序可以做到这一点 因此这是可能
  • Android 上的自定义视图和窗口属性

    我想要做的是在我的应用程序顶部添加一个视图 该视图类似于过滤器视图 我想操纵屏幕的颜色 并且我还希望能够同时更改屏幕的亮度时间 这两件事似乎是分开起作用的 但不能一起起作用 这是我的代码 添加视图 colourView new Layer
  • 在 JSF 自定义验证器中区分 ajax 请求和完整请求

    我的验证器需要知道它是完整请求还是 ajax 请求 在我当前的解决方案中 我检查 http 请求标头X Requested With元素 public void validate FacesContext context UICompone
  • 使用 Lint 和 SonarQube 分析 Android 项目

    我真的 溢出 了试图让这些东西一起工作 我按照这里的指示进行操作 http docs sonarqube org display PLUG Android Lint Plugin http docs sonarqube org displa
  • C3P0:生产中未返回的连接超时?

    参数unreturnedConnectionTimeout给定时间段后未返回的连接超时 我正在尝试决定是否应该在我的制作中使用它persistence xml 使用它的一大优点是连接池将能够从泄漏的连接中恢复 一个很大的缺点是泄漏的连接将很
  • 错误:列“this_.phitorsionangle”必须出现在 GROUP BY 子句中或在聚合函数中使用

    我在执行 sql 查询时遇到了一些问题 我正在使用 Hibernate Criteria 来构建查询 我通过按一定间隔 binSize 舍入值然后对它们进行分组来从数据库创建一些容器 当我直接在 SQL 中使用查询尝试时 效果非常好 SEL
  • JSF“总”变量类似于 JSTL 中的 c:set

    我不喜欢 JSF 但我需要用它来解决这个问题 我正在 纯 JSF 中工作 所以这就是我基本上需要的 但我不知道如何用 JSF 来实现它
  • 解析 SWIG 接口文件的结构属性

    这是我不久前问过的问题的延续 为通过参数返回的函数创建类型映射 https stackoverflow com questions 12793973 create a typemap for a function that returns
  • JSF - 实施受限页面过滤器

    我正在关注 BalusC 的回答JSF 2 0 如何获取在浏览器地址栏中输入的 URL https stackoverflow com questions 4105263 jsf 2 0 how to get the url that is
  • 丰富:数据表行跨度问题

    我需要创建一个 rich dataTable 甚至扩展 具有以下功能 我有一个公司类 其中包含产品对象的集合 我想展示下表 我仍然没有弄清楚如何使用子表执行此操作 在所有示例中 我发现子表具有与主表完全相同的列 据推测 我需要在前两列中使用
  • selenium 没有找到合适的方法,直到(ExpectedCondition)

    这是有线的问题 我导入的项目运行 100 几个月前 今天我已将其与依赖项一起导入 但存在问题WebDriverWait 这是我的代码 WebDriverWait driverWait new WebDriverWait driver 100

随机推荐

  • python编程实战(一):用户登录模块,用户注册、登录、信息管理、功能设计与实现!

    用户登录模块 前言 思维导图 1 判断首次启动 2 用户注册 3 管理员信息 登录 4 用户登录 5 完整代码 前言 思维导图 用户登录模块是最基本的模块之一 主要设计的有当前用户存在判断 用户注册 用户登录名和密码的保存 用户信息输出等等
  • html文件上传到云服务器,把html文件上传到云服务器上

    把html文件上传到云服务器上 内容精选 换一换 需要准备的软件和工具如表1 软件和工具所示 如果Linux操作系统弹性云服务器未安装密码重置插件 可以参见本节内容重新设置密码 本节操作重置的是root用户的密码 您可以重置完root密码后
  • 自媒体创作必备的6个网站,助你打造爆款作品

    很多新人在入行自媒体时 不知道需要用到什么样的工具软件 导致其效率非常的低 其实在创作过程中使用自媒体工具还是非常有必要的 一方面帮助你快速做好自己的作品 另一方面也可以打造出更加优秀和火爆的作品 下面就和大家分享一下比较常用的一些自媒体工
  • 数组链表堆栈和队列

    转自 http blog csdn net tm wb article details 6319146 数组链表堆栈和队列 数组链表堆栈和队列是最基本的数据结构 任何程序都会涉及到其中的一种或多种 1数组 数组是最最基本的数据结构 很多语言
  • stream对多个字段分组_Java8 stream 中利用 groupingBy 进行多字段分组求和案例

    Java8的groupingBy实现集合的分组 类似Mysql的group by分组功能 注意得到的是一个map 对集合按照单个属性分组 分组计数 排序 List items Arrays asList apple apple banana
  • html代码雨特效代码,简易代码雨特效

    window onload function 获取画布对象 var canvas document getElementById canvas 获取画布的上下文 var context canvas getContext 2d 获取浏览器屏
  • CentOS dstat 命令详解(二)参数详解

    CPU相关参数 l load 展示1分钟 5分钟和15分钟内的平均负载 c cpu 展示cpu状态 usr用户占比 sys系统占比 idl空闲占比 wai等待次数 这四个加和是100 hiq硬中断次数 siq软中断次数 C 必须和 c配合使
  • prometheus-basic_auth加密配置

    文章目录 前言 一 basic auth加密的引入 二 使用步骤 1 生成basic auth密钥 2 将密钥文件写入config yml文件内 3 查看prometheus相关参数 4 修改prometheus配置 5 启动服务 5 1
  • 为什么Java中只有值传递?

    1 必知概念 实参 方法被调用时传入的实际值 形参 在定义方法时括号内定义的参数列表即为形参 它用来接收方法调用时传入的实参 值传递 当方法被调用时 实参通过形参将其副本传入方法内 接下来对形参的操作就是在对实参副本的操作 并不会影响实参本
  • ​​​​​​​自动化批量漏洞扫描脚本定制

    github上找到一款并发框架 POC T https github com Xyntax POC T 可以优美的进行并发操作 上面所述的内容大多可以用插件联合POC T进行 因为POC T不能一次使用多个插件 于是笔者对POC T框架进行
  • Xshell5登录报“找不到匹配的host key 算法“的错误

    Xshell5登录报 找不到匹配的host key 算法 的错误 现象 解决方法一 解决方法二 现象 xshell5登录欧拉22 03时报错 找不到匹配的host key 算法 解决方法一 1 编辑 etc ssh sshd config
  • win10电脑任务栏右侧小图标消失解决方法

    WIN10系统任务栏 左边是窗口键和快捷图标 右边是时钟 系统喇叭 网线连接图标 任务栏左边没问题 窗口键和快捷图标都良好 右侧的系统图标无显示 只显示任务栏的底色 尝试操作隐藏任务栏再开启任务栏后 图标恢复正常了 再点击右侧任务栏任意图标
  • 网络环路导致公司网络瘫痪问题排查

    问题 公司网络突然很不稳定 跟踪发现大量丢包 问题排查 1 怀疑电信网络 设备有问题 联系电信经理 安排工程人员过来排查 排查发现入户网络正常 更换电信入户光猫后网络还是不稳定 还是大量丢包 2 机房排查 2 1 关闭所有交换机 然后再一台
  • Anaconda换国内源(清华源、中科大源)

    命令行执行 Windows下 Anaconda 清华源 conda config add channels https mirrors tuna tsinghua edu cn anaconda pkgs free conda config
  • PPP协议实现透明传输的2种方法以及工作状态

    文章目录 1 PPP协议帧格式 2 字节填充 2 1 零比特填充方法 不使用序号和确认机制 PPP协议的工作状态 1 PPP协议帧格式 7E 十六进制数0x7E 在PPP协议里代表帧头和帧尾 二进制表示为0111 1110 占一个子节 FF
  • 机器学习SVM函数

    目录 1 SVM的损失函数 2 SVM的核方法 2 1 什么是核函数 2 1 1 核函数概念 2 1 2 核函数举例 2 1 2 1 核方法举例1 2 1 2 2 核方法举例2 2 2 常见核函数 2 3 小结 3 SVM回归 1 SVM的
  • springboot的负载均衡

    springboot的负载均衡 eueka作为注册中心 负载均衡使用的是Ribbon Ribbon负载均衡的策略有轮询 重试 权重 默认轮询 这是它独特的算法去调用具体的服务 在消费者启动动类中加上 Bean LoadBalanced pu
  • C++ 机房预约系统(七):老师模块——老师登录和注销、查看所有预约功能、审核预约功能的具体实现

    9 教师模块 在这个模块中 登录和注销和管理员与学生的实现一样 查看所有预约也和学生的查看所有预约实现一样 审核预约基本上和学生的取消预约一样 不同的是 学生模块 是通过学号和预约状态找到可以取消的预约记录 在老师模块 是通过预约状态找到可
  • Ik分词器(自定义分词-mysql)

    引言 ik分词器的分词范围不够广泛 某些特定行业的专业用语分词能力就不够了 此时就需要自定义分词 与停顿词 1 下载ik分词器源码 git地址 https github com medcl elasticsearch analysis ik
  • Lombok 的正确使用姿势

    文章目录 1 Lombok 是什么 2 安装 Lombok 3 Spring Boot 集成 Lombok 4 使用 Lombok 4 1 注解一览表 4 2 部分使用介绍 Getter lazy true Value Builder Su