Skip to content

Instantly share code, notes, and snippets.

@biaocy
Last active December 23, 2020 08:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biaocy/3ad72573adaf3161f4eb76b1864a1ba7 to your computer and use it in GitHub Desktop.
Save biaocy/3ad72573adaf3161f4eb76b1864a1ba7 to your computer and use it in GitHub Desktop.

知识点

语言

基础
  • 面向对象特性:封装、继承、多态
  • 集合: List、Set、Map
  • 异常:
    • Checked Exception
    • Unchecked Exception: RuntimeException, Error, and their subclasses
  • I/O:
    • I/O Streams
    • File I/O
  • 缺点:性能低
    • 原因:
      • Method#invoke 方法会对参数做封装和解封操作
      • 需要检查方法可见性
      • 需要校验参数
      • 反射方法难以内联
      • JIT 无法优化
    • 替代方案: 参考
  • 获取Class对象:
    • Object.getClass(): 一般对象类型的Class对象获取方式
    • .class: 原始类型的Class对象获取方式,boolean.class
    • Class.forName(): 根据类全名获取Class对象,Class.forName("[Ljava.lang.String;"), 获取String[]Class对象
    • TYPE field for primitive type wrappers: Doulbe.TYPE
  • Class对象常见方法:
    • 获取Class modifers: c.getModifiers()
    • 获取Type parameters: c.getTypeParameters()
    • 获取实现接口: c.getGenericInterfaces()
    • 获取父类: c.getSuperClass()
    • 获取Annotations: c.getAnnotations()
    • 获取字段: c.getDeclaredField(), c.getField()
    • 获取方法: c.getDeclaredMethod(), c.getMethod()
    • 获取构造方法: c.getDeclaredConstructor(), c.getConstructor()
  • 使用:
    ...
    Constructor<?>[] ctors = Test.class.getDeclaredConstructors();
    Constructor ctor = null;
    for (int i = 0; i < ctors.length; i++) {
        ctor = ctors[i];
        if (ctor.getGenericParameterTypes().length == 0) {
            break;
        }
    }
    
    try {
        // 1. 反射创建对象
        Test t = (Test) ctor.newInstance();
        System.out.println(t);
    
        // 2. 反射调用对象方法
        Method declaredMethod = Test.class.getDeclaredMethod("setName", String.class);
        declaredMethod.invoke(t, "Reflection");
        System.out.println(t);
    } catch (Exception e) {
        e.printStackTrace();
    }
    ...
  • volatile: 保证被修饰字段的内存可见性,参考参考

    • 若两个线程A、B,分别对同一字段先后进行写读,则不能保证A线程对字段的写操作会被随后的B线程读操作可见,容易造成数据不一致问题; 此时对字段加上volatile关键字修饰,则可以保证以上场景的A线程写操作必定会被随后的B线程读操作可见,即保证了数据一致
    • 注意:在多线程写的场景下,会出现race condition,此时即使字段加上volatile关键字也无法解决race condition,必须对操作加锁
  • Runnable

  • Thread:

    • Thread.sleep
    • Thread.interrupted(), t.isInterrupted()
    • t.join
  • Synchronization:

    • Thread Interference
    • Memory Consistency Errors
    • Synchronized Methods and Synchronized Statements: Intrinsic lock
    • Atomic Access
  • Lock: 参考

    • ReentrantLock: 重入锁,拥有锁的线程可以再次持有锁
    • ReadWriteLock: 读写锁,实现ReentrantReadWriteLock,维持一对读写锁
      • 适用于多读少写的场景
      • 写锁: 互斥锁
      • 读锁: 当写锁未被持有时,可以被多个线程持有
    • StampedLock: JDK1.8之后新增,也是读写锁的一种,但是比ReadWriteLock多了乐观读操作,优化了ReadWriteLock
      • 适用于多读少写的场景
    • Condition: @TODO
  • Executors: 参考, 参考

    • Executor, ExecutorService, ScheduleExecutorService
    • Thread Pools
      • CachedThreadPool: 当需要的时候才创建线程,若线程池内有可用的线程也可复用,闲置线程默认等待60s销毁
      • FixedThreadPool: 创建指定线程数量的线程池,若池内所有线程都有任务,则新任务将会在队列里等待
      • ScheduledThreadPool: 创建调度线程池,具有定期执行或延期执行能力的线程池
    • Fork/Join Framework
  • Concurrent Collections

    • 接口:
      • BlockingQueue: Defines a first-in-first-out data structure that blocks or times out when you attempt to add to a full queue, or retrieve from an empty queue.
      • ConcurrentMap: A subinterface of java.util.Map that defines useful atomic operations. These operations remove or replace a key-value pair only if the key is present, or add a key-value pair only if the key is absent. Making these operations atomic helps avoid synchronization. The standard general-purpose implementation of ConcurrentMap is ConcurrentHashMap, which is a concurrent analog of HashMap.
      • ConcurrentNavigableMap: A subinterface of ConcurrentMap that supports approximate matches. The standard general-purpose implementation of ConcurrentNavigableMap is ConcurrentSkipListMap, which is a concurrent analog of TreeMap.
  • Atomic Vairables

