java 面试题汇总整理

java有哪四种引用类型

在Java中,有四种引用类型,用于控制对象的生命周期和垃圾回收行为。这些引用类型包括:

  1. 强引用(Strong Reference)

    • 强引用是最常见的引用类型,它们是默认的引用类型。
    • 当一个对象具有强引用时,垃圾回收器不会回收这个对象,即使内存不足也不会回收。
    • 只有当所有强引用都不再指向某个对象时,垃圾回收器才会回收它。
  2. 软引用(Soft Reference)

    • 软引用用于描述一些还有用但不是必需的对象。
    • 当内存不足时,垃圾回收器会尝试回收被软引用引用的对象,但只有在内存真正不足的情况下才会回收。
    • 软引用通常用于缓存等场景,以便在内存不足时释放缓存。
  3. 弱引用(Weak Reference)

    • 弱引用用于描述一些非必需的对象,但在下一次垃圾回收时就会被回收。
    • 弱引用通过java.lang.ref.WeakReference类来实现。
    • 一旦没有强引用引用一个对象,即使还有弱引用引用它,垃圾回收器也会回收该对象。
  4. 虚引用(Phantom Reference)

    • 虚引用是最弱的引用类型,用于监控对象被垃圾回收的情况。
    • 虚引用通过java.lang.ref.PhantomReference类来实现。
    • 虚引用不会阻止对象被回收,但允许在对象被回收之前执行一些清理操作。

引用类型的选择取决于对象的生命周期和应用程序的需求。强引用用于维持对象的持久性,而软引用和弱引用用于实现缓存和内存敏感的对象,虚引用则用于执行对象的清理操作。理解这些引用类型可以帮助开发人员更好地管理内存和资源。

ThreadLocal 使用的哪种类型的引用

ThreadLocal 使用弱引用(Weak Reference)来管理对象的引用。这意味着当一个对象只被 ThreadLocal 引用时,如果没有其他强引用指向这个对象,垃圾回收器有可能在适当的时候回收该对象。弱引用的使用允许 ThreadLocal 在不再需要对象时自动释放对对象的引用,从而避免潜在的内存泄漏问题。

ThreadLocal 主要用于在每个线程中存储独立的数据,每个线程拥有自己的数据副本。当线程结束时,线程本地存储中的数据会被自动回收,因此使用弱引用确保了在没有外部强引用的情况下,线程局部存储中的数据可以被垃圾回收。

需要注意的是,尽管 ThreadLocal 使用弱引用来管理对象引用,但在某些情况下,如果没有正确清理 ThreadLocal 变量,仍然可能导致内存泄漏问题。因此,使用 ThreadLocal 时需要小心,确保在不再需要线程局部存储中的数据时进行适当的清理或移除。

threadLocal是什么,简单的介绍一下

ThreadLocal 是 Java 中的一个类,用于在多线程环境中创建线程局部变量。线程局部变量是一种特殊的变量,每个线程都拥有自己的副本,互不干扰。简单来说,ThreadLocal 允许你为每个线程存储和维护其自己的数据,这些数据对其他线程是不可见的。

以下是 ThreadLocal 的一些关键特点和用途:

  1. 线程隔离ThreadLocal 变量允许每个线程在其内部存储自己的数据,不会与其他线程共享。这可以用于避免线程之间的数据冲突和竞态条件。

  2. 数据共享ThreadLocal 可以用于在多线程应用程序中共享数据,而不需要显式地传递数据参数或使用全局变量。

  3. 线程上下文ThreadLocal 常用于存储与线程相关的上下文信息,如用户身份认证信息、数据库连接、会话信息等。

  4. 线程安全性:由于每个线程都拥有自己的变量副本,ThreadLocal 变量本身在多线程环境中通常是线程安全的。

  5. 内存泄漏风险:需要小心管理 ThreadLocal 变量,以防止可能的内存泄漏。如果不及时清理 ThreadLocal 变量,可能会导致不再需要的数据一直存在于内存中。

