当前位置: 首页 > news >正文

常见网站模式敏捷模型是软件开发模型吗

常见网站模式,敏捷模型是软件开发模型吗,汕头seo网站排名,营销型网站建设推荐乐云seo文章目录 目录 文章目录 提问问题 问题1 问题2 问题3 问题4 问题5 问题6 问题7 问题8 问题9 问题10 问题11 问题12 问题13 问题14 问题15 问题16 问题17 问题18 问题19 写在最后 提问问题 项⽬的⽤户数据怎么存储的#xff0c;存储在哪⾥#xff0c;⽤的什…文章目录 目录 文章目录 提问问题 问题1  问题2  问题3  问题4  问题5  问题6  问题7  问题8  问题9  问题10  问题11  问题12  问题13  问题14  问题15 问题16  问题17  问题18  问题19  写在最后 提问问题 项⽬的⽤户数据怎么存储的存储在哪⾥⽤的什么数据结构索引的设计思想四种引⽤强引⽤、软引⽤、弱引⽤、虚引⽤分别介绍String、Stringbuilder、Stringbuffer的区别String s abc和String s new String(abd)⼀样吗序列化时某些字段不想被序列化怎么做⽤什么注解线程⽣命周期创建线程的⽅式常⽤的线程池有哪些使用场景分别是Sleep和Wait的区别Java中加锁的⽅式有哪些可重⼊锁是什么意思谁是可重⼊锁介绍JVM内存结构哪些是线程私有的哪些会发⽣OOMJava类加载过程介绍双亲委派机制是什么?tomcat中的是这样的吗如何判断垃圾是否该被回收?介绍常⽤的垃圾回收算法什么时候触发完全回收full GCSpring启动过程、分哪些步骤Spring Autowired和Resource有什么区别Spring bean作⽤域介绍AOP简单介绍AOP的⼏个主要核⼼概念是什么AOP中⼀些常⽤的注解的作⽤Redis缓存雪崩和缓存穿透介绍如何解决这些问题 问题1 用户数据存储常见 关系型数据库RDBMS 如MySQL、PostgreSQL、Oracle等使用表格来组织数据。每个表由多行记录和多列字段组成。数据结构通常使用B树或其变种B树作为索引结构以优化查询性能。索引设计主要目的是加快数据检索速度减少磁盘I/O操作。设计索引时会考虑查询频率高的列、唯一性、组合索引等因素。 非关系型数据库NoSQL 如MongoDB、Cassandra、Redis等根据不同的使用场景提供灵活的数据模型。数据结构 文档型数据库如MongoDB使用JSON或BSON格式存储文档索引可建立在文档内的字段上。键值存储如Redis使用键值对来存储数据索引即为键。列族存储如Cassandra将数据分组存储索引可建立在列族的列上。索引设计根据数据的访问模式和查询需求来设计索引。例如MongoDB中可以为文档中的某个字段创建索引以加速查询。 在设计用户数据存储时需要考虑数据的一致性、完整性、安全性以及备份恢复等因素。 索引的设计思想 主要是为了提高数据检索效率减少不必要的数据扫描和排序操作从而提升应用的性能。但也要注意过度索引可能会导致维护成本增加和写操作性能下降。 问题2 在Java中引用类型决定了垃圾收集器如何处理对象。每种引用类型都有其特定的用途选择合适的引用类型可以帮助开发者更好地管理内存避免内存泄漏并实现特定的功能需求。 以下是四种不同类型的引用及其特点 强引用Strong Reference 强引用是最常见的引用类型。只要强引用还存在对象就不会被垃圾收集器回收。 对象的生命周期完全依赖于强引用只要至少存在一个强引用指向该对象它就不会被垃圾回收。 Object obj new Object(); //这里的obj就是一个强引用。 软引用Soft Reference 软引用允许其所引用的对象被垃圾收集器回收以回收内存。 当JVM内存不足时软引用指向的对象会被回收。 软引用经常用在实现内存敏感的缓存中比如LRU缓存。 SoftReferenceObject softRef new SoftReference(new Object()); 弱引用Weak Reference 弱引用比软引用更弱无论当前内存是否足够只要进行垃圾回收弱引用指向的对象就一定会被回收。 弱引用主要用于实现不影响对象存活期的引用情况。 弱引用常用于实现对象的身份识别比如在HashMap中用作键时避免内存泄漏。 WeakReferenceObject weakRef new WeakReference(new Object()); 虚引用Phantom Reference 虚引用是最弱的引用类型。一个对象引用被设置为虚引用后它仍然可以被垃圾回收。 虚引用必须和引用队列ReferenceQueue一起使用。当垃圾收集器决定回收对象时如果对象上有虚引用垃圾收集器会在回收对象前将这个虚引用加入到与之关联的引用队列中。 虚引用主要用于跟踪对象被垃圾回收的活动通常很少使用。 ReferenceQueueObject refQueue new ReferenceQueue(); PhantomReferenceObject phantomRef new PhantomReference(new Object(), refQueue); 问题3 String、StringBuilder和StringBuffer都是Java中用于处理字符串的类但它们在性能和用途上有所不同 String String类的内容是不可变的。 当创建一个新的String对象时如果该对象的内容已经存在于堆内存中则不会创建新的对象而是引用已有的对象。 因为String对象不可变所以每次对String进行修改实际上都会生成一个新的String对象这会导致额外的内存分配和垃圾回收影响性能。 StringBuilder StringBuilder类的内容是可变的。 StringBuilder内部使用字符数组来存储字符串可以在不产生新对象的情况下直接修改字符串内容。 StringBuilder是非线程安全的适用于单线程环境下的字符串操作。 StringBuffer StringBuffer类的内容也是可变的与StringBuilder类似。 StringBuffer内部同样使用字符数组来存储字符串。 StringBuffer是线程安全的它的方法都是同步的可以在多线程环境下安全使用但因此在性能上略低于StringBuilder。 关于两个声明方式 String s abc; String s new String(abc);第一行代码中的s是对字面量abc的引用。如果堆内存中已存在相同内容的String对象则不会创建新对象而是引用已有的对象。 第二行代码中的s是通过new关键字创建了一个新的String对象即便堆内存中已存在相同内容的对象也会创建一个新的对象。第二种方式总是会在堆内存中创建一个新的String对象。 问题4 可以使用Transient注解标记该字段。带有Transient注解的字段会被忽略从而不会被序列化到输出的流中。 import java.io.Serializable;public class Example implements Serializable {private static final long serialVersionUID 1L;private String fieldToSerialize;Transientprivate String fieldNotToSerialize; } 在上述代码中fieldToSerialize会被序列化而fieldNotToSerialize由于被Transient注解标记将不会被序列化。 问题5 线程的生命周期通常包括以下几个状态 新建New 线程对象被创建后尚未开始执行。此时线程已经存在但还未调用start()方法。 就绪Runnable 调用了线程的start()方法后线程进入就绪状态准备执行。此时线程已经分配了CPU时间但还未实际运行。如果有其他线程正在使用CPU那么这个线程将等待CPU时间片在操作系统的调度下获得执行。 运行Running 线程获得CPU时间并开始执行run()方法中的代码。此时线程处于活跃状态执行着程序计数器指向的指令。 阻塞Blocked 当线程因为某些原因放弃CPU使用权时会进入阻塞状态。阻塞的原因可能有三种 等待阻塞执行wait()方法线程等待其他线程执行notify()或notifyAll()。同步阻塞线程在获取synchronized锁失败时会进入同步阻塞状态。其他阻塞线程执行sleep()或join()方法或者发送了请求打断信号而暂停执行。 等待Waiting 一个处于阻塞状态的线程只有在收到通知或中断信号或者其等待的超时时间到达时才会返回到可运行状态。 超时等待Timed Waiting 与等待状态类似但线程是在指定的时间内等待。例如通过Thread.sleep(long millis)或Object.wait(long timeout)方法。超时时间到达后线程会返回可运行状态。 终止Terminated 线程的run()方法执行完毕或者因异常退出了run()方法线程结束生命周期。 线程一旦终止就不能再次启动。如果需要再次执行必须创建一个新的线程对象。 问题6 在Java中创建线程主要有以下几种方式 1.继承Thread类 通过创建一个继承自Thread类的子类并重写其run()方法来实现线程的功能。然后通过该类的实例调用start()方法启动线程。 class MyThread extends Thread {public void run() {// 线程要执行的任务} }MyThread t new MyThread(); t.start();2.实现Runnable接口 创建一个实现了Runnable接口的类并重写其run()方法。然后创建该类的实例并将该实例作为参数传递给Thread类的构造函数创建Thread对象最后通过start()方法启动线程。 class MyRunnable implements Runnable {public void run() {// 线程要执行的任务} }Thread t new Thread(new MyRunnable()); t.start();3.实现Callable接口 类似于实现Runnable接口但是Callable接口允许线程返回结果并且可以抛出异常。实现Callable接口后使用FutureTask类包装Callable对象并传入ExecutorService来执行。 class MyCallable implements CallableInteger {public Integer call() throws Exception {// 线程要执行的任务返回结果return 123;} }ExecutorService executor Executors.newSingleThreadExecutor(); FutureInteger future executor.submit(new MyCallable()); executor.shutdown(); // 获取线程执行结果 try {Integer result future.get(); } catch (InterruptedException | ExecutionException e) {e.printStackTrace(); }4.使用线程池 通过ExecutorService接口的实现类比如Executors工厂类提供的线程池方法来创建线程。线程池可以有效管理线程资源避免创建过多线程导致的资源浪费。 ExecutorService executor Executors.newFixedThreadPool(10); executor.execute(new Runnable() {public void run() {// 线程要执行的任务} }); executor.shutdown();5.使用Lambda表达式 在Java 8及以上版本中可以利用Lambda表达式简化实现Runnable接口的代码特别是当Runnable接口的实现非常简单时。 Thread t new Thread(() - {// 线程要执行的任务 }); t.start();通常情况下推荐使用实现Runnable接口或Callable接口的方式因为这样可以避免单继承的限制并且可以使线程的逻辑与线程的创建和管理分离提高代码的可读性和可维护性。 问题7 在Java中常用的线程池主要包括以下几种它们分别适用于不同的使用场景 FixedThreadPool固定大小线程池 使用Executors.newFixedThreadPool(int nThreads)创建。特点线程数固定不会随着任务的增减而改变。适用场景适合任务量相对稳定且数量不多的场景可以避免频繁创建销毁线程带来的性能损耗。 CachedThreadPool缓存线程池 使用Executors.newCachedThreadPool()创建。特点线程数不固定空闲线程最多存活60秒后会被自动终止任务量大时会创建新线程任务量减少时会回收线程。适用场景适合任务量波动较大且CPU资源充足的场景可以根据实际负载动态调整线程数量。 SingleThreadExecutor单线程池 使用Executors.newSingleThreadExecutor()创建。特点只有一个工作线程保证任务按顺序执行不会并发执行。适用场景适合需要串行执行任务的场景如读写文件操作等可以保证线程安全。 ScheduledThreadPool定时线程池 使用Executors.newScheduledThreadPool(int corePoolSize)创建。特点除了具有普通线程池的特性外还支持定时和周期性任务的执行。适用场景适合需要定期执行任务的场景如定时清理缓存、定时检查更新等。 WorkStealingPool工作窃取线程池 使用Executors.newWorkStealingPool()创建。特点采用工作窃取算法适用于大量计算任务能够平衡负载提高CPU利用率。适用场景适合CPU密集型任务的场景可以充分利用多核处理器的优势。 问题8 sleep() 和 wait() 都是Java中用于线程控制的方法但它们有以下主要区别 所属类不同  sleep() 是 Thread 类的静态方法可以直接通过 Thread.sleep(millis) 调用。 wait() 是 Object 类的实例方法必须在同步方法或同步块中调用以确保对共享资源的访问是线程安全的。  锁的处理不同 sleep() 不会释放当前对象的锁即使线程在 sleep() 方法期间其他线程仍然无法调用该对象的同步方法或同步块。 wait() 会释放当前对象的锁使得其他线程可以进入同步方法或同步块获取该对象的锁并执行。 唤醒机制不同 sleep() 会在指定的时间后自动唤醒线程。 wait() 需要其他线程显式地调用同一对象上的 notify() 或 notifyAll() 方法来唤醒等待的线程。 使用目的不同 sleep() 通常用于短暂地暂停执行例如在轮询循环中暂停一段时间或者模拟延迟。 wait() 通常用于线程之间的协作当一个线程需要等待某个条件成立时它会调用 wait() 方法进入等待状态直到另一个线程改变条件并调用 notify() 或 notifyAll() 方法。 异常处理不同 sleep() 抛出的是 InterruptedException表示在等待过程中线程被中断。 wait() 同样抛出 InterruptedException表示在等待过程中线程被中断并且还可能抛出 IllegalMonitorStateException表示线程没有获得对象的锁就调用了 wait() 方法。 问题9 Java中的加锁方式主要有以下几种 synchronized关键字 同步方法在方法声明前添加synchronized关键字锁定当前对象。同步块在代码块前添加synchronized关键字锁定当前对象。 ReentrantLock类 提供比synchronized更灵活的锁机制如尝试非阻塞地获取锁、可中断地等待锁、公平锁等。 ReadWriteLock接口 由ReentrantReadWriteLock类实现提供读锁共享锁和写锁独占锁。允许多个线程同时持有读锁但写锁是互斥的。 StampedLock类Java 8引入 提供了三种锁模式读锁、写锁和乐观读锁。支持尝试非阻塞地获取锁并提供了锁的超时版本。 Condition接口 与ReentrantLock配合使用提供了更加灵活的线程间通信机制。 可重入锁Reentrant Lock 是指同一个线程可以多次获取同一把锁每次获取锁后都会增加锁的持有计数直到锁被释放次数与获取次数相等锁才真正被释放。 Java中的ReentrantLock和synchronized关键字都是可重入锁。 问题10 Java虚拟机JVM的内存结构可以分为几个主要区域 方法区 (Method Area) 存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。在HotSpot VM中方法区又称为永久代PermGen但是在Java 8及以后版本中已经被元空间Metaspace取代。 堆 (Heap) 所有线程共享的一块内存区域用于存储所有创建的对象实例。是垃圾收集器管理的主要区域也是最常发生内存溢出OutOfMemoryError的地方。 虚拟机栈 (Java Virtual Machine Stack) 线程私有的内存区域每个方法执行时都会创建一个栈帧Stack Frame用于存储局部变量表、操作数栈、动态链接、方法出口等信息。如果线程请求的栈深度大于虚拟机所允许的最大深度将抛出StackOverflowError。 本地方法栈 (Native Method Stack) 线程私有的内存区域为虚拟机使用到的Native方法服务。类似于虚拟机栈每个线程也会创建一个本地方法栈其生命周期与线程相同当线程请求的栈深度大于虚拟机所允许的最大深度时将抛出StackOverflowError。 程序计数器 (Program Counter Register) 线程私有的内存区域保存了当前线程所执行的字节码的行号指示器。线程切换时程序计数器也会随之切换但不会发生OutOfMemoryError。 在JVM中可能发生OOM的区域主要有堆和方法区元空间。 堆内存溢出通常是因为申请的对象超出了堆的最大容量而方法区元空间内存溢出则可能是由于类和方法的数量过多导致的。 对于虚拟机栈和本地方法栈通常情况下它们的大小是由虚拟机启动参数决定的如果分配给这些区域的内存过小可能会导致StackOverflowError但并不是OOM。 问题11 Java类加载是一个复杂的过程主要分为以下几个步骤 加载(Loading) 通过类的全限定名获取类的字节流这个字节流可以来自多种不同的数据源比如本地的.class文件、JAR文件、网络资源等。将字节流所代表的静态存储结构转换为方法区的运行时数据结构。在内存中生成一个代表这个类的java.lang.Class对象作为方法区这个类各种数据的访问入口。 连接(Linking) 验证确保Class文件的字节流中包含的信息符合虚拟机规范没有安全方面的问题。准备为类的静态变量分配内存并设置类变量的默认初始值。解析将常量池内的符号引用转换为直接引用。 初始化(Initialization) 执行类构造器clinit()方法的过程该方法不需要显式编写由编译器自动收集类中所有类变量的赋值动作和静态语句块中的语句合并产生。在多线程环境下类的初始化是线程安全的Java虚拟机会保证一个类被完全加载和初始化之后才允许其他线程去初始化这个类。 类加载过程中JVM采用双亲委派模型进行类的加载这意味着当一个类加载器收到类加载的请求时它首先会委托给父类加载器去尝试加载这个类如果父类加载器无法加载子类加载器才会自己尝试加载。这个机制保证了Java的核心类库只会被加载一次并且提高了安全性。 问题12 双亲委派机制 当一个类加载器被请求加载一个类时它首先不会自己去尝试加载这个类而是将这个请求委托给其父类加载器去完成。如果父类加载器不能加载该类子加载器才会尝试自己去加载。 这种机制的好处在于它保证了Java类库的唯一性确保了标准类库只会被加载一次避免了类的冲突。此外它还提供了安全性因为父加载器通常加载更为信任的类如Java核心API类。只有在父加载器无法找到或者加载该类时才会让子加载器去尝试加载。 在Tomcat中类加载机制与标准的Java类加载器一样Tomcat对双亲委派模型进行了一些扩展和调整仍然遵循了双亲委派模型的基本原则。Tomcat使用了一种叫做“分层类加载”的机制它将类加载器分为几个层次 Bootstrap ClassLoader负责加载Java核心库如rt.jar等。Common ClassLoader负责加载Tomcat的核心库如servlet API等。Catalina ClassLoader负责加载Tomcat容器的核心组件。Shared ClassLoader负责加载Web应用共享的库。Webapp ClassLoader针对每个Web应用单独存在负责加载该Web应用的类库。 问题13 在Java虚拟机JVM中判断垃圾是否应该被回收通常依赖于可达性分析算法Reachability Analysis即从根集合Root Set开始沿着应用程序中的引用链向上搜索直到遇到不可达的对象。 根集合通常包括以下几种类型的对象 活跃线程中的局部变量表。活跃线程的输入参数。活动方法的返回值。类静态变量。 如果一个对象不再被任何根集合中的对象所引用那么这个对象就被认为是垃圾可以被回收。 常用的垃圾回收算法包括 标记-清除Mark-Sweep 首先标记所有活动对象。清除所有未标记的对象。缺点是容易产生内存碎片。 复制Copying 将内存分为两个相等的区域每次只使用其中一个。标记活动对象并将它们复制到另一个区域。清理未使用的区域。优点是实现简单不容易产生内存碎片但牺牲了一半的内存作为临时空间。 标记-整理Mark-Compact 标记活动对象。移动所有活动对象到内存的一端从而整理出连续的空闲内存空间。优点是减少了内存碎片但实现比复制算法复杂。 分代收集Generational Collection 根据对象存活的周期将内存分为几代如新生代Young Generation、老年代Old Generation和永久代PermGen已在Java 8中被元空间Metaspace取代。大多数新创建的对象都在新生代中存活时间短暂。老年代中的对象存活时间较长。分代收集算法主要在新生代中使用复制算法在老年代中使用标记-清除或标记-整理算法。 增量/并行/并发收集Incremental/Parallel/Concurrent Collection 为了减少垃圾回收时的停顿时间这些算法尝试在后台并发地进行垃圾回收工作。增量回收将垃圾回收任务分成多个小的部分逐步执行。并行回收使用多个垃圾回收线程来同时处理垃圾回收任务。并发回收则允许应用程序和垃圾回收器并发运行减少了因垃圾回收而导致的停顿时间。 问题14 在Java虚拟机JVM中完全回收Full GC通常在以下情况下触发 老年代空间不足当老年代Tenured Generation的空间不足时无法再为新对象分配空间这时会触发Full GC来清理老年代以及整个堆内存并尝试回收更多的空间。 方法区Metaspace在Java 8之前为Permanent Generation空间不足如果JVM中的方法区用于存储类元数据、常量、静态变量等满了也会触发Full GC。在Java 8及以后版本中如果Metaspace区域满了同样会触发Full GC。 系统请求通过调用System.gc()方法可以向JVM建议执行垃圾回收但这并不保证Full GC一定会被触发这只是一个提示实际执行取决于JVM的实现。 配置的GC策略某些垃圾收集器比如CMS收集器可能在特定的回收阶段结束后为了整理内存碎片或进行老年代回收而触发Full GC。 并发模式下的Full GC在并发垃圾收集器如CMS或G1中可能在并发阶段未能及时回收足够的内存或者并发回收阶段完成后仍需执行一次完整的回收来清理剩余的垃圾这时也会触发Full GC。 异常情况例如内存泄露导致内存不断增加最终耗尽也会触发Full GC。 值得注意的是频繁的Full GC通常是一个不好的信号可能意味着存在内存泄漏或者JVM的垃圾收集器配置不当。理想情况下Full GC应该尽量少发生以避免对应用程序性能造成显著影响。 问题15 Spring框架的启动过程可以分为以下几个步骤 加载Spring应用上下文Spring应用的启动是从加载Spring应用上下文开始的。应用上下文负责初始化和管理Spring容器中的所有bean。 注册Spring容器根据配置信息XML配置、注解配置或基于Java的配置容器会注册所有的bean定义。这包括类的扫描、bean的创建和配置等。 实例化BeanSpring容器根据定义的bean定义信息实例化所有的bean。 装配BeanSpring容器将通过依赖注入DI机制将bean之间的依赖关系装配起来。这可能涉及属性设置、构造器调用等。 初始化Bean在所有的属性都被注入之后Spring容器会调用bean的初始化方法比如InitializingBean接口的afterPropertiesSet()方法或者自定义的初始化方法。 注册Bean后处理器Spring允许用户注册Bean后处理器这些处理器会在bean初始化之后、容器完成初始化之前被调用用于进一步处理bean。 启动监听器Spring容器提供了启动监听器机制允许用户在容器启动时和关闭时执行特定的操作。 准备环境Spring Boot等现代Spring框架会进一步提供环境准备功能如设置数据源、配置属性源、加载外部配置等。 应用准备就绪完成上述所有步骤后Spring应用就准备好了可以对外提供服务。 对于Spring Boot应用来说 启动过程还包括了自动配置的加载和引导如执行SpringApplicationRunListener的事件回调以及可能的应用准备和应用就绪事件的触发。 问题16 Autowired和Resource是Spring框架中两个不同的依赖注入注解它们用于自动装配bean之间的依赖关系但是它们之间有一些关键的区别 来源 Autowired是Spring自己的注解用于自动装配bean。Resource是Java标准的注解属于JSR-250也可以用于自动装配bean但它不仅仅限于Spring。 注入方式 Autowired默认按类型进行自动装配如果有多个相同类型的bean存在可以通过Qualifier指定具体的bean名称。Resource默认按名称进行自动装配如果没有指定名称它会按类型来查找bean。如果需要按类型装配可以使用Resource(type YourClass.class)。 注解作用域 Autowired可以作用于字段、构造函数、setter方法等。Resource主要用于字段和setter方法。 必须性 Autowired注解的使用是可选的如果没有找到匹配的bean会抛出异常。Resource注解的使用是必需的如果没有找到匹配的bean它不会抛出异常而是会将null注入到字段中。 处理未找到bean的方式 Autowired默认情况下如果找不到对应类型的bean会抛出异常NoSuchBeanDefinitionException。Resource默认情况下如果找不到对应名称的bean会注入null值除非设置autowireMode为Resource.AUTWIRE_REQUIRED类似于Autowired的行为。 问题17 在Spring框架中bean的作用域定义了bean的生命周期以及它们在应用程序中的可见性。 Spring提供了多种不同的作用域每种作用域都适用于不同的场景。以下是Spring中常见的六种bean作用域 singleton默认作用域。Spring容器中只创建一个共享的bean实例无论你请求多少次都会得到同一个实例。 prototype每次请求时都会创建一个新的bean实例。也就是说每次调用getBean()方法时都会获得一个全新的对象。 request每个HTTP请求都会有一个与之关联的bean实例。这个bean只在当前的HTTP请求内有效请求结束后bean会被销毁。 session在一个HTTP Session中bean的生命周期和Session的生命周期一致。这意味着在同一个Session中无论请求多少次都会得到相同的bean实例。 application在一个ServletContext范围内只创建一个bean实例。这个作用域适用于那些需要在整个web应用中共享的资源。 websocket在单个WebSocket会话中只创建一个bean实例。这个作用域适用于需要在单个WebSocket会话中共享的资源。 问题18 AOP面向切面编程是一种编程范式旨在通过将横切关注点cross-cutting concerns从业务逻辑中分离出来来提高模块化。横切关注点是那些影响多个类和模块的功能例如日志记录、安全性、事务管理等。在AOP中这些横切关注点被封装成独立的模块称为“切面”Aspect。 AOP的几个主要核心概念包括 切点Pointcut定义了哪些连接点Join Point需要被切面关注即哪些方法需要被拦截。 通知Advice也称为增强Advising它定义了在切点匹配的连接点上执行的操作。常见的通知类型包括前置通知Before、后置通知After、返回通知AfterReturning、异常通知AfterThrowing和环绕通知Around。 目标对象Target Object被一个或多个切面所通知的对象。 切面Aspect包含通知和切点的模块。它将横切关注点封装起来对业务逻辑的影响最小化。 织入Weaving是将切面连接到其他应用类型或对象上并创建一个被通知的目标对象的过程。织入可以在编译时、加载时或运行时完成。 在Spring AOP中常用的注解包括 Aspect标记一个类作为一个切面。 Pointcut定义一个切点表达式。 Before定义前置通知在目标方法执行前运行。 After定义后置通知在目标方法执行后运行。 AfterReturning定义返回通知在目标方法正常执行后返回结果时运行。 AfterThrowing定义异常通知在目标方法抛出异常时运行。 Around定义环绕通知它包围了目标方法的执行可以在方法执行前后做额外的处理。 EnableAspectJAutoProxy开启基于注解的自动代理通常在配置类上使用。 问题19 Redis缓存雪崩和缓存穿透是两种常见的缓存失效问题它们会导致大量的请求直接落到数据库上可能引起数据库压力过大甚至宕机。 缓存雪崩 缓存雪崩是指在某一个时间段内缓存集中过期导致大量的并发请求直接访问数据库。这通常发生在以下几种情况 缓存中的多个键在同一时间过期系统负载突然增大导致缓存的命中率下降缓存服务器宕机所有的缓存数据丢失。 缓存穿透 缓存穿透是指查询的数据在缓存中不存在同时在数据库中也不存在例如查询的是一个不存在的ID导致每次请求都需要访问数据库从而绕过缓存层给数据库带来压力。 解决方案 缓存雪崩 随机过期时间不要将所有的缓存键设置为同一时间过期可以设置一个随机的过期时间避免大量缓存同时失效。热点数据永不过期对于热点数据可以设置永不过期或者设置更长的过期时间。设置热点数据的备份对于非常重要的热点数据可以设置多份拷贝即使一部分缓存失效也不会影响数据的访问。使用互斥锁或分布式锁在缓存失效后通过锁机制控制并发量避免大量并发请求同时查询数据库。 缓存穿透 布隆过滤器Bloom Filter在写入缓存之前先使用布隆过滤器判断数据是否存在如果不存在则不写入缓存直接返回减少对数据库的访问。布隆过滤器虽然有一定的误报率但可以极大地减少无效请求。缓存空对象当查询的数据不存在时将一个空对象缓存起来设置一个较短的过期时间这样后续相同的查询请求就可以直接从缓存中获取空对象避免访问数据库。缓存NoSQL使用一些支持范围查询的NoSQL数据库作为缓存例如Cassandra、Redis的有序集合Sorted Set等可以有效地解决部分缓存穿透问题。背景刷新对于可能存在缓存穿透风险的数据可以通过后台任务定期刷新缓存而不是等待用户请求时才去查询数据库。 写在最后 PS以上是网络上收集的一些常见的问题以及自己对答案搜索整理一次整理大概在10-25个问题之间适合对自己的知识的查缺补漏 面试一般根据岗位要求或者简历上写的来进行扩展提问也有些是直接问公司常用到的相关方面的技术问题无论怎么准备都祝大家能拿到心怡的offer
http://www.pierceye.com/news/58991/

