diff --git a/jvm/JVM内存模型JMM.md b/jvm/JVM内存模型JMM.md new file mode 100644 index 0000000..26bab54 --- /dev/null +++ b/jvm/JVM内存模型JMM.md @@ -0,0 +1,27 @@ +大对象,新生代存储不下的对象,分配担保直接到老年代。 + +1. 年龄超过15 +2. 相同年龄超过50% +3. 动态年龄分配,不同年龄特别多。 +4. 内存担保,新生代垃圾回收无法完成,直接放入老年代。 **在GC前还会进行一次判断,如果要分配的内存>=Eden区大小的一半,那么会直接把要分配的内存放入老年代中。否则才会进入担保机制。** + +TLAB的全称是Thread Local Allocation Buffer,即线程本地分配缓存区,这是一个线程专用的内存分配区域。 + +java -XX:+PrintCommandLineFlags -version + +什么样的对象要被GC + +判断回收算法 + +- 引用计数法,相互引用,循环引用 +- 可达性分析,GCroot(本地变量表引用对象,用来关联对象关系、方法区中的静态变量和常量,虚拟机栈中本地变量表(局部变量),static成员,常量引用,本地方法栈中变量,类加载器,Thread)。 +- 不可达对象,finalize可以挽回一次防止回收。 +- 本地方法栈中JNI引用的对象 + +### 对象头内存分配 + +![](img\对象头描述.png) + +![](img\对象头信息分布.png) + +![](img\锁描述.png) diff --git a/jvm/JVM垃圾回收.md b/jvm/JVM垃圾回收.md new file mode 100644 index 0000000..d0ce512 --- /dev/null +++ b/jvm/JVM垃圾回收.md @@ -0,0 +1,9 @@ +## GC范围 + +GC管理的主要区域是Java堆,一般情况下只针对堆进行垃圾回收。方法区、栈和本地方法区不被GC所管理,因而选择这些区域内的对象的引用作为GC roots,被GC roots引用的对象不被GC回收。 + +## 垃圾收集器 + +- 并行parallel:多个垃圾收集线程并行工作,此时用户线程处于等待状态。 +- 并发concurrent:用户线程和垃圾收集线程同时执行。 +- 吞吐量:用户代码执行时间/(用户代码执行时间+垃圾收集时间) \ No newline at end of file diff --git a/jvm/JVM简介.md b/jvm/JVM简介.md index 2d80b41..7965fa1 100644 --- a/jvm/JVM简介.md +++ b/jvm/JVM简介.md @@ -1,28 +1,28 @@ # JVM简介 -write once run everywhere +优势: + +1. write once run everywhere +2. 内存管理 ## jvm空间加载运行 参考jvm规范:https://docs.oracle.com/javase/specs/index.html -### 空间、运行时数据区 - -- 线程共享 - - Heap堆:在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。存储数据不是线程安全的,**堆和常量池**空间不足时会触发OutOfMemoryError - - MetaSpace元数据区:在1.8之后取代Method Area 方法区永久代,不在jvm中,使用本地内存,受操作系统内存限制。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 -- 线程隔离 - - VM Stack虚拟机栈:每个线程创建一个单独的运行时堆栈。对于每一个方法调用,一个称为栈内存栈帧被创建。所有局部变量将被创建在栈内存中。栈区域时线程安全的,因为他不是一个共享资源。 - - Navive Method Stack本地方法栈:与虚拟机所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。 - - Program Counter Register 程序计数器:每个线程必须分开程序计数器登记,当前执行的指令一旦被执行,程序计数器更新下一个指令。一块较小的内存空间。他的作用可以看做是当前线程所执行的字节码的行号指示器。 +- ### 加载 +![](img\class文件加载.png) + - 类加载器 - Bootstrap:加载环境变量中$JAVA_HOME/jre/lib/rt.jar里所有的class,不是ClassLoader子类。 - Extension:加载java平台中扩展功能的一些jar包。包括环境变量中$JAVA_HOME/jre/lib/*.jar或-Djava.ext.dirs指定目录下的jar包。 - Application:加载classpath中指定的jar包及目录中class。 - Custom自定义:应用程序根据自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行是实现ClassLoader +- 双亲委派 + - 写类String写main方法无法启动,Bootstrap Class Loader 中已经加载了String,其中无main方法,无法启动。委派给父类,所有父类都加载不到才会有子类加载。不让jdk代码被修改。 + ### 链接 @@ -34,12 +34,39 @@ write once run everywhere - 类或接口的初始化由执行类或接口初始化方法构成,这里所有的静态变量与原来的值将被指派,静态块将被执行。 +### 线程空间 + +![](img\线程内存使用.png) + +![](img\虚拟机栈.png) + +- 线程共享 + - Heap堆:在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。存储数据不是线程安全的,**堆和常量池**空间不足时会触发OutOfMemoryError + - MetaSpace元数据区:在1.8之后取代Method Area 方法区永久代,不在jvm中,使用本地内存,受操作系统内存限制。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。 +- 线程隔离 + - VM Stack虚拟机栈:每个线程创建一个单独的运行时堆栈。对于每一个方法调用,一个称为栈内存栈帧被创建。所有局部变量将被创建在栈内存中。栈区域时线程安全的,因为他不是一个共享资源。 + - Navive Method Stack本地方法栈:与虚拟机所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。 + - Program Counter Register 程序计数器:每个线程必须分开程序计数器登记,当前执行的指令一旦被执行,程序计数器更新下一个指令。一块较小的内存空间。他的作用可以看做是当前线程所执行的字节码的行号指示器。 + +### 运行时数据区 + +- 程序计数器:指向当前线程正在执行的字节码指令的地址和行号 + +- 虚拟机栈:存储当前线程运行方法所需的数据、指令、返回地址(动态链接,注入使用查找实例)。 + +- - 栈帧:局部变量表,操作数栈、动态链接、出口 + - javap -c -v .class > p.txt + +- 本地方法 native + +- 方法区 类信息、常量、静态变量、JIT(just in time)编译时信息(永久代对方法的实现) + +- Heap 堆(内存模型)存放new出来的对象 + +- - 新生代 + - 老年代 + - 永久代/元数据区(方法区、非堆) + ## 内存空间分配 ![image-20211020152033799](img\image-20211020152033799.png) - -## 垃圾收集器 - -- 并行parallel:多个垃圾收集线程并行工作,此时用户线程处于等待状态。 -- 并发concurrent:用户线程和垃圾收集线程同时执行。 -- 吞吐量:用户代码执行时间/(用户代码执行时间+垃圾收集时间) diff --git a/jvm/img/class文件加载.png b/jvm/img/class文件加载.png new file mode 100644 index 0000000..1c3c625 Binary files /dev/null and b/jvm/img/class文件加载.png differ diff --git a/jvm/img/对象头信息分布.png b/jvm/img/对象头信息分布.png new file mode 100644 index 0000000..30e664f Binary files /dev/null and b/jvm/img/对象头信息分布.png differ diff --git a/jvm/img/对象头描述.png b/jvm/img/对象头描述.png new file mode 100644 index 0000000..c6245b4 Binary files /dev/null and b/jvm/img/对象头描述.png differ diff --git a/jvm/img/线程内存使用.png b/jvm/img/线程内存使用.png new file mode 100644 index 0000000..82f452c Binary files /dev/null and b/jvm/img/线程内存使用.png differ diff --git a/jvm/img/虚拟机栈.png b/jvm/img/虚拟机栈.png new file mode 100644 index 0000000..79f5a63 Binary files /dev/null and b/jvm/img/虚拟机栈.png differ diff --git a/jvm/img/锁描述.png b/jvm/img/锁描述.png new file mode 100644 index 0000000..8291274 Binary files /dev/null and b/jvm/img/锁描述.png differ diff --git a/kafka/kafka.md b/mq/kafka/kafka.md similarity index 100% rename from kafka/kafka.md rename to mq/kafka/kafka.md diff --git a/mq/rabbitmq/img/mqport.png b/mq/rabbitmq/img/mqport.png new file mode 100644 index 0000000..6f77c3b Binary files /dev/null and b/mq/rabbitmq/img/mqport.png differ diff --git a/mq/rabbitmq/rabbitmq.md b/mq/rabbitmq/rabbitmq.md new file mode 100644 index 0000000..72e1134 --- /dev/null +++ b/mq/rabbitmq/rabbitmq.md @@ -0,0 +1,25 @@ +## 安装 + +https://www.rabbitmq.com/install-debian.html + +## 启动 + +```shell +## 启动 +systemctl start rabbitmq-server +## 启动web ui +rabbitmq-plugins enable rabbitmq_management +## 启动websocket +rabbitmq-plugins enable rabbitmq_web_stomp + +# create a user +rabbitmqctl add_user full_access s3crEt +# tag the user with "administrator" for full management UI and HTTP API access +rabbitmqctl set_user_tags full_access administrator +``` + +## 端口 + +https://www.rabbitmq.com/install-debian.html + +![](img\mqport.png) \ No newline at end of file diff --git a/netty/netty注释.md b/netty/netty注释.md new file mode 100644 index 0000000..e69de29 diff --git a/spring/jpa/debug findAll.md b/spring/jpa/debug findAll.md new file mode 100644 index 0000000..bdb5b3b --- /dev/null +++ b/spring/jpa/debug findAll.md @@ -0,0 +1,24 @@ +# debug findAll + +1. JpaSpecificationExecutor::Page findAll(@Nullable Specification spec, Pageable pageable); +2. SimpleJpaRepository::public Page findAll(@Nullable Specification spec, Pageable pageable) +3. CriteriaQueryTypeQueryAdapter::getResultList() +4. AbstractProducedQuery::list() +5. AbstractProducedQuery::beforeQuery() +6. 执行第一条sql:final PreparedStatement st = prepareQueryStatement( sql, queryParameters, limitHandler, scroll, session ); + +根据结果获取内容 + +```java +final List results = getRowsFromResultSet( + rs, + queryParameters, + session, + returnProxies, + forcedResultTransformer, + maxRows, + nullSeparatedHydratedObjectsPerRow, + subselectResultKeys + ); +``` + diff --git a/vue/1-vue官网学习.md b/vue/1-vue官网学习.md new file mode 100644 index 0000000..7a39340 --- /dev/null +++ b/vue/1-vue官网学习.md @@ -0,0 +1,206 @@ +#### 绑定 v-bind + +v-bind attribute :将这个元素节点的 `title` attribute 和 Vue 实例的 `message` property 保持一致 + +```javascript +
+ + 鼠标悬停几秒钟查看此处动态绑定的提示信息! + +
+var app2 = new Vue({ + el: '#app-2', + data: { + message: '页面加载于 ' + new Date().toLocaleString() + } +}) +``` + +在控制台输入改变信息:app2.message = '新消息' + +#### 控制元素显示 v-if + +```js +
+

