源码

为什么要看源码、如何看源码,高手进阶必看

眉间皱痕 提交于 2020-01-23 14:10:03
由于项目的需求,最近花了较多的时间来看开源项目的代码,在本文中,简单总结一下对为什么要看源码、如何看源码这两个问题的思考。 看源码的意义 看源码只是一种方法、手段,而不是目的。我也曾经给自己制定过“阅读xxx源码”的目标,现在看起来真的很蠢,一点不smart(specific、measurable、attainable、relevant、time-bound)。 只有搞清楚了阅读代码的目标,才能有的放矢,抓住重点,高效达成任务。 看源码的意义总结起来包含但不限于以下几点: 一、解决问题(BUG) 只要是代码,就会有bug,只是说bug的多与少、深与浅罢了。现在大家都喜欢发布、使用开源项目,不同的开源项目社区成熟度、代码质量又会有较大的差异,遇到bug就不足为奇了。 当然,遇到bug肯定是先在网上搜索是否有类似的问题,一般可以在google、Stack Overflow、项目的issues里面有对应的关键词搜索。如果搜不到,那么就只能看源码解决了 二、知其所以然 我在[如何学习新技术、团队技术选型时要注意些什么][Link 1]里面提到过,如果我们需要将一个开源项目用到自己的项目中,那么就必须了解这项项目的优缺点,并深知原理,对部分细节(尤其是项目的优势、feature)进行深入研究。 如果是成熟的开源项目,遇到问题也许能google到很多答案;但如果是一个处于快速发展中的开源项目

Spring AOP 源码解析

若如初见. 提交于 2020-01-23 10:46:26
[TOC] 之前写过 IOC 的源码分析,那篇文章真的有点长,看完需要点耐心。很多读者希望能写一写 Spring AOP 的源码分析文章,这样读者看完 IOC + AOP 也就对 Spring 会有比较深的理解了。今天终于成文了,可能很多读者早就不再等待了,不过主要为了后来者吧。 本文不会像 IOC 源码分析那篇文章一样,很具体地分析每一行 Spring AOP 的源码,目标读者是已经知道 Spring IOC 源码是怎么回事的读者,因为 Spring AOP 终归是依赖于 IOC 容器来管理的。 阅读建议:1、先搞懂 IOC 容器的源码 ,AOP 依赖于 IOC 容器来管理。2、仔细看完 Spring AOP 使用介绍 这篇文章,先搞懂各种使用方式,你才能"猜到"应该怎么实现。 Spring AOP 的源码并不简单,因为它多,所以阅读源码最好就是找到一个分支,追踪下去。 本文定位为走马观花,看个大概,不具体到每一个细节。 目录: 前言 这一节,我们先来"猜猜" Spring 是怎么实现 AOP 的。 在 Spring 的容器中,我们面向的对象是一个个的 bean 实例,bean 是什么?我们可以简单理解为是 BeanDefinition 的实例,Spring 会根据 BeanDefinition 中的信息为我们生产合适的 bean 实例出来。 当我们需要使用 bean 的时候

HashMap以及源码详解

天涯浪子 提交于 2020-01-23 10:28:30
HashMap实现接口以及继承类 实现了Map,Cloneable,Serializable接口,继承自AbstractMap类。 允许 null 值和 null 键,无序,不允许重复的集合 HashMap底层结构 HashMap底层接口是哈希表,也就是所谓的散列表。 简单介绍一下散列表,散列表的出现是为了解决链表和数组的缺陷,链表增删快,查询慢,数组查询快,增删慢。而散列表基于数组和列表进行演变,使得查询和增删的速度都非常快。 散列表的结构如下。 hashMap中的散列表是用数组+链表+红黑树去实现的 。 好的散列方式,会把数据散列到不同的位置,哪怕散列到同一个位置(这就是所谓的 哈希冲突 ),我们可以把它链起来变成链表(Java采用 链地址法 ),只要这个链表足够的短,我们就可以最快的查询数据,因为遍历两三个节点的时间非常短,近似于O(1)。 当链表足够长( 链表长度 >= 8)并且,节点足够多(节点数 >= 64)的时候,我们就把当前的链表变成红黑树。 (为什么节点 >=8 才变成红黑树,<=6变成链表? 因为根据泊松分布,当节点树大于等于 8 的时候,红黑树查询会比链表查询要快,而当节点数小于等于 6 的时候,会链表查询回避红黑树要快。7的时候是相当。) HashMap常用方法以及源码解析 简单介绍以下变量以及初始值: HashMap的最大容量(MAXIMUM

HashMap源码解析(jdk1.8)

纵然是瞬间 提交于 2020-01-23 08:19:01
HashMap在开发中经常用,而且面试的时候肯定也会被问到,所以了解源码是很有必要的,能够让我们更好的使用HashMap,今天总结一下,在最后面会有相关面试题。本文不会对红黑树代码由太多深入研究,特别是删除方面太复杂,我们知道红黑树的特点和基本实现原理差不多就可以了,这里推荐先学习2-3树,然后学习红黑树就会水到渠成,然后能够手写实现红黑树就挺好的。 这里HashMap源码基于jdk1.8,我们都知道1.8版本的HashMap有很大改变,而且现在开发一般也都是使用jdk1.8+版本,HashMap底层通过数组+链表+红黑树实现,对红黑树和链表不了解可以参考: Java数据结构和算法(四)–链表 Java数据结构和算法(八)–红黑树与2-3树 HashMap数据结构: 基本结构: public class HashMap < K , V > extends AbstractMap < K , V > implements Map < K , V > , Cloneable , Serializable { private static final long serialVersionUID = 362498820763181265 L ; } 继承了AbstractMap,又实现了Map,这里算是jdk集合开发者的一个失误吧,后来证明这样写应该是没什么用的,只是一直保留下来了

JDK源码那些事儿之浅析Thread上篇

ⅰ亾dé卋堺 提交于 2020-01-23 03:53:39
JAVA中多线程的操作对于初学者而言是比较难理解的,其实联想到底层操作系统时我们可能会稍微明白些,对于程序而言最终都是硬件上运行二进制指令,然而,这些又太过底层,今天来看一下JAVA中的线程,浅析JDK源码中的Thread类,之后能帮助我们更好的处理线程问题 前言 JDK版本号:1.8.0_171 在Thread注释中可以看到大佬对其进行的解释: Thread就是程序中一个线程的执行.JVM允许一个应用中多个线程并发执行 每个线程都有优先级.高优先级线程优先于低优先级线程执行 每个线程都可以(不可以)被标记为守护线程 当线程中的run()方法代码里面又创建了一个新的线程对象时,新创建的线程优先级和父线程优先级一样 当且仅当父线程为守护线程时,新创建的线程才会是守护线程 当JVM启动时,通常会有唯一的一个非守护线程(这一线程用于调用指定类的main()方法) JVM会持续执行线程直到下面某一个情况发生为止: 1.类运行时exit()方法被调用且安全机制允许此exit()方法的调用. 2.所有非守护类型的线程均已经终止,或者run()方法调用返回或者在run()方法外部抛出了一些可传播性的异常. 可以联想下JVM的启动过程,从main方法启动,可以自己写代码查看下线程情况 线程实现 Thread注释类上清楚的写明了线程的两种实现方式: 定义一个继承Thread类的子类

源码包与RPM包安装的区别

匆匆过客 提交于 2020-01-23 01:58:26
1. 源码包与RPM包的区别 概念上的区别 安装位置不同 源码包安装位置/usr/local/软件名/ 2源码包安装准备 2.1安装准备 安装C语言编译器 下载源码包 2.2安装注意事项 源代码保存位置:/usr/local/src/ 软件安装位置:/usr/local/src/ 如何确定安装过程报错 安装过程停止 并出现error、warning或no的提示 3源码包安装过程 下载源码包 解压缩下载的源码包 进入解压缩目录 ./config 软件配置与检查 定义需要的功能选项 ./configure --prefix=/usr/local/apache2 检测系统环境是否符合安装要求 把定义好的功能选项和检测环境信息都写入Makefile文件,用于后续的编辑。 make 编译 make clean make install 编译安装 源码包卸载 rm -rf 安装目录 脚本安装包 http://sourceforge.net/projects/webadmin/files/webmin/ 解压缩 执行脚本 来源: CSDN 作者: 请叫我常总裁 链接: https://blog.csdn.net/weixin_43055250/article/details/103958438

Spring源码之环境搭建

寵の児 提交于 2020-01-23 01:34:18
Spring源码之环境搭建 源码阅读版本5.0x。 https://github.com/spring-projects/spring-framework/tree/5.0.x 操作步骤 第一步: 到github上找到对应的项目,切换对应的分支,让后下载 https://github.com/spring-projects/spring-framework/ 直接下载到本地,解压。 第二步: 借助InteliJ IDEA 导入工程。 Spring使用gradle进行管理,导入时使用gradle方式 补充异常: Plugin [id: ‘com.gradle.build-scan’, version: ‘1.8’] was not found in any of the following sources: 出现这个问题则先不用选择: use local gradle distribution 第一次使用import方式,会下载相关的jar包,过程比较长。 第三步 :解决 cglib 和 objenesis 的编译错误 Spring把最新的cglib和objensesis给重新打包,直接放在jar中,这个时候需要将对应的jar补回来 下载 spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.1.jar 到对应目录下

Vue源码之 $emit

旧时模样 提交于 2020-01-23 00:46:39
比如this.$emit('functionName',otherArguments),这里的this是一个Vue实例 $emit和v-on是一路的 组件节点上的v-on和真实节点上的v-on不一样,前者的v-on的方法key-value键值对会保存在组件的虚拟节点中,再传递给组件的parentListener属性, 在initEvents的时候,收集到vm._events数组中,(这个是在创建周期中提前处理的,而更新周期的处理在prepatch--->updateChildComponent方法中) 和真实节点的v-on对应的是组件节点上的v-on.native,这个的处理,在创建周期是先在生成虚拟节点vnode的时候把data.on = nativeOn 在patch()--->createComponent--->Vnode.data.hook.init之后的initComponent方法中的invokeCreateHooks, 把那七八个函数什么updateAttr,updateStyle,updateDOMListeners之类的,其中updateDOMListeners就是调用updateListeners方法,再调用真实节点的addEventListeners方法 真实的添加属性的绑定方法,注意上面说的initEvents也是调用updateListeners方法

源码学习之线程池

自作多情 提交于 2020-01-23 00:09:12
大家面试过程中肯定被问道过线程池。为什么要使用线程池呢?因为在系统中频繁创建线程会造成很大的CPU消耗。而且用完的线程要等待GC回收也会造成消耗。 下面我们就来学习下最常用的线程池 ThreadPoolExecutor, 首先先来看看它的构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.acc = System.getSecurityManager() =