使用 ThreadLocal 的典型场景包括:

  • 在Web应用程序中存储用户会话信息,以便每个用户的请求都能访问其自己的会话数据。
  • 在数据库连接池中管理数据库连接,确保每个线程都有自己的数据库连接,而不需要共享。
  • 在日志记录中存储线程特定的上下文信息,如请求ID或用户身份信息。

需要注意的是,虽然 ThreadLocal 可以解决多线程环境中的一些问题,但过度使用它也可能导致代码变得难以理解和维护,因此在使用时需要谨慎考虑,确保合理使用。

子类获取父类的泛型类型

在 Java 中,子类无法直接获取父类的泛型类型参数信息。泛型信息在编译时会被类型擦除,因此在运行时无法直接访问泛型类型参数。但是,可以通过反射来获取泛型类型参数的信息,尽管这需要更复杂的代码。

以下是一个示例,演示了如何使用反射获取父类的泛型类型参数的类型:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;class Parent<T> {public Parent() {// 使用反射获取泛型类型参数的类型Type genericSuperclass = getClass().getGenericSuperclass();if (genericSuperclass instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;Type[] typeArguments = parameterizedType.getActualTypeArguments();if (typeArguments.length > 0) {Type typeArgument = typeArguments[0];System.out.println("Generic Type: " + typeArgument.getTypeName());}}}
}class Child extends Parent<String> {// 子类不需要显式传递泛型类型参数的类型
}public class Main {public static void main(String[] args) {Child child = new Child();}
}

在上面的示例中,父类 Parent 在其构造函数中使用反射获取了泛型类型参数的类型。子类 Child 继承了父类,不需要显式传递泛型类型参数的类型。

需要注意的是,这种方式使用了 Java 的反射机制,可能会导致代码复杂性增加,并且反射操作会带来一定的性能开销。因此,建议在真正需要获取泛型类型信息时再使用这种方法,同时要小心处理异常情况。

线程的sleep和wait的区别?

sleepwait 都是用于线程控制的方法,但它们在用途和行为上有明显的区别:

  1. sleep

    • sleepThread类的静态方法,用于使当前线程进入休眠状态(暂停执行),让其他线程有机会运行。
    • sleep 方法接受一个参数,即线程休眠的时间,以毫秒为单位。线程在休眠期间不会释放持有的锁,因此其他线程无法获得锁并执行同步方法或代码块。
    • sleep 方法通常用于实现等待一段时间后再执行某个操作的场景,如定时任务等。
    try {Thread.sleep(1000); // 休眠1秒
    } catch (InterruptedException e) {// 处理中断异常
    }
    
  2. wait

    • waitObject 类的方法,用于在多线程之间进行协调和通信。调用 wait 方法会使当前线程进入等待状态,同时释放对象的锁。
    • wait 方法通常与 notifynotifyAll 方法一起使用,以实现线程之间的协作。等待的线程会在其他线程调用相同对象的 notifynotifyAll 方法时被唤醒。
    • wait 方法必须在同步块或同步方法中调用,因为它要求当前线程拥有对象的监视器锁(即在同步块或同步方法中获取的锁)。
    synchronized (lockObject) {try {lockObject.wait(); // 等待其他线程唤醒} catch (InterruptedException e) {// 处理中断异常}
    }
    

总结:

  • sleep 主要用于线程的休眠,等待一段时间后恢复执行,不会释放锁。
  • wait 主要用于线程之间的协作和通信,等待其他线程的通知或条件满足时恢复执行,并且会释放对象的锁。
  • wait 必须在同步块或同步方法中使用,而 sleep 不需要。
  • 使用 sleep 时,线程会在指定的时间后自动唤醒,而使用 wait 时,线程需要等待其他线程显式唤醒。

线程池中确定核心线程数的个数的公式?

确定线程池中核心线程数的个数没有一个固定的公式,因为它依赖于多个因素,包括应用程序的性质、硬件资源、负载预测和性能要求等。然而,可以根据以下一般原则来决定核心线程数:

  1. CPU核心数:通常情况下,将核心线程数设置为可用CPU核心数是一个合理的起点。这可以充分利用多核处理器的性能,使得线程池能够并行执行任务。

  2. 任务性质:任务的性质对核心线程数也有影响。如果任务是CPU密集型的,那么核心线程数可以设置得较低,因为CPU密集型任务不会频繁地阻塞等待外部资源。如果任务是I/O密集型的,可能需要更多的线程来处理等待I/O操作完成的情况。

  3. 响应时间要求:如果应用程序对响应时间有较高的要求,可能需要增加核心线程数,以减少任务等待执行的时间。较多的核心线程可以更快地响应任务请求。

  4. 负载预测:根据负载预测来调整核心线程数也是一个常见的做法。如果可以预测到应用程序的负载将在未来的某个时间段内增加,可以提前增加核心线程数以满足预期的需求。

  5. 性能测试:最终的线程数设置通常需要经过性能测试和监控来确定。通过观察线程池的性能指标,如平均响应时间、任务执行时间、任务队列长度等,可以调整核心线程数以获得最佳性能。

需要注意的是,线程池的性能不仅取决于核心线程数,还与任务队列、最大线程数、拒绝策略等参数有关。因此,在确定核心线程数时,也需要综合考虑这些参数的配置。

最终,确定核心线程数的个数通常是一个基于应用程序特性和性能需求的经验性决策,需要根据实际情况进行调整和优化。在实际应用中,可以使用性能测试和监控工具来帮助确定最佳的核心线程数。

简单介绍一下epoll多路复用

epoll 是一种在Linux操作系统上提供的多路复用机制,用于高效地管理大量的文件描述符(通常是套接字文件描述符),以实现高性能的I/O多路复用。epoll 在Linux中取代了传统的selectpoll系统调用,它的设计目标是更好地处理大规模的并发连接和事件处理。

以下是epoll多路复用的一些关键特点和工作原理:

  1. 事件驱动epoll是事件驱动的,它等待并处理发生在文件描述符上的事件。这些事件可以包括套接字上有新连接到达、套接字可读或可写、套接字发生错误等。

  2. 高性能:与selectpoll相比,epoll在处理大量文件描述符时表现更好,因为它使用了更高效的数据结构和算法。epoll不会随着文件描述符数量的增加而线性扩展,因此适用于高并发的场景。

  3. 三个接口epoll提供了三个主要的系统调用接口,分别是epoll_createepoll_ctlepoll_wait

    • epoll_create:用于创建一个epoll实例,返回一个文件描述符,用于后续的epoll操作。
    • epoll_ctl:用于向epoll实例中添加、修改或删除文件描述符,并指定关注的事件类型。
    • epoll_wait:用于等待事件发生,一旦有事件发生,它会返回一个包含就绪文件描述符的列表。
  4. 边缘触发和水平触发epoll支持两种事件触发方式,即边缘触发(Edge-Triggered,ET)和水平触发(Level-Triggered,LT)。边缘触发仅在文件描述符状态发生变化时通知一次,而水平触发则在文件描述符就绪时通知。

  5. 高度可配置epoll提供了丰富的配置选项,可以根据需要调整不同的参数,以满足具体的应用场景。

epoll多路复用在高性能网络编程中被广泛使用,特别是在服务器端应用程序中,因为它能够有效地管理大量并发连接和高吞吐量的I/O操作。但需要注意,epoll是Linux特有的机制,不同的操作系统使用不同的多路复用机制,如BSD上的kqueue和Windows上的IOCP。因此,在编写跨平台的应用程序时需要考虑不同操作系统的差异。

造成线程阻塞的原因

线程阻塞是指线程在执行过程中被暂停或阻止继续执行的状态。线程阻塞的原因多种多样,以下是一些常见的造成线程阻塞的原因:

  1. 等待I/O操作完成:线程在进行输入/输出操作时,如果涉及到读取文件、网络通信、数据库查询等需要等待外部资源返回的操作,线程会被阻塞,直到I/O操作完成。

  2. 等待锁:当线程尝试访问一个已经被其他线程持有的锁时,它会被阻塞,直到锁被释放。这种情况常见于多线程并发编程中,用于确保多个线程之间的同步。

  3. 等待条件满足:线程可能被要求等待某个条件达到,然后才能继续执行。这通常与线程间的协作和通信有关,例如使用waitnotify方法。

  4. 休眠(Sleep):线程可以通过调用Thread.sleep方法来主动休眠一段时间,使线程进入阻塞状态,等待指定的时间后才会继续执行。

  5. 等待系统资源:有些操作需要等待系统资源的可用性,如申请内存或文件句柄。线程可能会因为等待系统资源而被阻塞。

  6. 死锁:死锁是多线程编程中的一种特殊情况,其中多个线程相互等待对方释放锁,导致所有线程都无法继续执行。

  7. 线程调度:线程调度器可能会导致线程在多个就绪线程之间切换,这也可能导致线程被阻塞。

  8. 异常情况:某些异常情况,如未捕获的异常,可能会导致线程被终止或异常退出,从而造成线程阻塞。

  9. 等待用户输入:在图形用户界面(GUI)或命令行应用程序中,线程可能会等待用户输入或交互操作,直到用户完成输入才能继续执行。

线程阻塞是多线程编程中需要特别注意的问题之一,因为不合理的阻塞可能导致性能下降或应用程序的不稳定性。因此,开发人员需要仔细管理线程的状态,确保线程在需要阻塞时合理地等待,以避免潜在的问题。

什么是读写锁

读写锁(Read-Write Lock)是一种用于多线程编程的同步机制,它允许多个线程同时读取共享数据,但在写操作时需要互斥,即写操作是排他的。读写锁的目的是提高多线程环境下对共享数据的访问效率,特别是在读操作比写操作频繁的情况下。

读写锁具有两种锁状态:读锁(共享锁)和写锁(排他锁),并提供以下特性:

  1. 多个线程可以同时持有读锁:多个线程可以同时获取并持有读锁,这意味着它们可以并发地读取共享数据而不会相互干扰。这对于读操作频繁但写操作较少的情况非常有用。

  2. 写锁是排他的:当一个线程持有写锁时,其他线程不能同时持有读锁或写锁。这确保了写操作是互斥的,防止写线程和读线程之间的竞争条件。

  3. 写锁优先于读锁:如果一个线程持有写锁,并且有其他线程在等待获取写锁,那么写锁的优先级更高,这意味着写线程将获得写锁,并且其他线程将等待写线程释放锁后才能继续执行。

读写锁通常用于以下情况:

  • 当读操作频繁而写操作较少时,可以使用读写锁来提高性能,因为多个线程可以同时读取数据而无需互斥。
  • 当需要对共享数据进行读取和更新操作时,可以使用读写锁来确保写操作的互斥性,以防止写线程与读线程之间的竞争条件。

在Java中,java.util.concurrent包提供了ReentrantReadWriteLock类,它是一个可重入的读写锁的实现,可以在多线程编程中使用。使用读写锁需要谨慎,根据具体的应用场景来合理选择何时获取读锁和写锁,以充分利用多线程的并发性和提高性能。

什么是可重入锁

可重入锁(Reentrant Lock)是一种支持同一个线程多次获取锁的锁机制。也就是说,当线程已经获得了某个锁后,如果再次尝试获取同一个锁,它会成功而不会被阻塞。可重入锁的主要特点是同一个线程可以多次获取锁,而不会发生死锁。

可重入锁通常用于多线程编程中,提供了更灵活的锁定机制,允许线程在多个嵌套的方法调用中获取和释放锁,而不必担心死锁或其他同步问题。这对于复杂的线程逻辑和代码组织非常有用。

在Java中,java.util.concurrent包提供了ReentrantLock类,它是可重入锁的一种实现。以下是可重入锁的一些关键特点:

  1. 可重入性:同一个线程可以多次获得同一个可重入锁,而不会被阻塞。线程每次获取锁后,都会维护一个锁计数器,当计数器为零时,锁被释放。

  2. 公平性:可重入锁可以配置为公平锁或非公平锁。在公平锁模式下,锁将按照请求的顺序分配给等待线程。在非公平锁模式下,锁可能会分配给等待时间较短的线程,以提高性能。

  3. 条件变量:可重入锁通常提供了条件变量(Condition)的支持,允许线程等待特定的条件得到满足后再继续执行。这在一些线程协作的场景中非常有用。

  4. 可中断性:可重入锁允许等待锁的线程响应中断,当线程处于等待锁状态时,可以通过中断线程来取消等待。

  5. 超时等待:可重入锁通常支持超时等待,允许线程在一定时间内等待锁,如果超过指定的时间仍未获取锁,线程可以继续执行其他操作。

可重入锁是一种强大的同步机制,但需要谨慎使用,以避免潜在的死锁和性能问题。在多线程编程中,它可以用来代替传统的synchronized关键字来实现更灵活的同步控制。

java的stream流

Java 8引入了Stream流,它是一个用于处理集合数据(包括数组、集合等)的新的抽象概念。Stream提供了一种声明性的、函数式的方式来处理数据,可以大大简化集合操作,使代码更具可读性和可维护性。

以下是Stream流的一些关键概念和用法:

  1. 创建流:可以通过多种方式创建Stream流,包括从集合、数组、文件等数据源创建。例如:

    List<String> list = Arrays.asList("apple", "banana", "cherry");
    Stream<String> stream = list.stream();
    
  2. 中间操作:中间操作是对流进行处理的一系列操作,这些操作不会立即执行,而是返回一个新的流。中间操作包括filtermapdistinctsortedlimit等,用于筛选、转换、排序和截断数据。

    Stream<String> filteredStream = list.stream().filter(s -> s.startsWith("a")).map(String::toUpperCase);
    
  3. 终端操作:终端操作是对流进行最终处理的操作,它们会触发流的处理并返回结果。终端操作包括forEachcollectreducecountminmax等,用于遍历、收集、统计、计算等操作。

    filteredStream.forEach(System.out::println);
    long count = list.stream().count();
    
  4. 惰性求值Stream流是惰性求值的,这意味着在执行终端操作之前,中间操作不会立即执行。这样可以减少不必要的计算和内存开销。

  5. 流的并行处理Stream可以轻松实现并行处理,通过调用parallel方法将流转换为并行流,可以充分利用多核处理器的性能。

    Stream<String> parallelStream = list.parallelStream();
    
  6. 可复用性Stream流是可复用的,可以对同一个流进行多次操作,每次操作都会返回一个新的流,不会影响原始流。

    Stream<String> stream1 = list.stream().filter(s -> s.length() > 5);
    Stream<String> stream2 = stream1.map(String::toUpperCase);
    
  7. 自动关闭资源Stream可以自动关闭底层的资源,例如文件流。当使用try-with-resources块时,Stream会在块结束时自动关闭。

    try (Stream<String> lines = Files.lines(Paths.get("file.txt"))) {lines.forEach(System.out::println);
    } catch (IOException e) {// 处理异常
    }
    

Stream流提供了一种更现代、更函数式的方式来处理集合数据,可以使代码更加清晰、简洁,并且支持并行处理,有助于提高性能。在使用Stream时,需要了解各种中间操作和终端操作的用法,以满足不同的数据处理需求。

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

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

相关文章

ChatGPT:革命性的自然语言处理技术

自然语言处理&#xff08;NLP&#xff09;技术的快速发展已经为我们的日常生活带来了巨大的变革。在这个领域&#xff0c;ChatGPT作为一个突出的代表&#xff0c;正在为我们带来更多的便利和机会。本文将介绍ChatGPT的基本概念、应用领域以及它在未来可能带来的影响。 ChatGPT…

Python UI自动化 —— 关键字+excel表格数据驱动

步骤&#xff1a; 1. 对selenium进行二次封装&#xff0c;创建关键字的库 2. 准备一个表格文件来写入所有测试用例步骤 3. 对表格内容进行读取&#xff0c;使用映射关系来对用例进行调用执行 4. 执行用例 1. 对selenium进行二次封装&#xff0c;创建关键字的库 from time imp…

【SpingBoot】详细介绍SpringBoot项目中前端请求到数据库再返回前端的完整数据流转,并用代码实现

在SpringBoot项目中&#xff0c;前端请求到最终返回的完整数据流转一般包括以下几个步骤&#xff1a; 前端发送HTTP请求到后端Controller。 Controller接收到请求后&#xff0c;调用相关Service处理业务逻辑。 Service调用DAO层获取数据。 DAO层访问数据库获取数据。 数据库…

【51单片机实验笔记】中断篇(一) 外部中断

目录 前言中断系统概述寄存器说明中断优先级寄存器&#xff08;IP&#xff09;中断允许控制寄存器&#xff08;IE&#xff09;中断请求标志寄存器&#xff08;TCON&#xff09; 外部中断配置软件实现按键事件的外部中断实现 遇到的问题总结 前言 中断是单片机非常重要的概念&a…

2021江苏省赛热身赛 C Magic Rabbit(数形结合)

2021江苏省赛热身赛 C Magic Rabbit(数形结合) Magic Rabbit 非常好且巧妙地一道题。 大意&#xff1a;给出三种溶液 &#xff0c; 三种溶液分别含有不同浓度的 x &#xff0c;y 两种物质。 溶液x (mg/ml)y (mg/ml)溶液1x1y1溶液2x2y2溶液3x3y3 给出 Q 组询问 &#xff0c…

MySQL 8.0.34安装教程

一、下载MySQL 1.官网下载 MySQL官网下载地址&#xff1a; MySQL :: MySQL Downloads &#xff0c;选择下载社区版&#xff08;平时项目开发足够了&#xff09; 2.点击下载MySQL Installer for Windows 3.选择版本8.0.34&#xff0c;并根据自己需求&#xff0c;选择下载全社区安…

flutter报错-cmdline-tools component is missing

安装完androidsdk和android studio后&#xff0c;打开控制台&#xff0c;出现错误 解决办法 找到自己安装android sdk的位置&#xff0c;然后安装上&#xff0c;并将下面的勾选上 再次运行 flutter doctor 不报错&#xff0c;出现以下画面 Doctor summary (to see all det…

WebSocket的那些事(5-Spring中STOMP连接外部消息代理)

目录 一、序言二、开启RabbitMQ外部消息代理三、代码示例1、Maven依赖项2、相关实体3、自定义用户认证拦截器4、Websocket外部消息代理配置5、ChatController6、前端页面chat.html 四、测试示例1、群聊、私聊、后台定时推送测试2、登录RabbitMQ控制台查看队列信息 五、结语 一、…

超图嵌入论文阅读2:超图神经网络

超图嵌入论文阅读2&#xff1a;超图神经网络 原文&#xff1a;Hypergraph Neural Networks ——AAAI2019&#xff08;CCF-A&#xff09; 源码&#xff1a;https://github.com/iMoonLab/HGNN 500star 概述 贡献&#xff1a;用于数据表示学习的超图神经网络 (HGNN) 框架&#xf…

【高阶数据结构】红黑树 {概念及性质;红黑树的结构;红黑树的实现;红黑树插入操作详细解释;红黑树的验证}

红黑树 一、红黑树的概念 红黑树&#xff08;Red Black Tree&#xff09; 是一种自平衡二叉查找树&#xff0c;在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有…

旅游APP外包开发注意事项

旅游类APP通常具有多种功能&#xff0c;以提供给用户更好的旅行体验。以下分享常见的旅游类APP功能以及在开发和使用这些APP时需要注意的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 常见功能…

八大排序算法----堆排序

堆排序的基本步骤&#xff1a;&#xff08;以从大到小的顺序排序为例&#xff09; 1.构建大顶堆&#xff08;每个结点的值都大于或等于其左右孩子结点的值&#xff09; 2.排序&#xff1a;每次堆顶的元素取出来&#xff08;整个堆中值最大&#xff09;&#xff0c;与最后一个…

drf之--认证组件、权限组件(django项目国际化)、频率组件、排序

视图集回顾 # 1 9 个视图子类-GenericAPIView5个视图扩展类的组合-ListAPIView,CreateAPIView,DestroyAPIView,RetrieveAPIView,UpdateAPIView-ListCreateAPIView-RetrieveDestroyAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView-class TestView(ListAPIView):qu…

数学建模圈养湖羊的空间利用率

数学建模圈养湖羊的空间利用率 问题&#xff1a;规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&#xff1b;与此同时&#xff0c;也要尽量减少空间闲置所造成的资源浪费…

Code Inspector:点击页面元素自动定位到代码

Code Inspector是一个开发提效的神器 点击页面上的 DOM 元素&#xff0c;它能自动打开 IDE 并定位到 DOM 对应源代码位置 文档 https://inspector.fe-dev.cn/https://github.com/zh-lx/code-inspector 目录 1、安装2、配置2.1、webpack2.2、vue2.3、vite 3、使用 1、安装 n…

入栏需看——学习记忆

记忆方法千千种&#xff0c;本栏意在梳理其中道道来&#xff0c;旦有小得&#xff0c;肥肠幸耶。从不同角度分析学习记忆。 逻辑篇 有逻辑 用思维导图 思维导图记忆有逻辑的文本/内容 理论 巧记书本结构–思维导图 模仿 HCIE-Cloud Computing LAB备考第一步&#xff1a…

Python基于Mirai开发的QQ机器人保姆式教程(亲测可用)

在本教程中&#xff0c;我们将使用Python和Mirai来开发一个QQ机器人&#xff0c;本文提供了三个教学视频&#xff0c;包教包会&#xff0c;本文也很贴心贴了代码和相关文件。话不多说&#xff0c;直接开始教学。 目录 一、安装配置MIrai 图片验证码报错&#xff1a; 二、机器…

vue-cli中总提示组件没有正确注册

这里写目录标题 一、报错提示二、修改办法 一、报错提示 二、修改办法 <template><div><aside-component style"width: 15%"></aside-component></div> </template><script> import AsideComponent from /components/Asi…

【学习方法论】学习的三种境界、三种习惯、三个要点,三个心态

学习的三种境界、三种习惯、三个要点&#xff0c;三个心态 三种学习境界 苦学 古人云&#xff1a;“头悬梁、锥刺股”&#xff0c;勤学苦练是第一境界。处于这种层次的同学&#xff0c;觉得学习枯燥无味&#xff0c;对他们来说学习是一种被迫行为&#xff0c;体会不到学习中的…

NATAPP使用详细教程(免费隧道内网映射)

NATAPP - https://natapp.cn/tunnel/lists NATAPP 在开发时可能会有将自己开发的机器上的应用提供到公网上进行访问&#xff0c;但是并不想通过注册域名、搭建服务器&#xff1b;由此可以使用natapp&#xff08;内网穿透&#xff09; 购买免费隧道 修改隧道配置 看自己的web…