0%

一、ThreadLocal解决了什么问题

在一些情况下,我们希望对于某一个共享变量,对于不同线程来说都是独一无二的,例如:有一个共享变量x,线程A去对其进行写操作,读操作,线程B也对其进行写操作读操作,而线程A和线程B在去读写x时的感觉,就像是读写一个本地变量一样,完全与外界封闭, 这就是线程封闭的想法。下面有三种线程封闭的实践:

  • Ad-hoc 线程封闭:

    • 即维护线程封闭性职责交给程序实现,很不推荐使用。
  • 栈封闭:

    • 利用线程的局部变量只有自己可见这一特性,每次都手动将共享变量拷贝一份局部变量的副本。缺点是,只有编写程序的人才知道哪些对象需要封闭,并且还要考虑栈溢出的问题。
阅读全文 »

一、索引

1. 为什么使用索引

提高查询效率,避免全表扫描;

2. 如何定位并优化慢sql

先说步骤:

  • 第一步:根据慢日志定位慢查询sql

    • 根据慢查询日志确定慢sql:

      • 使用show variables like '%quer%';可以看到一些变量(可以使用set global xx=..;, 也可以在my.cnf配置文件里修改,是mysql server的启动配置),其中:
        1. slow_query_log 表示满查询日志是否开启;
        2. long_query_time 超过了这个时间的将被视为慢查询(一般超过1秒就被视为慢查询, 修改完需要重新获取connection)
        3. slow_query_log_file: 慢查询日志保存位置
      • 系统状态:
        • 使用show status like '%slow_queries%' ; 查询下面这个变量
        • Slow_queries: 慢查询的数量 ( 客户端重新连接时,这个数据会被清0 )
阅读全文 »

一、bean的几种创建方式(IOC)

1. 使用构造函数创建bean

1.1 使用默认构造函数创建bean

<bean id=.. class=.. />, 则默认调用无参构造函数来创建bean,并装入容器中. 此时如果类中没有默认构造函数,那么对象将无法被创建

1.2 使用有参构造函数创建bean

1
2
3
4
<bean id=".." class="..">
<constructor-arg name="变量名" value="变量值"></constructor-arg>
<constructor-arg name="变量名" ref="其他bean的id"></constructor-arg>
</bean>
阅读全文 »

一、预备知识

1. 如何判断一个对象是不是垃圾

1.1 可达性分析

在这里插入图片描述
以GC ROOT为起点进行扫描,能够被扫描到的对象,都是存活的对象,而无法被扫描到的对象,就是“垃圾”,需要被回收。GC ROOT一般包括但不限于:

  • 虚拟机栈中局部变量表中引用的对象
  • 本地方法栈中 JNI 中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中的常量引用的对象
  • 被同步锁持有的对象

1.2 对象引用

可达性分析是通过 GC ROOT对象引用来完成的可达性分析,GC ROOT上面已经说过了,这里主要说说对象引用。 如果对象引用只有 :被引用 和 没被引用,那么对于描述一些“食之无味,弃之可惜”的对象就显得无能为力。 例如,对于有些对象,我们希望在内存足够多的时候保留,内存吃紧的时候被回收(例如缓存),或是对于有些对象我们希望当仅仅被某个特殊引用引用着时被回收(WeakHashMap)等,仅靠 “被引用”和“未被引用” 这两个状态,显然无法满足一些特殊情况的要求,为此,在JDK1.2之后,Java对引用概念进行了扩充。

阅读全文 »

在啃Spring的AOP之前,在复习以下动态代理及其实现方式

代理模式

在不使用代理模式的场景下,对象A想使用对象B的功能,一个方法是通过持有对对象B的引用,然后直接使用对象B提供的服务了。

而使用了代理模式,则引入一个第三方的代理对象,这个代理对象持有着对对象B的引用,可以调用对象B的服务与资源,而如果有对象希望使用对象B提供的服务的话,则不再去找对象B,而是去找这个代理对象。 如下图所示。
在这里插入图片描述
很多思想都是通过引入一个第三者来去实现某个功能,使得程序耦合度更低,或者提高代码复用性等等,例如发布-订阅模式,控制反转,领域模型的思想等等,而这里的代理模式,也是引入了一个第三者(代理对象),这个对象对外提供的接口仅仅是对某一主要功能的服务接口,代理对象内部持有真正提供这一服务的对象,通过它们来调用服务,同时,在代理对象这一层面对方法进行增强。。。

阅读全文 »

一、为什么使用线程池

1. 能够减少线程切换带来的开销

如果有大量执行时间很短的任务,那么上下文切换带来的时间开销甚至会超过任务执行的时间,这显然是不合理的。而使用线程池就能降低线程创建和销毁造成的损耗。

2. 能够提高响应速度

任务到达时,无需等待线程创建即可立即执行。

3. 提高线程的可管理性

线程是稀缺资源,如果无限制创建,不仅会消耗系统资源,还会因为线程的不合理分布导致资源调度失衡,降低系统的稳定性。使用线程池可以进行统一的分配、调优和监控。

阅读全文 »

问题:

某人给五个朋友写信,邀请他们来家中聚会。请柬和信封交由助手去处理。
粗心的助手却把请柬全装错了信封。请问:助手会有多少种装错的可能呢?

阅读全文 »

IO模型

一次网络IO会涉及两个系统对象:

  1. 等待数据准备好
  2. 将数据从内核空间的buffer拷贝到用户空间进程的buffer
    而这五种IO模型的特点就在于以怎样的方式来处理这两个系统对象和两个阶段.

Unix 有五种 I/O 模型:

  1. 阻塞式 I/O
  2. 非阻塞式 I/O
  3. I/O 复用(select 和 poll)
  4. 信号驱动式 I/O(SIGIO)
  5. 异步 I/O(AIO)
阅读全文 »