Skip to content

Commit 60829e5

Browse files
committed
feat: update
1 parent e268420 commit 60829e5

31 files changed

Lines changed: 64 additions & 64 deletions

‎CPP/函数.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ inline int inline03()
3232

3333
内联函数:
3434

35-
Tip: 只有当函数只有 10 行甚至更少时才将其定义为内联函数.
35+
Tip: 只有当函数只有 10 行甚至更少时才将其定义为内联函数.
3636

3737
定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用.
3838
优点: 当函数体比较小的时候, 内联该函数可以令目标代码更加高效. 对于存取函数以及其它函数体比较短, 性能关键的函数, 鼓励使用内联.
@@ -42,7 +42,7 @@ Tip: 只有当函数只有 10 行甚至更少时才将其定义为内联函数
4242

4343
-inl.h 文件:
4444

45-
Tip: 复杂的内联函数的定义, 应放在后缀名为 -inl.h 的头文件中.
45+
Tip: 复杂的内联函数的定义, 应放在后缀名为 -inl.h 的头文件中.
4646

4747
内联函数的定义必须放在头文件中, 编译器才能在调用点内联展开定义. 然而, 实现代码理论上应该放在 .cc 文件中, 我们不希望 .h 文件中有太多实现代码, 除非在可读性和性能上有明显优势.
4848
如果内联函数的定义比较短小, 逻辑比较简单, 实现代码放在 .h 文件里没有任何问题. 比如, 存取函数的实现理所当然都应该放在类定义内. 出于编写者和调用者的方便, 较复杂的内联函数也可以放到 .h 文件中, 如果你觉得这样会使头文件显得笨重, 也可以把它萃取到单独的 -inl.h 中. 这样把实现和类定义分离开来, 当需要时包含对应的 -inl.h 即可。

‎CPP/继承与重载.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,4 +379,4 @@ class B
379379

380380
静态联编:在程序链接阶段就可以确定的调用。动态联编:在程序执行时才能确定的调用。
381381

382-
1. this 指针的用处: 一个对象的 this 指针并不是对象本身的一部分,不会影响 sizeof(对象)的结果。this 作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上 this 指针,编译器在编译的时候也是加上 this 的,它作为非静态成员函数的隐含形参,对各成员的访问均通过 this 进行。 例如,调用 date.SetMonth(9) <===> SetMonth(&date, 9),this 帮助完成了这一转换 2. this 指针的使用: 一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;另外一种情况是当参数与成员变量名相同时,如 this->n = n (不能写成 n = n)。3. this 指针程序示例: this 指针存在于类的成员函数中,指向被调用函数所在的类实例的地址。 根据以下程序来说明 this 指针 #include<iostream.h> class Point { int x, y; public: Point(int a, int b) { x=a; y=b;} void MovePoint( int a, int b){ x+=a; y+=b;} void print(){ cout<<"x="<<x<<"y="<<y<<endl;} }; void main( ) { Point point1( 10,10); point1.MovePoint(2,2); point1.print( ); } 当对象 point1 调用 MovePoint(2,2)函数时,即将 point1 对象的地址传递给了 this 指针。 MovePoint 函数的原型应该是 void MovePoint( Point *this, int a, int b);第一个参数是指向该类对象的一个指针,我们在定义成员函数时没看见是因为这个参数在类中是隐含的。这样 point1 的地址传递给了 this,所以在 MovePoint 函数中便显式的写成: void MovePoint(int a, int b) { this->x +=a; this-> y+= b;} 即可以知道,point1 调用该函数后,也就是 point1 的数据成员被调用并更新了值。 即该函数过程可写成 point1.x+= a; point1. y + = b;4. 关于 this 指针的一个经典回答: 当你进入一个房子后, 你可以看见桌子、椅子、地板等, 但是房子你是看不到全貌了。 对于一个类的实例来说, 你可以看到它的成员函数、成员变量, 但是实例本身呢? this 是一个指针,它时时刻刻指向你这个实例本身 1. this 指针的用处: 一个对象的 this 指针并不是对象本身的一部分,不会影响 sizeof(对象)的结果。this 作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上 this 指针,编译器在编译的时候也是加上 this 的,它作为非静态成员函数的隐含形参,对各成员的访问均通过 this 进行。 例如,调用 date.SetMonth(9) <===> SetMonth(&date, 9),this 帮助完成了这一转换 2. this 指针的使用: 一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;另外一种情况是当参数与成员变量名相同时,如 this->n = n (不能写成 n = n)。3. this 指针程序示例: this 指针存在于类的成员函数中,指向被调用函数所在的类实例的地址。 根据以下程序来说明 this 指针 #include<iostream.h> class Point { int x, y; public: Point(int a, int b) { x=a; y=b;} void MovePoint( int a, int b){ x+=a; y+=b;} void print(){ cout<<"x="<<x<<"y="<<y<<endl;} }; void main( ) { Point point1( 10,10); point1.MovePoint(2,2); point1.print( ); } 当对象 point1 调用 MovePoint(2,2)函数时,即将 point1 对象的地址传递给了 this 指针。 MovePoint 函数的原型应该是 void MovePoint( Point *this, int a, int b);第一个参数是指向该类对象的一个指针,我们在定义成员函数时没看见是因为这个参数在类中是隐含的。这样 point1 的地址传递给了 this,所以在 MovePoint 函数中便显式的写成: void MovePoint(int a, int b) { this->x +=a; this-> y+= b;} 即可以知道,point1 调用该函数后,也就是 point1 的数据成员被调用并更新了值。 即该函数过程可写成 point1.x+= a; point1. y + = b;4. 关于 this 指针的一个经典回答: 当你进入一个房子后, 你可以看见桌子、椅子、地板等, 但是房子你是看不到全貌了。 对于一个类的实例来说, 你可以看到它的成员函数、成员变量, 但是实例本身呢? this 是一个指针,它时时刻刻指向你这个实例本身
382+
1. this 指针的用处: 一个对象的 this 指针并不是对象本身的一部分,不会影响 sizeof(对象)的结果。this 作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上 this 指针,编译器在编译的时候也是加上 this 的,它作为非静态成员函数的隐含形参,对各成员的访问均通过 this 进行。 例如,调用 date.SetMonth(9) <===> SetMonth(&date, 9),this 帮助完成了这一转换 2. this 指针的使用: 一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;另外一种情况是当参数与成员变量名相同时,如 this->n = n (不能写成 n = n)。3. this 指针程序示例: this 指针存在于类的成员函数中,指向被调用函数所在的类实例的地址。 根据以下程序来说明 this 指针 #include<iostream.h> class Point { int x, y; public: Point(int a, int b) { x=a; y=b;} void MovePoint( int a, int b){ x+=a; y+=b;} void print(){ cout<<"x="<<x<<"y="<<y<<endl;} }; void main( ) { Point point1( 10,10); point1.MovePoint(2,2); point1.print( ); } 当对象 point1 调用 MovePoint(2,2)函数时,即将 point1 对象的地址传递给了 this 指针。 MovePoint 函数的原型应该是 void MovePoint( Point *this, int a, int b);第一个参数是指向该类对象的一个指针,我们在定义成员函数时没看见是因为这个参数在类中是隐含的。这样 point1 的地址传递给了 this,所以在 MovePoint 函数中便显式的写成: void MovePoint(int a, int b) { this->x +=a; this-> y+= b;} 即可以知道,point1 调用该函数后,也就是 point1 的数据成员被调用并更新了值。 即该函数过程可写成 point1.x+= a; point1. y + = b;4. 关于 this 指针的一个经典回答: 当你进入一个房子后, 你可以看见桌子、椅子、地板等, 但是房子你是看不到全貌了。 对于一个类的实例来说, 你可以看到它的成员函数、成员变量, 但是实例本身呢? this 是一个指针,它时时刻刻指向你这个实例本身 1. this 指针的用处: 一个对象的 this 指针并不是对象本身的一部分,不会影响 sizeof(对象)的结果。this 作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上 this 指针,编译器在编译的时候也是加上 this 的,它作为非静态成员函数的隐含形参,对各成员的访问均通过 this 进行。 例如,调用 date.SetMonth(9) <===> SetMonth(&date, 9),this 帮助完成了这一转换 2. this 指针的使用: 一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;另外一种情况是当参数与成员变量名相同时,如 this->n = n (不能写成 n = n)。3. this 指针程序示例: this 指针存在于类的成员函数中,指向被调用函数所在的类实例的地址。 根据以下程序来说明 this 指针 #include<iostream.h> class Point { int x, y; public: Point(int a, int b) { x=a; y=b;} void MovePoint( int a, int b){ x+=a; y+=b;} void print(){ cout<<"x="<<x<<"y="<<y<<endl;} }; void main( ) { Point point1( 10,10); point1.MovePoint(2,2); point1.print( ); } 当对象 point1 调用 MovePoint(2,2)函数时,即将 point1 对象的地址传递给了 this 指针。 MovePoint 函数的原型应该是 void MovePoint( Point *this, int a, int b);第一个参数是指向该类对象的一个指针,我们在定义成员函数时没看见是因为这个参数在类中是隐含的。这样 point1 的地址传递给了 this,所以在 MovePoint 函数中便显式的写成: void MovePoint(int a, int b) { this->x +=a; this-> y+= b;} 即可以知道,point1 调用该函数后,也就是 point1 的数据成员被调用并更新了值。 即该函数过程可写成 point1.x+= a; point1. y + = b;4. 关于 this 指针的一个经典回答: 当你进入一个房子后, 你可以看见桌子、椅子、地板等, 但是房子你是看不到全貌了。 对于一个类的实例来说, 你可以看到它的成员函数、成员变量, 但是实例本身呢? this 是一个指针,它时时刻刻指向你这个实例本身

‎Java/JVM/内存机制/内存分配.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ Java中常见的创建对象的方式有使用new关键字进行创建,也可
299299
[Tenured: 4096K->4244K(10240K), 0.0042901 secs]
300300
10474K->4244K(19456K), [Perm : 2104K->2104K(12288K)],
301301
0.0043613 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
302-
以MaxTenuringThreshold= true的参数设置来运行的结果:
302+
以MaxTenuringThreshold= true的参数设置来运行的结果:
303303
[GC [DefNew: 6651K->148K(9216K), 0.0054913 secs]
304304
6651K->4244K(19456K), 0.0055327 secs] [Times:
305305
user=0.00 sys=0.00, real=0.00 secs]

‎Java/JVM/内存机制/内存占用.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ static class A {
5656
```
5757
A对象占用内存情况:
5858

59-
关闭指针压缩: 16+4=20不是8的倍数,所以+padding/4=24
59+
关闭指针压缩: 16+4=20不是8的倍数,所以+padding/4=24
6060

6161
![img](http://ww2.sinaimg.cn/mw690/b254dc71jw1eoy9ymr5rgj20fe02adgc.jpg)
6262

63-
开启指针压缩: 12+4=16已经是8的倍数了,不需要再padding。
63+
开启指针压缩: 12+4=16已经是8的倍数了,不需要再padding。
6464

6565
![img](http://ww4.sinaimg.cn/mw690/b254dc71jw1eoy9yn3517j20fd02emxk.jpg)
6666
(2)Reference压缩
@@ -75,11 +75,11 @@ static class B2 {
7575
```
7676
B2对象占用内存情况:
7777

78-
关闭指针压缩: 16+4+8=28不是8的倍数,所以+padding/4=32
78+
关闭指针压缩: 16+4+8=28不是8的倍数,所以+padding/4=32
7979

8080
![img](http://ww4.sinaimg.cn/mw690/b254dc71jw1eoy9ynson6j20f703bmxu.jpg)
8181

82-
开启指针压缩: 12+4+4=20不是8的倍数,所以+padding/4=24
82+
开启指针压缩: 12+4+4=20不是8的倍数,所以+padding/4=24
8383

8484
![img](http://ww4.sinaimg.cn/mw690/b254dc71jw1eoy9yo7j86j20fi03gq3l.jpg)
8585

‎Java/JVM/类/类文件分析.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class SimpleClass {
5050
}
5151
```
5252

53-
运行下面的命令,就可以得到下面的结果输出: javap -v -p -s -sysinfo -constants classes/org/jvminternals/SimpleClass.class。
53+
运行下面的命令,就可以得到下面的结果输出: javap -v -p -s -sysinfo -constants classes/org/jvminternals/SimpleClass.class。
5454

5555
```
5656
public class org.jvminternals.SimpleClass

‎Java/基础/Maven/Maven 依赖管理详解与实践.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848

4949

5050
调停什么?谁会有冲突?是版本!同一个jar包,又会有不同的版本,因为总是在升级嘛。当你所依赖的jar有不同的版本的时候,该选择那一个呢?那位说了,就选最新的呗。好主意,毕竟大部门软件都向下兼容,但这也不一定哦。看看maven怎么做。maven选择最近的一个版本。什么意思?
51-
比如你的A项目:
51+
比如你的A项目:
5252
A -> B -> C -> D 2.0 and A -> E -> D 1.0,什么意思?A依赖B,。。。一直到依传递依赖到D2.0。同时A还依赖了E到一直到D1.0。这就出现了冲突,你当然也可以再A里面配置指定依赖D2.0。如果你没在A的pom里面配置指定用哪一个。maven会替你找一个近的。哪个近?当然是D1.0,那build A的时候就会选择D1.0。什么原因?这样就好吗?得好好想想?你有什么看法?
5353
有什么好想的?别这么纠结,就指定呗。说的容易,你想想很多时候你是不知道D的存在的,它很可能是个很底层的库,你只熟悉和你最近的项目B和E。
5454
# Excluded & Optional Dependencies(排除依赖于可选依赖)
@@ -89,7 +89,7 @@ A -> B -> C -> D 2.0 and A -> E -> D 1.0,什么意思?A依赖B,。。。
8989
```
9090
# Dependency Scope
9191
maven有三套classpath(编译classpath,运行classpath,测试classpath)分别对应构建的三个阶段。依赖范围就是控制依赖与这三套classpath的关系。依赖范围有六种:
92-
在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署。目前<scope>可以使用5个值:
92+
在POM 4中,<dependency>中还引入了<scope>,它主要管理依赖的部署。目前<scope>可以使用5个值:
9393
* compile,缺省值,适用于所有阶段,会随着项目一起发布。 compile 是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范围。编译范围依赖在所有的classpath 中可用,同时它们也会被打包。
9494
* provided,provided 依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如,如果你开发了一个web 应用,你可能在编译classpath 中需要可用的ServletAPI 来编译一个servlet,但是你不会想要在打包好的WAR中包含这个ServletAPI;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译classpath(不是运行时)可用。它们不是传递性的,也不会被打包。 * runtime, runtime 依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实现。
9595
* test,只在测试时使用,用于编译和运行测试代码。不会随项目发布。

‎Java/基础/Maven/Maven 工作流.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ resource节点是关键,它表明了哪个目录下的配置文件(不管是xm
221221

222222
各属性节点的值,用占位符"${属性名}"占位,maven在package时,会根据profile的环境自动替换这些占位符为实际属性值。
223223

224-
默认情况下:
224+
默认情况下:
225225

226226
`maven package`
227227

‎Java/基础/函数式编程/Lambda 与函数式接口.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# Lambda 与闭包
44

55
## Functional Interface: 函数式接口
6-
Java原本作为纯粹的面向对象的语言,需要对Lambda表达式特性进行支持,其实是基于了一种特殊的函数式接口。换言之,()->{}这样的语法本质上还是继承并且实现了一个接口。FI的定义其实很简单:任何接口,如果只包含 **唯一** 一个抽象方法,那么它就是一个FI。为了让编译器帮助我们确保一个接口满足FI的要求(也就是说有且仅有一个抽象方法),Java8提供了@FunctionalInterface注解。举个简单的例子,Runnable接口就是一个FI,下面是它的源代码:
6+
Java原本作为纯粹的面向对象的语言,需要对Lambda表达式特性进行支持,其实是基于了一种特殊的函数式接口。换言之,()->{}这样的语法本质上还是继承并且实现了一个接口。FI的定义其实很简单:任何接口,如果只包含 **唯一** 一个抽象方法,那么它就是一个FI。为了让编译器帮助我们确保一个接口满足FI的要求(也就是说有且仅有一个抽象方法),Java8提供了@FunctionalInterface注解。举个简单的例子,Runnable接口就是一个FI,下面是它的源代码:
77

88
``` java
99
@FunctionalInterface

‎Java/基础/基本类型/字符串.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Java中输入字符串是默认需要转义字符的
5353
星号的转义:* ==> u002A
5454
加号的转义:+ ==> u002B
5555
问号的转义:? ==> u003F
56-
反斜杠的转义: ==> u005C 
56+
反斜杠的转义: ==> u005C 
5757

5858

5959
譬如我们如果需要从System.in中输入"C:\",在Java中的字符串表示的是:"C:\\",而如果要用正则表达式匹配"\"这个字符的时候,正则表达式要写成"\\\\",即首先是根据Java语言本身的转义字符,转化为普通字符中的"\\",其就等价于正则表达式中匹配"\"这个字符。

‎Java/基础/基本类型/时间与日期处理.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ java# 获取当前时间为 Wed Mar 04 10:00:00 CST 2015, 意思就是2015年3
7474
转化为
7575
GMT时间为:04 Mar 2015 02:00:00 GMT,也就是说GMT时间加上 8 个小时等于CST表示的时间, 那这个CST不就是北京时间么,因为我们是在东八区的。
7676

77-
一切看起来很正常,不过在客户端用JavaScript解析这个时间就有问题了:
77+
一切看起来很正常,不过在客户端用JavaScript解析这个时间就有问题了:
7878
// Thu Mar 05 2015 16:00:00 GMT+0800
7979
var d=new Date('Wed Mar 04 10:00:00 CST 2015').toGMTString();
8080

0 commit comments

Comments
 (0)