现在你看到我了

+
+var app3 = new Vue({ + el: '#app-3', + data: { + seen: true + } +}) +``` + +直接在控制台改变属性:app3.seen = false + +#### 循环展示 v-for + +```js +
+
    +
  1. + {{ todo.text }} +
  2. +
+
+ +var app4 = new Vue({ + el: '#app-4', + data: { + todos: [ + { text: '学习 JavaScript' }, + { text: '学习 Vue' }, + { text: '整个牛项目' } + ] + } +}) +``` + +在控制台改变内容:app4.todos.push({ text: '新项目' }) + +#### 添加一个事件监听器 v-on + +```javascript +
+

{{ message }}

+ +
+var app5 = new Vue({ + el: '#app-5', + data: { + message: 'Hello Vue.js!' + }, + methods: { + reverseMessage: function () { + this.message = this.message.split('').reverse().join('') + } + } +}) +``` + +#### 表单输入和应用状态之间的双向绑定 v-model + +```js +
+

{{ message }}

+ +
+ +var app6 = new Vue({ + el: '#app-6', + data: { + message: 'Hello Vue!' + } +}) +``` + +#### 组件 + +- 任意类型的应用界面都可以抽象为一个组件树。 + +- 子单元通过 prop 接口与父单元进行了良好的解耦。 + +- 所有的 Vue 组件都是 Vue 实例。 + +```js +Vue.component('todo-item', { + // todo-item 组件现在接受一个 + // "prop",类似于一个自定义 attribute。 + // 这个 prop 名为 todo。 + props: ['todo'], + template: '
  • {{ todo.text }}
  • ' +}) + +
    +
      + + +
    +
    + +var app7 = new Vue({ + el: '#app-7', + data: { + groceryList: [ + { id: 0, text: '蔬菜' }, + { id: 1, text: '奶酪' }, + { id: 2, text: '随便其它什么人吃的东西' } + ] + } +}) + +``` + +#### 响应式 + +- 当一个 Vue 实例被创建时,它将 `data` 对象中的所有的 property 加入到 Vue 的**响应式系统**中。当这些 property 的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。 +- 值得注意的是只有当实例被创建时就已经存在于 `data` 中的 property 才是**响应式**的。 +- `Object.freeze()`,这会阻止修改现有的 property,也意味着响应系统无法再*追踪*变化。 + +```js +var obj = { + foo: 'bar' +} + +Object.freeze(obj) + +new Vue({ + el: '#app', + data: obj +}) + +
    +

    {{ foo }}

    + + +
    +``` + +- 除了数据 property,Vue 实例还暴露了一些有用的实例 property 与方法。它们都有前缀 `$`,以便与用户定义的 property 区分开来。 + +```js +var data = { a: 1 } +var vm = new Vue({ + el: '#example', + data: data +}) + +vm.$data === data // => true +vm.$el === document.getElementById('example') // => true + +// $watch 是一个实例方法 +vm.$watch('a', function (newValue, oldValue) { + // 这个回调将在 `vm.a` 改变后调用 +}) +``` + +#### 生命周期钩子 + +- 生命周期钩子的 `this` 上下文指向调用它的 Vue 实例。 +- 不要在选项 property 或回调上使用箭头函数 + +```js +new Vue({ + data: { + a: 1 + }, + created: function () { + // `this` 指向 vm 实例 + console.log('a is: ' + this.a) + } +}) +// => "a is: 1" +``` + +![](img\lifecycle.png) + diff --git a/vue/2-模板语法.md b/vue/2-模板语法.md new file mode 100644 index 0000000..e20016c --- /dev/null +++ b/vue/2-模板语法.md @@ -0,0 +1,110 @@ +如果你熟悉虚拟 DOM 并且偏爱 JavaScript 的原始力量,你也可以不用模板,[直接写渲染 (render) 函数](https://cn.vuejs.org/v2/guide/render-function.html),使用可选的 JSX 语法。 + +#### 数据绑定 + +- 数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值。 +- 通过使用 [v-once 指令](https://cn.vuejs.org/v2/api/#v-once),你也能执行一次性地插值,当数据改变时,插值处的内容不会更新,类似Object.freeze()。但请留心这会影响到该节点上的其它数据绑定。 + +```js +Message: {{ msg }} +这个将不会改变: {{ msg }} +``` + +#### v-html + +- 双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令 + +```js +

    Using mustaches: {{ rawHtml }}

    +

    Using v-html directive:

    +``` + +#### v-bind + +- Mustache 语法不能作用在 HTML attribute 上,遇到这种情况应该使用 v-bind + +```js +
    +// 如果 isButtonDisabled 的值是 null、undefined 或 false,则 disabled attribute 甚至不会被包含在渲染出来的 +``` + +#### javascript语法 + +``` +{{ number + 1 }} +{{ ok ? 'YES' : 'NO' }} +{{ message.split('').reverse().join('') }} +
    +``` + +- 数据绑定支持javascript语法 +- 每个绑定都只能包含**单个表达式** +- 模板表达式都被放在沙盒中,只能访问[全局变量的一个白名单](https://github.com/vuejs/vue/blob/v2.6.10/src/core/instance/proxy.js#L9),如 `Math` 和 `Date` 。你不应该在模板表达式中试图访问用户定义的全局变量。 + +```js + +{{ var a = 1 }} + +{{ if (ok) { return message } }} +``` + +#### 指令v- + +- 指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM。 + +```js +

    现在你看到我了

    +``` + +#### 参数 + +```js +... +// 在这里 href 是参数,告知 v-bind 指令将该元素的 href attribute 与表达式 url 的值绑定。 +... +// 在这里参数是监听的事件名。 + ... +// 这里的 attributeName 会被作为一个 JavaScript 表达式进行动态求值,求得的值将会作为最终的参数来使用。例如,如果你的 Vue 实例有一个 data property // attributeName,其值为 "href",那么这个绑定将等价于 v-bind:href。 + ... +// 当 eventName 的值为 "focus" 时,v-on:[eventName] 将等价于 v-on:focus。 +``` + +- 在 DOM 中使用模板时 (直接在一个 HTML 文件里撰写模板),还需要避免使用大写字符来命名键名,因为浏览器会把 attribute 名全部强制转为小写 + +```js + + ... +``` + +#### 修饰符 + +- 修饰符 (modifier) 是以半角句号 `.` 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。例如,`.prevent` 修饰符告诉 `v-on` 指令对于触发的事件调用 `event.preventDefault()` + +```js +
    ...
    +``` + +#### 缩写:@ + +```js + +... + +... + + ... + + +... + +... + + ... +``` + + + diff --git a/vue/3-计算属性和侦听器.md b/vue/3-计算属性和侦听器.md new file mode 100644 index 0000000..c8cb073 --- /dev/null +++ b/vue/3-计算属性和侦听器.md @@ -0,0 +1,154 @@ +## computed + +#### 计算属性 + +- 计算属性是基于它们的响应式依赖进行缓存的 + +```js +
    +

    Original message: "{{ message }}"

    +

    Computed reversed message: "{{ reversedMessage }}"

    +
    +var vm = new Vue({ + el: '#example', + data: { + message: 'Hello' + }, + computed: { + // 计算属性的 getter + reversedMessage: function () { + // `this` 指向 vm 实例 + return this.message.split('').reverse().join('') + } + } +}) + +

    Reversed message: "{{ reversedMessage() }}"

    + +// 在组件中 +methods: { + reversedMessage: function () { + return this.message.split('').reverse().join('') + } +} +``` + +#### 监听属性 + +- 类似watch + +```js +
    {{ fullName }}
    +// watch +var vm = new Vue({ + el: '#demo', + data: { + firstName: 'Foo', + lastName: 'Bar', + fullName: 'Foo Bar' + }, + watch: { + firstName: function (val) { + this.fullName = val + ' ' + this.lastName + }, + lastName: function (val) { + this.fullName = this.firstName + ' ' + val + } + } +}) +// +var vm = new Vue({ + el: '#demo', + data: { + firstName: 'Foo', + lastName: 'Bar' + }, + computed: { + fullName: function () { + return this.firstName + ' ' + this.lastName + } + } +}) +``` + +#### set + +```js +computed: { + fullName: { + // getter + get: function () { + return this.firstName + ' ' + this.lastName + }, + // setter + set: function (newValue) { + var names = newValue.split(' ') + this.firstName = names[0] + this.lastName = names[names.length - 1] + } + } +} +// 现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。 +``` + +## 监听器 + +- 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。 +- 在这个示例中,使用 `watch` 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。 + +```js +
    +

    + Ask a yes/no question: + +

    +

    {{ answer }}

    +
    + + + + + + +``` + diff --git a/vue/4-Class 与 Style 绑定.md b/vue/4-Class 与 Style 绑定.md new file mode 100644 index 0000000..cd74a8c --- /dev/null +++ b/vue/4-Class 与 Style 绑定.md @@ -0,0 +1,86 @@ +### v-bind:class + +#### 属性 + +- 我们可以传给 `v-bind:class` 一个对象,以动态地切换 class + +```js +
    + +data: { + isActive: true, + hasError: false +} +``` + +#### 对象 + +```js +
    + +//绑定的数据对象不必内联定义在模板里: +
    +data: { + classObject: { + active: true, + 'text-danger': false + } +} +data: { + isActive: true, + error: null +}, +computed: { + classObject: function () { + return { + active: this.isActive && !this.error, + 'text-danger': this.error && this.error.type === 'fatal' + } + } +} +``` + +#### 数组 + +```js +
    +data: { + activeClass: 'active', + errorClass: 'text-danger' +} +
    + +
    +
    +``` + +#### 用在组件上 + +组件中信息不会被覆盖而是追加 + +### 绑定内联样式 v-bind:style + +- CSS property 名可以用驼峰式 (camelCase) 或短横线分隔 (kebab-case,记得用引号括起来) 来命名 + +```html +
    +
    +
    +``` + +```js +data: { + activeColor: 'red', + fontSize: 30 +} +data: { + styleObject: { + color: 'red', + fontSize: '13px' + } +} +``` + diff --git a/vue/5-条件渲染.md b/vue/5-条件渲染.md new file mode 100644 index 0000000..867c623 --- /dev/null +++ b/vue/5-条件渲染.md @@ -0,0 +1,71 @@ +#### v-if + +- 当 `v-if` 与 `v-for` 一起使用时,`v-for` 具有比 `v-if` 更高的优先级。不推荐两个一起使用 + +```html +

    Vue is awesome!

    +

    Oh no 😢

    + + + +
    + Now you see me +
    +
    + Now you don't +
    + +
    + A +
    +
    + B +
    +
    + C +
    +
    + Not A/B/C +
    +``` + +#### key管理可复用元素 + +- 那么在上面的代码中切换 `loginType` 将不会清除用户已经输入的内容。因为两个模板使用了相同的元素,`` 不会被替换掉——仅仅是替换了它的 `placeholder`。 + +```html + + +``` + +- 这样也不总是符合实际需求,所以 Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 `key` attribute 即可 + +```html + + +``` + +#### v-show + +```html +

    Hello!

    +``` + +- v-show` 不支持 `