相关文章:

  • 做照明出口的网站淘宝关键词搜索量排名
  • 做公司网站详细步骤乐山的网站建设公司
  • 做购物网站智慧团建官网登陆入口
  • 企业宣传网站制作北京中邦亚通网站
  • 网站解析ip地址传奇设计师身亡
  • 网站开发语言在那看出来叮当设计app官方下载
  • 我是建造网站企业邮箱注册申请免费流程
  • 网站改域名审核时间3d模拟设计房子软件
  • 网络网站制作技巧庆阳网站设计费用
  • 网站后台管理系统论文网站开发人员招聘it管理
  • 电子政务与网站建设工作总结网站建设方案书阿里云模板
  • 建设银行对公打不开网站合肥百度竞价推广代理公司
  • 做网站付多少定金广东省网页制作
  • 网站推广优化流程建筑网片价格
  • 免费营销管理系统crm宁波seo教程推广平台
  • zero的大型网站seo教程wordpress 大气主题
  • 福州模板建站代理浦东新区网站建设
  • 网站建设项目总结报告网站的策划做推广
  • 成都建网站要多少钱wordpress 微信服务号
  • 做网站动态效果心得wordpress new2主题使用
  • wordpress建站 外贸佛山网站建站推广
  • 淘宝网站建设多少钱seo网站关键词优化报价
  • 一个备案可以做几个网站电商网站怎么做搜索
  • 视频制作网站素材免费网站收录入口
  • 石家庄网站制作长沙怎样给网站做百度推广
  • 上海快速建站公众号注册入口官网
  • 本网站只做信息展示wordpress 点不到子菜单
  • 网站权重排名wordpress程序员
  • 没有网站可以做域名解析吗扬州建设银行网站
  • 企业网站的设计与实现摄影作品投稿网站