- 博客(50)
- 收藏
- 关注
原创 面试小札:Java后端闪电五连鞭_11
MyISAM采用表级锁,当一个事务对表进行写操作时,整个表都会被锁定,其他事务不能对该表进行写操作,在并发写入较多的场景下性能较差,但在以读为主的场景下,表级锁的开销相对较小。如果删除的节点是黑色,可能会导致从根到叶子的某条路径上的黑色节点数减少,这时需要通过一些复杂的调整操作来恢复平衡,比如将其兄弟节点的颜色和结构进行调整,可能涉及变色和旋转操作,以保证红黑树的性质仍然成立。它的索引和数据是分开存储的,有三个文件,分别是 .frm (表结构定义文件)、 .MYD (数据文件)和 .MYI (索引文件)。
2024-12-24 08:40:21
691
原创 面试小札:Java后端闪电五连鞭_9
s1 == s2 的结果是 false ,因为它们是两个不同的对象,在堆内存中有不同的地址,而 s1.equals(s2) 的结果是 true ,因为 equals 方法在 String 类中被重写来比较字符串的内容。,此时 s1 和 s2 指向同一个 String 对象,通过任何一个引用修改对象的内容都会影响到另一个引用所指向的对象(对于不可变类如 String ,虽然不能直接修改对象内容,但如果是可变类就会有影响)。- 优点:具有良好的封装性,可以隐藏对象内部的细节,提高代码的安全性和可维护性;
2024-12-20 09:00:06
518
原创 面试小札:Java后端闪电五连鞭_9
例如,在一个游戏排行榜中,玩家的分数作为元素的分数,玩家ID作为元素存储在有序集合中,通过查询有序集合可以快速获取排行榜信息。例如,在查询分数在[min_score, max_score]范围内的所有元素时,可以从跳表的高层索引开始,快速定位到这个范围的起始位置,然后在底层链表中遍历这个范围内的所有元素,这种方式比线性结构在处理范围查询时效率更高。同一个消费者组中的消费者共同消费主题下的队列消息,一个队列的消息在同一时刻只会被一个消费者组中的一个消费者消费,通过这种方式实现负载均衡。
2024-12-19 19:00:12
440
原创 面试小札:Java后端闪电五连鞭_8
例如,如果一个主题有多个分区,且消息堆积在这些分区上,可以增加消费者组中的消费者数量,使其与分区数量匹配或者超过分区数量,以加快消息的消费速度。这种情况在实际应用中很有用,比如一个消费者组用于实时处理消息,另一个消费者组用于离线分析消息,它们可以共享相同的消息源(即分区),但处理方式不同。消息在队列内有序,消费者通过订阅主题下的队列来消费消息。RocketMQ支持消息的广播消费(一个消息可以被同一个消费者组中的所有消费者消费)和集群消费(类似于Kafka的消费者组模式,一个队列的消息被一个消费者消费)。
2024-12-19 08:45:04
1150
原创 Java基础夯实——2.6 Java中锁
锁用于控制多个线程对共享资源的访问。只有持有锁的线程才能访问被保护的资源,其他线程必须等待锁的释放。这种机制可以防止线程之间的竞争条件(Race Condition)。保证了同一时刻只有一个线程持有对象的锁并修改该对象,从而保障数据的安全。java中的锁包括。
2024-12-18 23:31:06
1315
原创 面试小札:闪电五连鞭_7
例如,在一个线程可能需要等待一定时间获取锁,如果超时则放弃等待,或者线程在等待锁的过程中可以被中断的情况下,ReentrantLock的这些功能就很有用。线程在获取锁时,如果锁被其他线程占用,它会进入队列等待,当锁可用时,队列中的第一个线程会获取到锁。AQS维护了一个等待队列,当线程尝试获取锁时,如果锁已经被其他线程持有,该线程会被包装成一个节点加入到等待队列中。当线程释放锁时,会通过CAS操作将state递减,当state变为0时,锁才真正被释放,并且会唤醒等待队列中的一个线程。
2024-12-18 18:19:56
748
原创 面试小札:闪电五连鞭_6
原子性操作是指不可被中断的操作,在多线程环境下,一个原子操作一旦开始,就会一直执行到结束,不会被其他线程干扰。- 可重入性:例如,一个线程在进入一个被 synchronized 修饰的方法后,如果这个方法内部又调用了另一个被 synchronized 修饰的方法(属于同一个对象),该线程可以直接进入而不需要重新获取锁。- 在数据库中使用排它锁(FOR UPDATE):在SQL中,例如在关系型数据库(如MySQL)中,当执行 SELECT...FOR UPDATE 语句时,会对查询到的数据行加排它锁。
2024-12-18 09:05:16
926
原创 面试小札:闪电五连鞭_5
当一个线程获取了排它锁后,其他线程不能再获取该锁,直到持有锁的线程释放锁。当一个线程尝试获取自旋锁而该锁已经被其他线程占用时,这个线程不会立即进入阻塞状态,而是会在一个循环中不断地检查锁是否被释放,这个过程就像线程在“自旋”。例如,线程A持有资源R1并且等待资源R2,而线程B持有资源R2并且等待资源R1,这样两个线程就会一直等待下去,无法继续执行,导致程序出现停滞状态。例如,一个线程在开始执行任务前,就把它需要的所有资源都申请好,如果无法获取全部资源,就等待,直到所有资源都可用。- 也可以用于代码块。
2024-12-18 08:47:06
451
原创 面试小札:闪电五连鞭_4
对数据库进行限流、降级等保护措施,防止数据库被压垮。它基于客户端 - 服务器模型,客户端发起调用请求,将参数进行序列化后通过网络传输到服务器端,服务器端接收到请求后进行反序列化,执行相应的函数或方法,得到结果后再将结果序列化返回给客户端,客户端接收到结果后进行反序列化得到最终的返回值。选择合适的日志框架,如 Log4j、Logback 等,这些框架提供了丰富的功能,包括不同级别的日志记录(DEBUG、INFO、WARN、ERROR 等)、日志输出到不同的目的地(控制台、文件、数据库等)以及日志格式的定制。
2024-12-17 08:59:09
465
原创 面试小札:闪电五连鞭_3
还有基于消息队列的最终一致性方案,比如在分布式事务中,一个服务操作成功后发送消息到消息队列,其他相关服务消费消息并执行相应操作,最终达到数据的一致状态,但可能存在短暂的不一致情况,需要有相应的补偿机制来处理。缺点是索引会占用额外的存储空间,并且在数据插入、更新和删除操作时,需要同时维护索引,会带来一定的性能开销,所以要合理选择建立索引的列,避免过度索引。同时,可以根据系统的并发量预估合理设置连接池的大小,并且对连接的获取和归还进行优化和监控,防止连接泄露等问题。问题 2:如何处理高并发情况下的数据库连接?
2024-12-17 08:45:14
396
原创 面试小札:闪电五连鞭_2
一个类可以实现多个接口,实现接口的类必须实现接口中的所有方法。IOC是一种设计思想,它将对象的创建和依赖关系的管理从程序代码中转移到容器(如Spring容器)中。传统的程序是由程序员自己在代码中创建对象并管理对象之间的依赖关系,而在IOC模式下,容器负责创建对象并将对象注入到需要的地方。抽象类是不能被实例化的类,它可以包含抽象方法(没有方法体的方法)和非抽象方法。算法和数据结构优化:选择合适的算法和数据结构,例如,在需要频繁查找元素的场景下,使用 HashMap 比 ArrayList 效率更高。
2024-12-10 21:12:00
437
原创 面试小札:闪电五连鞭_2
它定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存中,每个线程都有自己的工作内存(类似于CPU的高速缓存),线程对变量的操作(读取、赋值等)必须在工作内存中进行,不能直接操作主内存中的变量。这就涉及到了变量的从主内存到工作内存的加载(load)、从工作内存到主内存的存储(store)等操作,以及工作内存之间变量值的传递(read、write)等操作,这些操作规则保证了多线程环境下数据的一致性。POST :用于创建新的资源。它是幂等的,意味着多次相同的 PUT 操作对资源的修改效果是相同的。
2024-12-06 08:35:30
930
原创 面试小札:神奇四侠
例如, ShapeProxy 类也实现了 Shape 接口,它内部持有一个 Shape 类型的对象(可以是 Circle 等具体形状),在 draw 方法中,它可以先记录日志,然后调用真实形状对象的 draw 方法。例如,一个Web应用程序可能会缓存一些经常访问的数据库查询结果,这些查询结果以对象的形式存在,通过序列化和缓存,可以减少数据库的访问次数,提高应用程序的响应速度。例如,在一个大型的企业级应用中,有很多服务接口需要代理,使用动态代理可以在一个地方统一管理代理逻辑,而不是为每个接口编写一个代理类。
2024-12-05 21:41:32
920
原创 面试小札:Java后端_闪电五连鞭_1
常见实现类: HashMap (基于哈希表实现,允许键或值为 null )、 TreeMap (基于红黑树实现,键有序)、 HashTable (线程安全,不允许键或值为 null )。常见实现类: ArrayList (基于数组实现,随机访问快,插入和删除慢)、 LinkedList (基于链表实现,插入和删除快,随机访问慢)。复制算法:将内存分为两块,每次只使用其中一块。方法重写发生在子类继承父类时,子类可以重新定义父类中的方法,当通过父类引用调用被重写的方法时,实际执行的是子类中的实现。
2024-12-04 12:47:34
742
原创 面试小札:线程池
任务提交:当有新的任务提交到线程池时,如果线程池中的线程数小于核心线程数,会创建新的线程来执行任务。线程池创建:首先创建一个线程池,指定一些参数,如核心线程数、最大线程数、线程空闲时间等。线程复用:如果线程数已经达到核心线程数,新的任务会被放入任务队列等待线程空闲时执行。线程回收:当线程空闲时间超过指定的时间,且线程数大于核心线程数,多余的线程会被回收。线程扩充:当任务队列已满,且线程数小于最大线程数,会创建新的线程来执行任务。回收线程:当线程空闲时间超过设定值且线程数大于核心线程数,回收多余线程。
2024-12-04 10:19:59
629
原创 面试小札:Java如何实现并发编程
当一个线程访问被 synchronized 修饰的方法或者代码块时,其他线程需要等待该线程释放锁才能访问。线程池会自动管理线程的复用,提高线程的使用效率,减少线程创建和销毁的开销。通过创建该类的实例,然后调用 start 方法来启动线程,如 new MyThread().start();在 run 方法中编写线程要执行的任务逻辑。它可以实现公平锁和非公平锁,还可以通过 tryLock 方法尝试获取锁而不阻塞线程,提供了更多的控制功能。System.out.println("线程池中的线程执行任务");
2024-11-30 08:31:22
573
原创 面试小札:ThreadLocal底层实现原理和具体应用场景
这有助于防止 ThreadLocal 对象的内存泄漏,但如果在使用过程中不小心,仍然可能出现 value 无法被回收的情况(例如 ThreadLocal 对象被回收了,但 value 还在 ThreadLocalMap 中,并且 Thread 生命周期很长)。例如在一个Web应用服务器中,对于每个用户请求,服务器可能会使用多个线程来处理不同的任务,如数据库查询、业务逻辑计算等。这样,在整个请求处理过程中的各个方法(可能分布在不同的类中)都可以方便地获取当前用户的信息,而不用担心多用户并发访问时信息的混乱。
2024-11-30 08:22:05
458
原创 面试小札:什么情况下会频繁full GC
例如,在一个高并发的Web应用中,大量的用户请求导致大量的临时对象产生,这些对象的生命周期管理不当就容易引发频繁Full GC。像在一些使用缓存的场景中,如果缓存没有设置合理的过期策略或者大小限制,缓存中的对象会一直占用内存,随着对象的不断积累,老年代内存空间会逐渐被填满,从而频繁触发Full GC。如果有大量大对象(如大数组、大字符串等)被创建,并且这些大对象直接进入老年代(例如,通过参数设置 - XX:PretenureSizeThreshold,当对象大小超过这个阈值时,直接在老年代分配内存)。
2024-11-29 08:35:34
283
原创 面试小札:什么是JavaGC
它将堆内存划分为多个大小相等的Region,在回收时可以根据各个Region中垃圾对象的多少优先回收垃圾最多的Region。标记过程和标记 - 清除算法类似,但后续不是简单地清除垃圾对象,而是将存活的对象向一端移动,然后清理掉边界以外的内存,既避免了内存碎片,又不需要像复制算法那样浪费一半的内存空间。它是单线程的垃圾回收器,在进行垃圾回收时,会暂停所有用户线程,直到垃圾回收完成。在一些垃圾回收算法中,如标记 - 整理算法,会在清除垃圾对象后,将存活的对象向内存一端移动,从而减少内存碎片,方便后续内存分配。
2024-11-29 08:28:11
697
原创 什么是分布式锁
同时,为了防止节点获取锁后由于某些原因(如进程崩溃)没有释放锁,还会设置一个过期时间,确保锁最终能够被释放。如果是,则表示获取锁成功,可以访问共享资源;如果不是,它会监听比自己序号小的节点的删除事件,当比自己序号小的节点被删除(即持有锁的节点释放锁)时,它会再次检查自己是否是序号最小的节点,以此来获取锁。例如,在MySQL中,当一个事务对某行数据执行“select...for update”语句时,会对该行数据加排他锁,其他事务如果也想对该行数据进行修改操作,就会被阻塞,直到持有锁的事务提交或回滚。
2024-11-28 22:47:32
408
原创 面试小札:JVM虚拟机
JIT编译器会在程序运行过程中,将热点代码(经常被执行的代码)编译成机器码,这样后续执行这些代码时就可以直接以机器码的速度运行,大大提高了执行效率。- 是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。它是线程私有的,生命周期与线程相同。- 与Java虚拟机栈类似,不过它是为本地(Native)方法服务的,本地方法是用其他语言(如C、C++)编写并通过JNI(Java Native Interface)调用的方法。- 是Java虚拟机所管理的内存中最大的一块,它是所有线程共享的区域。
2024-11-28 08:59:40
925
原创 面试小札:Java的类加载过程和类加载机制。
例如,从加密的字节码文件中加载类,或者从非标准的位置(如数据库)加载类。例如,用户自定义了一个 java.lang.String 类,由于双亲委派模型,这个类不会被加载,因为启动类加载器会首先加载Java核心库中的 java.lang.String 类,这样就防止了用户恶意篡改核心类库的行为。元数据验证:对字节码描述的信息进行语义分析,以保证其符合Java语言规范,例如检查这个类是否有父类(除了 java.lang.Object ),是否继承了不允许继承的类(如 final 类)等。
2024-11-22 20:21:20
573
原创 面试小札:Java反射原理和具体应用
代理类实现了相同的接口,在调用方法时,通过反射调用被代理对象的方法,并且可以在前后添加额外的逻辑。例如,当配置文件中指定 service 层的类依赖于 dao 层的类时,Spring会使用反射创建 dao 类的实例,并将其注入到 service 类的实例中。可以实现插件式的架构。一句话:Java反射原理通过获取类的Class对象来访问和操作类的成员(如字段、方法、构造函数),它的应用包括框架开发中依赖注入和Servlet调用、动态代理实现AOP、单元测试访问私有成员以及开发插件系统加载插件类。
2024-11-22 08:42:58
699
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人