北京--面试1(设计模式、反射、队列、线程、锁、Linux命令、JVM调优参数)

1、写三个设计模式(代码)

//单例懒汉模式:单例模式确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式被广泛用于控制资源访问,配置管理器等场景。实现单例模式的方式包括懒汉式、饿汉式、双重检查锁等。
public class Singleton {private static volatile Singleton instance;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}//工厂模式:工厂模式用于创建对象,但隐藏了对象的创建逻辑。通过定义一个接口或抽象类,工厂模式允许子类决定实例化哪个类。在Java中,工厂模式常被用于处理对象的创建,使得代码更具灵活性和可维护性。interface Car {void drive();
}class MPV implements Car {@Overridepublic void drive() {}
}class SUV implements Car {@Overridepublic void drive() {}
}class CarFactory {public Car getCar(String carType) {if (carType == null) {return null;}if (carType.equalsIgnoreCase("MPV")) {return new MPV();} else if (carType.equalsIgnoreCase("SUV")) {return new SUV();}return null;}
}
//代理模式-动态代理:动态代理模式是一种在运行时动态创建代理对象的机制,它允许开发者在无需修改原有代码的基础上,为特定接口或类的对象提供额外的逻辑或功能,如方法拦截、增强、日志记录、权限检查、事务管理等。
//这种模式实现了代理设计模式的动态版本,其中代理对象与委托对象(即被代理的对象)具有相同的接口,代理对象在方法调用前后可以执行额外的操作,然后将调用转发给委托对象。
// 定义一个接口,被代理对象需要实现该接口
public interface MyInterface {void doSomething();
}// 被代理对象,实现MyInterface接口
public class RealObject implements MyInterface {@Overridepublic void doSomething() {System.out.println("Real object doing something...");}
}// 实现InvocationHandler接口,提供代理逻辑
public class MyInvocationHandler implements InvocationHandler {private Object target; // 被代理对象public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("Before method call: " + method.getName());// 调用目标对象的方法Object result = method.invoke(target, args);System.out.println("After method call: " + method.getName());return result;}
}public class DynamicProxyExample {public static void main(String[] args) {// 创建被代理对象MyInterface realObject = new RealObject();// 创建InvocationHandler实例,传入被代理对象InvocationHandler handler = new MyInvocationHandler(realObject);// 通过Proxy.newProxyInstance创建动态代理对象MyInterface proxy = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),new Class[]{MyInterface.class},handler);// 通过代理对象调用方法,此时会触发代理逻辑proxy.doSomething();}
}

2、不使用Java自带的BlockingQueue,实现一个阻塞队列,要求有删除和增加方法以及线程安全--考察阻塞队列(代码)

(1)先看下 JDK17 中 ArryBlockingQueue 的实现方式

主要思想依旧是基于数组实现阻塞队列。ArrayBlockingQueuejava.util.concurrent 包下的一个类,实现了 BlockingQueue 接口,提供了一个有界的阻塞队列,其中元素按 FIFO(先进先出)的顺序进行排序。

数据结构: ArrayBlockingQueue 内部使用一个定长数组(Object[] items)存储元素,并维护两个索引变量:

   takeIndex:指向下一个可供消费者取出(take() 或 poll())的元素位置。

   putIndex:指向下一个可供生产者放入(put() 或 offer())新元素的位置。

线程同步: 为了保证线程安全性,ArrayBlockingQueue 使用一个可重入锁(ReentrantLock)来保护队列的访问,并且使用两个相关的条件变量(notEmpty 和 notFull)来实现阻塞和唤醒操作。当队列满时,尝试入队的线程会被阻塞在 notFull 上;当队列空时,尝试出队的线程会被阻塞在 notEmpty 上。

主要方法实现

  1. 入队操作

  2. put(E e):将元素添加到队列尾部。如果队列已满,则当前线程会被阻塞,直到有空间可用(即有其他线程消费了一个元素,使得队列不再满)。    

  3. offer(E e):类似 put(),但非阻塞版本。如果队列满,立即返回 false,不等待。

  4. 出队操作

  5. take():从队列头部移除并返回一个元素。如果队列为空,则当前线程会被阻塞,直到有元素可用(即有其他线程生产了一个元素,使得队列不再空)。poll():类似 take(),但非阻塞版本。如果队列空,立即返回 null,不等待。

  6. 容量控制

  7. ArrayBlockingQueue 在构造时指定固定容量,一旦创建,容量不可变。

  8. 入队时检查 putIndex 是否超过数组长度,若超过则回绕至数组起始处。若此时 takeIndex == putIndex(即队列已满),则阻塞生产者线程。

  9. 出队时检查 takeIndex 是否超过数组长度,若超过则回绕至数组起始处。若此时 takeIndex == putIndex(即队列已空),则阻塞消费者线程。

  10. 其他方法

  11. peek():查看队头元素但不移除,若队列为空返回 null

  12. size()remainingCapacity()isEmpty()isFull() 等方法用于查询队列状态,均受内部锁保护,确保线程安全。

性能优化: ArrayBlockingQueue 的实现考虑了性能优化:

       使用循环数组实现,避免数组复制或扩容操作。

       利用条件变量精确地唤醒等待的线程,避免不必要的“惊群效应”(即一次性唤醒所有等待线程,只有一个是真正需要工作的)

public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {private static final long serialVersionUID = -817911632652898426L;// Conditionally serializableprivate final Object[] items;//items index for next take, poll, peek or removeprivate int takeIndex;//items index for next put, offer, or addprivate int putIndex;//Number of elements in the queueprivate int count;//并发控制使用经典的双条件算法//Main lock guarding all accessprivate final ReentrantLock lock;//Classes implementing Condition may be serializableprivate final Condition notEmpty;//Classes implementing Condition may be serializableprivate final Condition notFull;/*** 行参:capacity - 此队列的容量*      fair - 如果是 true 插入或删除时阻塞的队列的线程访问按照FIFO顺序处理;如果 false未指定访问顺序*     如果 capacity < 1 则抛出异常 IllegalArgumentException*/ public ArrayBlockingQueue(int capacity, boolean fair) {if (capacity <= 0)throw new IllegalArgumentException();this.items = new Object[capacity];lock = new ReentrantLock(fair);notEmpty = lock.newCondition();notFull =  lock.newCondition();}// 入队操作public void put(E e) throws InterruptedException {// 检查入队的元素是否为空,如果为空则抛出 NullPointerExceptionObjects.requireNonNull(e);// 获取可重入锁对象final ReentrantLock lock = this.lock;// 尝试获取锁,如果被中断则抛出 InterruptedExceptionlock.lockInterruptibly();try {// 当队列已满时,线程阻塞等待直到队列有空间可用while (count == items.length)notFull.await();// 将元素加入队列enqueue(e);} finally {// 无论如何都要释放锁,确保锁的正常释放lock.unlock();}}// 出队操作public E take() throws InterruptedException {// 获取可重入锁对象final ReentrantLock lock = this.lock;// 尝试获取锁,如果被中断则抛出 InterruptedExceptionlock.lockInterruptibly();try {// 当队列为空时,线程阻塞等待直到队列中有元素可取while (count == 0)notEmpty.await();// 从队列中取出元素并返回return dequeue();} finally {// 无论如何都要释放锁,确保锁的正常释放lock.unlock();}}}

(2)自己实现 ,仿照官方的来写就可以了

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class BlockingQueue<E> {private final Queue<E> queue;private final int capacity;private final Lock lock;private final Condition notFull;private final Condition notEmpty;public BlockingQueue(int capacity) {this.capacity = capacity;this.queue = new LinkedList<>();this.lock = new ReentrantLock();this.notFull = lock.newCondition();this.notEmpty = lock.newCondition();}public void enqueue(E element) throws InterruptedException {lock.lock();try {while (queue.size() == capacity) {// 队列已满,等待队列不满的条件notFull.await();}queue.offer(element);// 入队后唤醒可能在等待队列不空的线程notEmpty.signal();} finally {lock.unlock();}}public E dequeue() throws InterruptedException {lock.lock();try {while (queue.isEmpty()) {// 队列为空,等待队列不空的条件notEmpty.await();}E element = queue.poll();// 出队后唤醒可能在等待队列不满的线程notFull.signal();return element;} finally {lock.unlock();}}
}

3、怎么获取一个类的注解--考察反射(代码)

1、Class<?> clazz = Class.forName(className)

作用:通过全限定类名字符串动态加载并获取对应的Class对象。这是获取类的元数据入口点,所有反射操作都围绕Class对象展开。

2、Constructor<?>[] constructors = clazz.getConstructors()

作用:获取类的所有公共构造器(包括其参数类型、修饰符等信息)。可以进一步调用构造器的newInstance()方法创建对象。

3、Constructor<?> constructor = clazz.getDeclaredConstructor(paramTypes...)

作用:获取类的指定签名的构造器(包括私有构造器)。同样可用于创建对象。

4、Method[] methods = clazz.getMethods()

作用:获取类及其父类中所有公开的(包括继承的)方法。可用于获取方法名、返回类型、参数列表等信息,并通过invoke()方法调用它们。

5、Method method = clazz.getDeclaredMethod(methodName, paramTypes...)

作用:获取类中指定签名的(包括私有、受保护的)方法。同样可用于获取方法详情和调用方法。

6、Field[] fields = clazz.getFields()

作用:获取类及其父类中所有公开的(包括继承的)字段(属性)。可以获取字段名、类型、修饰符,并通过get()set()方法访问或修改字段值。

7、Field field = clazz.getDeclaredField(fieldName)

作用:获取类中指定名称的(包括私有、受保护的)字段。同样可用于获取字段详情和访问或修改字段值。

8、Object obj = clazz.newInstance()

作用:如果类有一个无参的公共构造器,此方法用于创建该类的新实例。等价于调用clazz.getConstructor().newInstance()

9、T result = (T) method.invoke(obj, args...)

作用:在给定对象上调用指定方法,并传递参数。返回方法的执行结果(如果有的话)。允许调用私有方法和访问受保护的属性。

10、field.setAccessible(true)

作用:设置字段或方法为可访问,即使它们原本是非公有的(如私有或受保护)。这对于反射操作中访问或修改私有成员非常关键。

11、AnnotatedType annotatedType = field.getAnnotatedType()

作用:获取字段的注解类型信息,包括注解及其元注解。用于处理元数据级别的自定义注解。

12、Class<?> superclass = clazz.getSuperclass()

作用:获取类的直接超类。可用于递归遍历类的继承层次结构。

13、Type[] genericInterfaces = clazz.getGenericInterfaces()

作用:获取类实现的所有泛型接口及它们的类型参数。对于理解类的泛型类型信息很有帮助。

14、Annotation[] annotations = clzz.getAnnotations();

作用:获取此类下所有的注解

4、同步锁(synchronized 、 ReentrantLock )的替代方案--考察对同步锁的理解(简述)

为什么要替代同步锁呢?主要有以下几个原因:

1、性能问题: 同步锁可能会引起线程之间的竞争,从而导致性能下降。另外,同步锁的粒度较大时,可能会导致线程间的阻塞,进一步影响性能。

2、死锁问题: 同步锁可能会引起死锁,当多个线程相互等待对方释放锁时,会出现死锁情况,导致程序无法继续执行。

3、复杂性: 使用同步锁需要开发人员手动管理锁的获取和释放,容易出现错误,增加了代码的复杂性和维护成本。

4、可扩展性: 使用同步锁会导致代码的耦合性增加,降低了代码的可扩展性和可重用性。使用替代方案可以更灵活地管理并发访问,提高了代码的可扩展性。 

同步锁的一些常见替代方案:

1、并发集合类(Concurrent Collections): Java并发包中提供了一些并发安全的集合类,如 ConcurrentHashMapConcurrentLinkedQueue 等。这些集合类是线程安全的,并且通常比使用同步锁更高效。

2、原子类(Atomic Classes): Java提供了一系列的原子类,如 AtomicIntegerAtomicReference 等,它们提供了一种无锁的线程安全的方式来更新共享变量的值。

3、并发工具类(Concurrency Utilities): Java并发包中提供了各种并发工具类,如 CountDownLatchSemaphoreCyclicBarrier 等,它们可以帮助我们更灵活地管理并发执行的任务。

4、无锁数据结构(Lock-Free Data Structures): 一些无锁数据结构可以实现高效的并发访问,如无锁队列、无锁链表等。这些数据结构通常使用原子操作来实现,避免了同步锁的性能开销和可能的死锁问题。

5、软件事务内存(Software Transactional Memory,STM): STM是一种高级的并发控制机制,它将代码块包装在事务中,类似于数据库中的事务,可以在事务中执行一系列的读写操作,然后提交或回滚。但在Java中,STM并不是标准库的一部分,需要使用第三方库实现。

5、快速排序(代码/思路)

快速排序是一种分治策略的排序算法,通过选取一个“基准”元素将数组划分为两个子序列,左边的元素小于基准,右边的元素大于基准。然后递归地对左右子序列进行同样的操作。  

public class QuickSort {// 快速排序方法,采用分治法策略public static void quickSort(int[] arr, int low, int high) {if (low < high) {// 找到分区点(pivot),将数组分为两部分:小于pivot的元素和大于pivot的元素int pivotIndex = partition(arr, low, high);// 对左右两边的子数组进行递归排序quickSort(arr, low, pivotIndex - 1);quickSort(arr, pivotIndex + 1, high);}}// 分区操作,返回pivot的位置private static int partition(int[] arr, int low, int high) {// 选取最后一个元素作为基准值int pivot = arr[high];int i = (low - 1);  // index of smaller elementfor (int j = low; j <= high - 1; j++) {// 如果当前元素小于或等于pivot,则交换位置并将较小元素索引后移if (arr[j] <= pivot) {i++;// 交换arr[i]和arr[j]int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将基准值与i+1位置上的元素交换,保证基准值左边的都比它小,右边的都比它大int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}public static void main(String[] args) {int[] array = {9, 7, 5, 11, 12, 2, 14, 3, 10, 6};quickSort(array, 0, array.length - 1);System.out.println("Sorted array: ");for (int num : array) {System.out.print(num + " ");}}
}

6、有 t1、t2、t3 三个线程,保证 t1、t2 同时执行, t3 在t1、t2之后执行(代码)

(1)使用计数器

通过计数法(倒计时器),让一些线程堵塞直到另一个线程完成一系列操作后才被唤醒;该⼯具通常⽤来控制线程等待,它可以让某⼀个线程等待直到倒计时结束,再开始执⾏。具体可以使用countDownLatch.await()来等待结果。多用于多线程通信。

  @Testvoid CountDownLatchTest() {//通过计数法(倒计时器)CountDownLatch latch = new CountDownLatch(2);Thread t1 = new Thread(() -> {System.out.println("Thread t1 is running");//省略模拟耗时操作latch.countDown();});Thread t2 = new Thread(() -> {System.out.println("Thread t2 is running");//省略模拟耗时操作latch.countDown();});Thread t3 = new Thread(() -> {try {latch.await(); // 等待t1和t2执行完毕} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("Thread t3 is running after t1 and t2");});t1.start();t2.start();t3.start();}

(2)使用CompletableFuture 

通过设置参数,可以完成CountDownLatch同样的多平台响应问题,但是可以针对其中部分返回结果做更加灵活的展示。

    @Testvoid CompletableFutureTest() {// 创建 CompletableFuture 对象CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {// 模拟耗时操作try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task t1 finished");});CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {// 模拟耗时操作try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Task t2 finished");});// 使用 thenCombine 方法等待 future1 和 future2 完成后执行 t3 线程CompletableFuture<Void> combinedFuture = future1.thenCombine(future2, (result1, result2) -> {System.out.println("Task t3 can run after t1 and t2 finished");return null;});try {// 等待 t3 线程执行完成combinedFuture.get();} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}

(3) 使用CyclicBarrier

可循环(Cyclic)使用的屏障(Barrier)。他要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。可以用于批量发送消息队列信息、异步限流。 

    @Testvoid CyclicBarrierTest() {CyclicBarrier barrier = new CyclicBarrier(3);Thread t1 = new Thread(new CyclicBarrierTask("Thread 1", barrier));Thread t2 = new Thread(new CyclicBarrierTask("Thread 2", barrier));Thread t3 = new Thread(new CyclicBarrierTask("Thread 3", barrier));t1.start();t2.start();t3.start();try {t1.join();t2.join();t3.join();} catch (InterruptedException e) {e.printStackTrace();}}class CyclicBarrierTask implements Runnable {final String name;final CyclicBarrier barrier;CyclicBarrierTask(String name, CyclicBarrier barrier) {this.name = name;this.barrier = barrier;}@Overridepublic void run() {System.out.println(name + " started.");try {// 执行任务...Thread.sleep((int) (Math.random() * 1000)); // 模拟耗时任务// 到达屏障,等待其他线程barrier.await();System.out.println(name + " finished.");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}}}

(4)使用Semaphore(信号量)

信号量主要用于两个目的,一个是用于多个共享资源的互斥作用,另一个用于并发线程数的控制。SpringHystrix限流的思想 

    @Testvoid SemaphoreTest(){Semaphore semaphore = new Semaphore(0); // 初始计数为0Thread t1 = new Thread(new SemaphoreTask(semaphore, "Thread 1"));Thread t2 = new Thread(new SemaphoreTask(semaphore, "Thread 2"));Thread t3 = new Thread(new SemaphoreTask(semaphore, "Thread 3"));t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}t3.start();}static class SemaphoreTask implements Runnable {private Semaphore semaphore;private String name;public SemaphoreTask(Semaphore semaphore, String name) {this.semaphore = semaphore;this.name = name;}@Overridepublic void run() {if (name.equals("Thread 3")) {try {semaphore.acquire(); // 等待许可} catch (InterruptedException e) {e.printStackTrace();}System.out.println(name + " is executing after Thread 1 and Thread 2");} else {System.out.println(name + " is executing");semaphore.release(); // 释放许可}}}

7、Linux命令:1、查找文件并删除;2、后台启动服务;3、使用java命令合理分配新生代和老年代

(1) 查找一个文件并删除它

find:

是一个强大的文件查找工具,可以递归地搜索指定目录及其子目录,并根据各种条件(如文件名、大小、类型、修改时间等)进行匹配。
locate:

基于系统维护的一个文件索引数据库
whereis:

主要用于查找二进制文件、源代码文件和帮助手册页的路径,适用于查找系统命令或程序相关文件。对于非系统级别的用户文件,可能无法找到
which:

命令用于查找可执行文件的路径,它会在环境变量 PATH 指定的目录列表中查找。主要用于查找系统命令或用户自定义的可执行脚本的路径。

第一种:find /path/to/search -name "filename" -type f -delete   
第二种:已知一个文件路径,使用   rm 文件路径   也可以删除/path/to/search: 要在哪个目录及其子目录下查找文件。请替换为实际的路径,如 /home/user 或 /var/log。
-name "filename": 根据文件名进行匹配。将 "filename" 替换为你想要查找的具体文件名,可以使用通配符(如 *.txt 或 file*)。
-type f: 只查找普通文件,避免删除目录。
-delete: 如果找到匹配的文件,直接删除它。

(2) 后台启动服务,实际就是deamon方式启动

nohup java -jar xxx.jar > app.log 2>&1 标准输出(stdout)被重定向到app.log文件,标准错误输出(stderr)通过2>&1被合并到标准输出中,同样写入app.log

(3) 使用java命令分配年轻带和老年代(优化代码结构 --> JVM参数调优)

-XX:+ :‘+’ 表示启用该选项

-XX:- :‘-’ 表示关闭该选项

-classpath-cp:指定 Java 类路径,用于告诉 JVM 在哪里查找类文件。

-D:用于设置系统属性。例如,-Dproperty=value 可以设置名为 property 的系统属性的值为 value

-Xmx:设置 Java 堆的最大内存。例如,-Xmx512m 表示最大堆大小为 512MB。

-Xms:设置 Java 堆的初始大小。例如,-Xms256m 表示初始堆大小为 256MB。

-Xmn:设置年轻代大小,增大年轻代后,将会减小年老代大小,官方推荐配置为整个堆的3/8。例如,-Xmn128m 表示年轻代大小为 128MB。

-Xss:设置线程堆栈大小。根据应用的递归深度、本地变量数量等因素调整,避免栈溢出或浪费内存。例如,-Xss1m 表示每个线程的堆栈大小为 1MB。

-XX:PermSize:设置永久代(PermGen)的初始大小。在 Java 8 及更高版本中已废弃

-XX:MaxPermSize:设置永久代(PermGen)的最大大小。在 Java 8 及更高版本中,PermGen 被元空间(Metaspace)取代。

-XX:MetaspaceSize:设置 Metaspace 的初始大小。例如,-XX:MetaspaceSize=256m 表示 Metaspace 的初始大小为 256MB。

-XX:MaxMetaspaceSize:设置 Metaspace 的最大大小。例如,-XX:MaxMetaspaceSize=256m 表示 Metaspace 的最大大小为 256MB。

-XX:MaxDirectMemorySize:设置最大直接内存(堆外)大小,例如,-XX:MaxDirectMemorySize=256m 表示最大直接内存为 256MB。

-verbose:gc:启用 GC 日志输出,用于调试和性能分析。

-XX:+PrintGCDetails:打印 GC 详细信息,默认关闭,可以通过jinfo -flag [+|-]PrintGCDetails <pid> 或 jinfo -flag PrintGCDetails=<value> <pid> 来动态开启或设置值

-Xloggc:/data/gclog/gc.log:GC日志文件路径

-XX:+UseGCLogFileRotation:滚动GC日志文件,须配置Xloggc

-XX:NumberOfGCLogFiles:滚动GC日志文件数,默认0,不滚动

-XX:GCLogFileSize:GC文件滚动大小,需配置UseGCLogFileRotation,设置为0表示仅通过jcmd命令触发

-XX:+PrintGCDateStamps:GC时打印时间戳信息,默认关闭

-XX:+PrintTenuringDistribution:打印存活实例年龄信息,默认关闭

-XX:+PrintGCApplicationStoppedTime:打印应用暂停时间,默认关闭

-XX:+PrintHeapAtGC:GC前后打印堆区使用信息,默认关闭

-XX:+UseG1GC:指定使用 G1 垃圾回收器。

-XX:MaxGCPauseMillis:设置目标停顿时间

-XX:InitiatingHeapOccupancyPercent:设置触发并发标记周期的堆占用百分比。

-XX:+HeapDumpOnOutOfMemoryError:当发生 OutOfMemoryError 错误时自动生成堆转储文件。

-XX:HeapDumpPath:指定堆转储文件的输出路径。

-XX:-OmitStackTraceInFastThrow:某些热点异常抛的太多的话,JVM默认会做优化,会使用JVM初始化的时候创建的异常代替实际的异常,这些异常是没有异常栈信息的,不方便定位问题,如果有碰到这种情况,可以考虑关闭这个配置

-XX:NewRatio:设置新生代和老年代的大小比例,例如 -XX:NewRatio=2

-XX:SurvivorRatio:设置 Eden 区和 Survivor 区大小比例,例如,-XX:SurvivorRatio=8 表示两个Survivor区与一个Eden区比值为2:8,一个Survivor占1/10

-XX:MaxTenuringThreshold:设置对象晋升到老年代的年龄阈值,当超过这个参数值时就进入老年代,最大支持15

-XX:+UseSerialGC:年轻代使用Serial垃圾收集器,不推荐使用,性能太差,老年代将会使用SerialOld垃圾收集器

-XX:InitialCodeCacheSize-XX:ReservedCodeCacheSize:设置代码缓存的初始大小和最大大小。

-XX:+ParallelCompilation:启用并行编译,对于CPU密集型应用,启用并行编译可以加快类的加载速度

-XX:CompileThreshold:指定方法被调用多少次后进行即时编译。

-XX:PretenureSizeThreshold:设置该参数,可以使大于这个值的对象直接在老年代分配,避免在Eden区和Survivor区发生大量的内存复制,该参数只对Serial和ParNew收集器有效,Parallel Scavenge并不认识该参数

-XX:ParallelGCThreads=16:并行执行gc的线程数

-XX:MaxGCPauseMillis:自适应大小策略的最大GC暂停时间目标(以毫秒为单位),或(仅G1)每个MMU时间片的最大GC时间

-XX:+DisableExplicitGC:禁止运行期显式地调用System.gc()来触发fulll GC​​​​​​​,不建议开启,如果开启了这个参数可能会导致堆外内存无法及时回收造成内存溢出

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

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

相关文章

Leetcode56_合并区间

1.leetcode原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 2.题目描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数…

Stable Diffusion|Ai赋能电商 Inpaint Anything

1. 背景介绍 随着人工智能技术的不断发展&#xff0c;其在电商领域的应用也越来越广泛。其中&#xff0c;图像修复技术在电商领域有着重要的应用价值。例如&#xff0c;在商品图片处理中&#xff0c;去除图片中的水印、瑕疵等&#xff0c;可以提高商品图片的质量和美观度。 2…

牛顿:Archetype AI 的开创性模型,实时解读真实世界的新宠儿

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

kafka命令行高级命令

#--time -1 查看topic各个partition 未过期最早offset --time -2 最后offest&#xff0c;根据二者差值计算存量数据 sh /usr/local/kafka9092/bin/kafka-run-class.sh kafka.tools.GetOffsetShell --bootstrap-server xxxxx:9092 --topic __consumer_offsets --time -1 #查…

不同系统锁库存的实现方式

目录 1. 系统内部实现锁库存 2. 使用中间件实现锁库存 3. 服务化实现锁库存 4. 分布式事务实现锁库存 1. 系统内部实现锁库存 描述&#xff1a;系统采用内部机制&#xff0c;如数据库事务、行锁或乐观锁等技术&#xff0c;来在必要的时候锁定库存。特点&#xff1a;实现细…

英语学习笔记-音节划分和字母发音对照表

国际音标 音节划分 英语音节以元音为主体构成的发音单位&#xff0c;一般说来元音发音响亮&#xff0c;可以构成音节&#xff0c;辅音发音不响亮&#xff0c;不能单独构成音节 ((m] (n] [I] 例外)。 从单词拼写形式上看&#xff0c;有几个元字组就有几个音节 音节划分规则 长…

[通俗易懂]《动手学强化学习》学习笔记1-第1章 初探强化学习

文章目录 前言第1章 初探强化学习1.1 简介序贯决策&#xff08;sequential decision making&#xff09;任务&#xff1a;强化学习与有监督学习或无监督学习的**区别**&#xff1a;改变未来 1.2 什么是强化学习环境交互与有监督学习的区别1&#xff1a;改变环境 &#xff08;说…

GPU环境安装与虚拟环境安装(适用于Windows下的李沐GPU)

之前我是用的都是VMware的虚拟机且安装的是cpu的pytorch版本,因为想要使用GPU,最终实现了在Windows上使用GPU,并且相关原理也在参考文章或视频内,可以通过原理自行挑选自己所需的配置并安装。 文章目录 1.GPU安装1.1 名词解释1.2 卸载旧版本的CUDA1.3 版本选择步骤(Nivida显卡…

ubuntu安装

一、安装虚拟机 https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html 下载后运行安装向导&#xff0c;一直Next即可 许可证&#xff1a; https://zhuanlan.zhihu.com/p/685829787#:~:textpro,17%E5%AF%86%E9%92%A5%EF%BC%9AMC60H-DWHD5-H80U9-6…

【SpringCloud】Nacos 配置管理

目 录 一.统一配置管理1. 在 nacos 中添加配置文件2. 从微服务拉取配置 二.配置热更新1. 方式一2. 方式二 三.配置共享1. 添加一个环境共享配置2. 在 user-service 中读取共享配置3. 运行两个 UserApplication&#xff0c;使用不同的 profile4. 配置共享的优先级5. 多服务共享配…

[STM32+HAL]DengFOC移植之闭环速度控制

一、前言&#xff1a; 有关闭环位置控制&#xff0c;详见[STM32HAL]DengFOC移植之闭环位置控制 二、Keil填写代码&#xff1a; 1、AS5600读取角位移 #include "AS5600.h" #include "math.h" #include "FOC2.h"float angle_prev0; // 最…

I2C协议介绍

I2C&#xff08;Inter-Integrated Circuit&#xff09;协议是一种广泛使用的串行通信协议&#xff0c;它允许多个设备通过两根线路进行通信。这种协议最初由Philips Semiconductor&#xff08;现在的NXP Semiconductors&#xff09;在1980年代推出&#xff0c;目的是简化集成电…

2024泰迪杯c题详细思路代码讲解:竞赛论文的辅助自动评阅

C&#xff1a;竞赛论文的辅助自动评阅 步骤一&#xff1a;理解拆解题目&#xff0c;并对附件1中的论文集进行初步分析。 步骤二&#xff1a;特征构造 论文完整性&#xff1a;开发算法以检查论文是否全面回答了赛题。这包括自然语言处理(NLP)技术来识别关键段落和论证的完整…

如何使用vscode启动Flask并实现无公网IP远程访问内网服务

文章目录 1. 安装部署Flask2. 安装Cpolar内网穿透3. 配置Flask的web界面公网访问地址4. 公网远程访问Flask的web界面 本篇文章主要讲解如何在本地安装Flask&#xff0c;以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架&#xff0c;采用Python编程语…

LeetCode初级算法书Java题解日常更新

LeetCode初级算法高效题解&#xff08;含思路注释&#xff09; 文章目录 LeetCode初级算法高效题解&#xff08;含思路注释&#xff09;前言一、数组1.删除排序数组中的重复项2.买卖股票的最佳时机 II3.旋转数组4.存在重复元素 总结 前言 决定用四个月过一下算法 一、数组 1.…

【绩效管理】帮助零售企业建立分层分类绩效考核体系项目纪实

购物中心张经理评价&#xff1a;“员工的绩效管理一直是困扰我公司的难题&#xff0c;我们只懂得怎么经营&#xff0c;至于怎么做人力资源管理&#xff0c;真是一点都不懂。这次华恒智信为我们提供的服务对我们的帮助很大。基于企业实际调研情况&#xff0c;华恒智信专家明确指…

Linux-等待子进程

参考资料&#xff1a;《Linux环境编程&#xff1a;从应用到内核》 僵尸进程 进程退出时会进行内核清理&#xff0c;基本就是释放进程所有的资源&#xff0c;这些资源包括内存资源、文件资源、信号量资源、共享内存资源&#xff0c;或者引用计数减一&#xff0c;或者彻底释放。…

PANet网络

PANet&#xff08;Path Aggregation Network&#xff09;是一种用于语义分割任务的神经网络结构&#xff0c;旨在解决多尺度特征融合的问题。该网络结构由中国科学院计算技术研究所提出&#xff0c;在2018年的论文中首次提出。 PANet的主要目标是解决语义分割任务中多尺度信息…

电脑开机启动项设置

电脑开机启动项设置 一、Windows 系统&#xff1a; 1、Windows 系统&#xff0c;可以通过【系统配置实用程序】来设置开机启动项&#xff1a; 1&#xff09;、按【WinR】组合键&#xff0c;打开【运行】对话框。 2&#xff09;、输入【msconfig】&#xff0c;点击【确定】或…

Transformer 模型及其典型应用研究

摘要&#xff1a; Transformer 模型是一种基于自注意力机制的深度学习架构&#xff0c;在自然语言处理等领域取得了巨大成功。本文介绍了 Transformer 模型的原理和结构&#xff0c;并探讨了其在语言翻译、文本生成、对话系统、语言模型、图像处理和推荐系统等典型应用领域的研…