ClassLoader
  • 类型
    • Bootstrap class loader: JVM's built-in class loader, it is the parent of all others class loaders.
    • Application/System class loader: An application class loader loads our own files in the classpath.
    • Extension class loader: It load classes that are an extension of the standard core Java classes (Sits in $JAVA_HOME/lib/ext directory).
  • 加载原理:
    • The java.lang.ClassLoader.loadClass() method is responsible for loading the class definition into runtime. It tries to load the class based on a fully qualified name.
    • If the class isnt' already loaded, it delegates the request to the parent class loader. This process happens recursively.
    • Eventually, if the parent class loader doesn't find the class, then the child class loader will call java.net.URLClassLoader.findClass() method to look for classes in the file system itself.
    • If the last class loader isn't able to load the class either, it throws java.lang.NoClassDefFoundError or java.lang.CLassNotFoundException.
  • Every Class object contains a reference to the ClassLoader that defined it, except class objects for array class.

框架

Bean
  • 生命周期:
    当Spring容器启动时,会根据bean的定义去实例化bean,如果bean定义了初始化方法(init,@PostConstruct,InitlizingBean.afterPropertiesSet),就先执行初始化方法;
    当bean使用完后,如果bean定义了销毁方法(destroy,@PreDestroy,DisposableBean.destroy),就会执行销毁方法,然后销毁bean实例
  • Scope:
    • singleton(default): Single bean object instance per Spring IoC container.
    • prototype: Opposite to singleton, it produces a new instance each and every time a bean is requested.
    • request: A single instance will be created and available during complete lifecycle of an HTTP request. Only valid in web-aware Spring ApplicationContext.
    • session: A single instance will be created and available during complete lifecycle of an HTTP session. Only valid in web-aware Spring ApplicationContext.
    • application: A single instance will be created and available during complete lifecycle of ServletContext. Only valid in web-aware Spring ApplicationContext.
    • websocket: A single instance will be created and available during complete lifecycle of WebSocket. Only valid in web-aware Spring ApplicationContext.
  • 创建方式:
    • Constructor
    <bean id="exampleBean"/>
    • Static factory method
    <bean id="exampleBean" factory-method="createInstance"/>
    • Instance factory method
    <bean id="myFactoryBean"  class="...">
    
    <bean id="exampleBean"  factory-bean="myFactoryBean" factory-method="createInstance"></bean>
  • Setter Injection
public class TestSetterDI {
 
    DemoBean demoBean = null;
     
    public void setDemoBean(DemoBean demoBean) {
        this.demoBean = demoBean;
    }
}
  • Constructor Injection
