0%

2018年5月4日 上午9:56

  1. 不可变对象
  2. 线程封闭
  3. 同步容器
    1. 通过加锁,最终将操作串行化—一次只允许一个线程进行访问
    2. 可行,但是效率不高
  4. 并发容器
    1. 也是通过加锁,但是这里的锁设计的更加好。
    2. 锁的设计上下功夫
    3. 并发容器中的分段锁

2018年5月4日 上午9:19

  1. 我一直想尝试把并发的知识有一个简单的认识,做个总结。

    1. 我们可以想象一下,为啥硬件和java的创造者要创建出线程不安全的情况
    2. 对于硬件来说,就像缓存的出现一样,他是被现实所打败
    3. 对于java语言来说,
      1. 整体上去看,他提供了各种底层的准则去保证一定的顺序性,但是远远是不够的,并不能保证并发的安全。
      2. 并且,他还设计出了类似指令重排,这样就会更加引起线程的不安全
      3. 他这么做的原因是在速度和线程安全的一种相互的博弈
      4. 为了弥补缺陷,他设计出个各种关键字让程序员自己实现线程安全,
      5. 同时他也提供了自己的一些线程安全和线程不安全的类,stringBuilder等,是因为线程安全会消耗一定的时间,这能让程序员更加灵活的选择。
  2. 首先提出了两个问题:

    1. 线程不安全的原因
    2. 如何让线程安全的方法 线程安全的策略
  3. 发现:三性(原子性、可见性、有序性)其实就是回答了这两个问题。下面我从java、硬件的设计者角度去尝试理解并解决这两个问题。


  4. 【JVM】:规定了线程基本的有序性规则,可以理解成java语言默认的东西。

  5. 【JMM】:规定了那些“最废话”的规则,是人的都知道的。

    1. 或者换种说法:JMM就是为了规定哪些最废话的规则而产生的
    2. 他定义的是一个基本的框架,这个框架本身就有很多的不足
    3. JMM管理JVM和内存之间的协同工作方式
    4. 本地内存的理解很关键:
      1. 是针对每个线程的
      2. 是抽象的概念,可以理解成主内存之外各种小的内存都可称之某个线程的本地内存
      3. 作用:其实就是主内存数据的副本
  6. 【 硬件】:

    1. cpu缓存局部性原理
    2. 缓存一致性原理:MESI
      1. 理解:因为要解决cpu和内存速度不匹配的问题,引入缓存之后而带来的本来内存中的一份数据 ,现在变成了多份,因为缓存中会出现对内存数据的拷贝和加工
      2. 这时候就需要一个准则来表明各个数据的状态,那么我们就可以根据数据的状态进行判断和处理,区分、处理各种情况

2018年5月4日 下午4:18

前提:

1
2
3
4
5
6
7
8
localhost:~ czh$ webpack -v
2.6.1

localhost:~ czh$ node -v
v4.4.7

localhost:Front-end czh$ webpack -v
webpack 1.15.0

安装过程:

1
sudo rm -rf /usr/local/{bin/{node,npm},lib/node_modules/npm,lib/node,share/man/*/node.*}
1
2
localhost:Front-end czh$ node -v
v4.9.1
1
2
localhost:Front-end czh$ webpack -v
webpack 1.15.0

npm init

1
localhost:Front-end czh$ npm install css-loader style-loader --save-dev

注:这里只要不报err就行,WARN不用管它。解决的方式就是像下面一样指定版本号。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
npm install file-loader@0.11.1 --save-dev

npm install html-loader@0.4.5 --save-dev

npm install url-loader@0.5.8 --save-dev

npm uninstall style-loader --save-dev

npm install style-loader@0.17.0 --save-dev

npm install css-loader@0.28.1 --save-dev

npm install extract-text-webpack-plugin@1.0.1 --save-dev

npm install html-webpack-plugin@2.28.0 --save-dev

npm install webpack-dev-server@1.16.5 --save-dev

这里不报错的关键是:指定版本号

1
2
3
4
5
npm install hogan@1.0.2 --save

npm install font-awesome@4.7.0 --save

npm install hogan.js@3.0.2 --save
1
2
3
4
5
6
"scripts": {
"dev": "WEBPACK_ENV=dev webpack-dev-server --inline --port 8088",
"dev_win": "set WEBPACK_ENV=dev && webpack-dev-server --inline --port 8088",
"dist": "WEBPACK_ENV=online webpack -p",
"dist_win": "set WEBPACK_ENV=online && webpack -p"
},

2018年5月4日 下午4:01

  1. 这里是通过webpack.config.js,这个文件来管理webpack的如何工作的。
  2. 而不是使用webpack原始的webpack 待处理文件名 处理完后的文件名









2018年5月4日 下午3:49

init过程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
localhost:Front-end czh$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
name: (Front-end)
Sorry, name can no longer contain capital letters.
name: (Front-end) front-end
version: (1.0.0)
description: programing前端代码
entry point: (index.js)
test command:
git repository: (https://github.com/czh55/Front-end.git)
keywords:
author: czh
license: (ISC)
About to write to /Users/czh/front-end/Front-end/package.json:

{
"name": "front-end",
"version": "1.0.0",
"description": "programing前端代码",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/czh55/Front-end.git"
},
"author": "czh",
"license": "ISC",
"bugs": {
"url": "https://github.com/czh55/Front-end/issues"
},
"homepage": "https://github.com/czh55/Front-end#readme"
}


Is this ok? (yes)

安装webpack过程

  1. 全局安装webpack
    1. npm install webpack -g
  2. 生产环境安装webpack
    1. npm install webpack@1.15.0 --save-dev
  3. 报错

解决报错问题

  1. 全局安装的webpack默认安装版本是4.6.0,版本太高,要卸载
  2. 我们要指定全局安装为2.6.1
  3. 参考安装webpack后,执行webpack -v命令时报错:SyntaxError: Block-sc-zero-51CTO博客
  4. npm uninstall webpack -g
  5. npm install webpack@2.6.1 -g --registry=https://registry.npm.taobao.org
  6. webpack -v

最后的结果

2018年5月2日 下午3:54
House Robber - LeetCode

从这道题可以看出动态规划也是可以用遍历去解释的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
int rob(vector<int>& nums) {
if(nums.size() == 0) return 0;
std::vector<int> dp(nums.size()+1, 0);

dp[0] = nums[0];
dp[1] = nums[1] > nums[0] ? nums[1]:nums[0];
//这里的遍历对象是:0~1 0~2 0~3 0~4 .... 0~(n-1)
//这里的数字是只下标!
for(int i = 2; i < nums.size(); i++){
dp[i] = max((dp[i-2]+nums[i]), dp[i-1]);
}

return dp[nums.size()-1];
}
};

2018年5月2日 下午3:54
Coin Change - LeetCode

  1. 现在特殊情况是面值只有2。那么如果我们要求dp[1],一元面值对应的张数,我们应该怎么给dp[1]赋值。那么对应的dp[3]用2,又应该怎么复制,这是最不可到达的。一种问题的第一个问题。
  2. 第二个问题,假如我们有两种处理方法,第一种是把它设成无限大。然后。这才这样的好处是我们使用递推公式的时候。因为递推公式要求最小值,那么我们就可以直接把这个最大值过滤掉,但是这个最大值不一定特别保险。这是他的缺点和他优点。然后第二个办法就是把它设成-1表示不可达。
  3. 现在我们考虑第二种情况,就是把这个不可达的值表示为-1,就比如说dp[3]等于-1表示dp[3]可达。那么。当dp[3]入到递推公式,求最小值之后一定就求出来就是-1。所以我们会对递推公式产生影响。
  4. 面对这个问题,我们解决方法是将递推公式拆开变成一个循环。
  5. 在每次循环中遍历各个面值,然后把一个递推公式多次执行,也就多次给dp[i]进行赋值。
  6. 在这个过程中要比大小,最终取出的跟直接求最小值递推公式是一样的。
  7. 下一个问题是你如何,何时给这个不可达设置-1的值。
  8. 我当初的想法是。找见不可到达和可到达之间的区分点。就比如说用判断啊什么的区分开。就是上面写if,下面是else句分别去执行。
  9. 老师的方法是一开始就将所有的面值对应的数量设置为-1,全部识别不可达的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public:
//这道题就是特殊情况比较难考虑:
int coinChange(vector<int>& coins, int amount) {
//初始化dp数组,初始值为-1
std::vector<int> dp(coins.size()+1, -1);

//金额0,最优解为0
dp[0] = 0;
for(int i = 0; i <= amount; i++){
//循环遍历各个面值,找到dp[i]最优解
for(int j = 0; j < coins.size(); j++){
//i-coins[j]>=0:特殊情况面值只有2,我们要给1元赋值
//dp[i-coins[j]]!=-1:如果前面的面值是不可到达的,那么我们不能使用它进行更新dp[i]
if(i-coins[j]>=0 && dp[i-coins[j]]!=-1){
//dp[i] == -1:是dp[i]的首次赋值,dp[i] > dp[i-coins[j]] + 1:是dp[i]的寻找最优解的过程
if(dp[i] == -1 || dp[i] > dp[i-coins[j]] + 1){
dp[i] = dp[i-coins[j]] + 1;
}
}
}
}
return dp[amount];
}
};