public class ConstructorDI {
 
    DemoBean demoBean = null;
     
    public TestSetterDI (DemoBean demoBean) {
        this.demoBean = demoBean;
    }
}
  • BeanFactory
  • ApplicationContext: 添加了读取properties配置,发布应用事件等能力
    • ClassPathXmlApplicationContext
    • FileSystemXmlApplicationContext
    • XmlWebApplicationContext
  • Spring AOP defaults to using standard JDK dynamic proxies for AOP proxies.
    If the target object to be proxied implements at least one interface, a JDK dynamic proxy is used.
    If the target object does not implement any interfaces, a CGLIB proxy is created.
  • Advice 类型: Before, after, around
  • 术语:
    • Aspect 切面: 事务管理,日志等等
    • Joint Point 切入点: 方法的执行,异常的处理等
    • Advice 切入逻辑: 被切入的逻辑, 类型有 Before, after returning, after throwing, after, around.
    • Pointcut 切入点的定义: 用表达式去定义切入点,譬如 execution (* Classname.methodName(..))
    • Introdcution 切面所新增的方法和字段
    • Target Object: 被切入的对象,也叫 advised object.
    • AOP Proxy 代理:
      • JDK Dynamic Proxy: 基于interface的代理
      • CGLIB Proxy: 基于class的代理
MVC
  • Front controller: DispatcherServlet

  • Spring web 容器启动后,根据配置(applicationContext.xml或注解或JavaConfig)会默认注册一系列的组件

    public class MvcNamespaceHandler extends NamespaceHandlerSupport {
    
        @Override
        public void init() {
            registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
            registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
            registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
            registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
            registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
            registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
            registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
            registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
            registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
            registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
            registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
            registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
            registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
        }
    
    }
    • AnnotationDrivenBeanDefinitionParser 为例
    • 注册以下HandlerMapping:
      • RequestMappingHandlerMapping
      • BeanNameUrlHandlerMapping
    • 注册以下HandlerAdapter:
      • RequestMappingHandlerAdapter
      • HttpRequestHandlerAdapter
      • SimpleControllerHandlerAdapter
    • 注册以下HandlerExceptionResolver:
      • ExceptionHandlerExceptionResolver
      • ResponseStatusExceptionResolver
      • DefaultHandlerExceptionResolver
    • 且注册的RequestMappingHandlerAdapterExceptionHandlerExceptionResolver都默认配置了以下实例:
      • ContentNegotiationManager
      • DefaultFormattingConversionService
      • LocalValidatorFactoryBean(如果JSR-303实现类库存在classpath中)
      • 一些HttpMessageConverter(具体视classpath中的第三方类库而定)
      • 默认的ArugmentResolvers
      • 默认的InitBinderArgumentResolvers
      • 默认的ReturnValueHandlers
        RequestMappingHandlerAdapter.java
        public void afterPropertiesSet() {
            ...
            if (this.argumentResolvers == null) {
                List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
                this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
            }
            if (this.initBinderArgumentResolvers == null) {
                List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
                this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
            }
            if (this.returnValueHandlers == null) {
                List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();
                this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
            }
        }
  • Spring MVC 处理请求流程:

    • 所有请求首先都由 DispactherServlet 处理
    • 为请求设置 applicationContext, localeResolver, themeResolver等等
    • 根据容器内已注册的Handlers,按顺序为请求匹配 Handler,如RequestMappingHandlerMapping,BeanNameUrlHandlerMapping
    • 根据容器内已注册的Adapters,按顺序为 Handler 匹配 Adapters, 如RequestMappingHandlerAdapter
    • 由Adapter调用已匹配的Handler,开始执行业务逻辑,得到响应或抛出异常
      • 根据请求信息和ArgumentResolver,解析业务方法参数
        InvocableHandlerMethod.java
        public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
                Object... providedArgs) throws Exception {
        
            Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
            if (logger.isTraceEnabled()) {
                logger.trace("Arguments: " + Arrays.toString(args));
            }
            return doInvoke(args);
        }
      • 由已注册的ReturnValueHandler,解析业务方法返回值
        ServletInvocableHandlerMethod.java
        public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
                Object... providedArgs) throws Exception {
            ...
            try {
                this.returnValueHandlers.handleReturnValue(
                        returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
            }
            catch (Exception ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace(formatErrorForReturnValue(returnValue), ex);
                }
                throw ex;
            }
            ...
        }
      • 若得到正常响应,则渲染ModelAndView,由LocaleResolver设置本地化信息,查找匹配的ViewResolver,解析真实的View进行渲染
      • 若抛出异常,则解析异常,查找匹配的HandlerExceptionResolver,解析异常的View或设置http status code返回
事物传递类型: 参考
定时任务

Spring Cloud

Spring Cloud Config

Provides server-side and client-side support for externalized configuration in distributed system.

  • Config Server
  • Config Client

MyBatis

  • 缓存:
    • 一级缓存: 默认开启, Session cache within a SqlSession. It can not be accessed from another SqlSession.
      一级缓存开启情况下,当多个会话同时对同个数据进行读写,很容易造成数据脏读. 建议关闭,设置为 Statement.
    • 二级缓存: 默认关闭,Global cache is shared among SqlSessions.
      分布式环境需要使用缓存中间件实现数据一致
  • 批量插入:
    • 利用 <foreach>标签: 插入量大时,性能差
    <insert id="batchInsert" parameterType="..." useGenerate>
        INSERT INTO TABLE_NAME(field1, field2)
        VALUES
        <foreach collection="list" item="model" seperator=",">
            (model.field1, model.field2)
        </foreach>
    </insert>
    • 利用MyBatis的Batch Insert Support,需要设置ExecutorType.BATCH: 针对插入量大的情况
        ...
        try(SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
            SimpleTableMapper mapper = session.getMapper(SimpleTableMapper.class);
            List<SimpleTableRecord> records = getRecordsToInsert(); // not shown
    
            BatchInsert<SimpleTableRecord> batchInsert = insert(records)
                    .into(simpleTable)
                    .map(id).toProperty("id")
                    .map(firstName).toProperty("firstName")
                    .map(lastName).toProperty("lastName")
                    .map(birthDate).toProperty("birthDate")
                    .map(employed).toProperty("employed")
                    .map(occupation).toProperty("occupation")
                    .build()
                    .render(RenderingStrategies.MYBATIS3);
    
            batchInsert.insertStatements().forEach(mapper::insert);
    
            session.commit();
        }
        ...
      - 如果写xml mapper,创建的`SqlSession`必须设置`ExexcutorType.BATCH`:[参考](https://stackoverflow.com/questions/36407980/mybatis-performance-of-bulk-operator/36425820)
    

Hibernate

  1. 缓存
  2. 映射关系

ES

缓存/消息中间件

Redis
  • 数据类型
    • Strings: String值默认最大可存储512M
      Command: SET, GET, INCR, DECR...
    • Lists: Lists of strings. Sorted by insertion order by default. Can add elements on the head or on the tail.
      Command: LPUSH, LPOP, LSET, LRANGE...
    • Sets: An unordered collection of Strings. Can add, remove, test for existence of members in O(1).
      Command: SADD, SPOP, SMEMBERS, SISMEMBER...
    • Hashes: Map between string fields and string values.
      Command: HSET, HGET, HDEL, HMSET...
    • Sorted sets: Sets in order with score.
      Command: ZADD, ZRANGE, ZINCRBY, ZSCORE...
  • 高可用: Redis Sentinel, Redis Cluster, Redis 主从
  • 持久化:
    • RDB: 快照,以指定时间间隔保存数据。例如在24小时内的每小时间隔,以及30天内每天间隔保存快照。
    • AOF: 追加文件,服务器记录每一个写操作。服务器重启时,再根据记录重建数据。所有命令都会以Redis协议格式记录,追加到数据文件。
  • 分布式锁: @TODO 参考
Kafka

数据库

  • 问题

    • 脏读: 一事务中可以读到其他事务未提交的数据
    • 不可重复读: 在一事务中,两次读同一数据,两次结果不同
    • 幻读: 在一事务中,同样条件两次查询数据,两次条数不同
  • MySQL(InnoDB): 参考

    • ACID特性:
      • Atomicity: 原子性,一个事务是一个不可分割的工作单位,要么都做,要么不做。
      • Durability: 持久性,保证事务提较后,不会因为宕机等原因导致数据丢失。
      • Isolation: 隔离性,保证事务执行尽可能不受其他事务影响。
      • Consistency: 一致性,保证事务执行结束后,数据库的完整性约束没有被破坏,事务执行前后都是合法的数据状态。
    • 事务隔离级别: 隔离级别越低,系统开销越低,可支持的并发越高,隔离性越差
      • Read Uncommitted: 读未提交
      • Read Committed: 读已提交
      • Repeatable Read: 可重复读
        InnoDB默认隔离级别RR,InnoDB通过MVCC Multi-Version Concurrency Control 多版本并发控制,避免了RR脏读、不可重复读、幻读的问题
      • Serializable: 串行化
    隔离级别 脏读 不可重复读 幻读
    Read Uncommitted 可能 可能 可能
    Read Committed 不可能 可能 可能
    Repeatable Read 不可能 不可能 可能
    Serializable 不可能 不可能 不可能
    • 索引

Web服务器

Tomcat
  • 最大并发请求数:视connector类型而定,NIO默认10000,APR/Native默认8192,可修改maxConnections参数参见

反代

Nginx
  • 负载均衡
    • 均衡方法:

      • round-robin: 默认,轮询
      • least-connected: 分配给最少连接的server
      • ip-hash: 基于连接ip,以ip hash来决定连接的server
      • 其他:
        • 还可以配置server 权重,以下配置,每5个请求将会有3个连接srv1server,srv2、srv3各1个
        upstream myapp1 {
            server srv1.example.com weight=3;
            server srv2.example.com;
            server srv3.example.com;
        }
        
    • 配置:

    http {
        upstream myapp1 {
            [least_conn | ip_hash]
            server srv1.example.com;
            server srv2.example.com;
            server srv3.example.com;
        }
    
        server {
            listen 80;
    
            location / {
                proxy_pass http://myapp1;
            }
        }
    }
    
  • 动态路由

底层

JVM
  • HotSpot JVM:
    • JVM内存结构和内存模型: 参考0参考1, 参考2
    • Class Loader Subsystem: Classloader is used to load class files.
    • Runtime Data Area:
      • Method Area: Method area stores data for each and every class like fields, constant pool, methods'data and information
      • Heap: Heap is place where all objects are stored in JVM
        • Young generation:
          • Eden
          • Survivor Space:
            • S0
            • S1
        • Old(Tenured) generation
        • Permanent generation
      • Java Threads(Java thread Stack): Whenever new method is called, new stack frame is created and it is pushed on top of
        that thread's stack
      • Program counter registers(PC Registers)
      • Native internal Threads(Native thread Stack)
    • Execution Engine:
    • GC Tuning:
      • Java 6
      • Java 8
      • Heap:
        • -Xms,-Xmx: Set the size of minimum/maximum heap
        • -Xmn: Set the size of young generation
        • -XX:NewRatio: Control the size of young/old generation ratio -XX:NewRatio=3, means that the ratio between the young and old generation is 1:3
        • -XX:NewSize,-XX:MaxNewSize: Set minimum/maximum size of young generation
        • -XX:PermSize,-XX:MaxPermSize: Set minimum/maximum size of permanent generation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment