sheerLi

一位只会cv的前端码农


  • 首页

  • 标签

  • 分类

  • 归档

显示器科普推荐

发表于 2022-07-13

本文会记录一些显示器的常规参数含义,以及个人对显示器购买的建议。(持续更新)

面板

显示器面板有 IPS、TN、VA 三种类型。

  • IPS屏: 面板较硬,用手指轻触屏幕,画面不会变形。IPS屏在色彩显示、可视角度等方面比TN面板好上不少,对于色彩的呈现范围与准确性也都有亮眼的表现,广视角是IPS面板的原生优势,不论哪个角度观看都不会产生色偏。但在响应时间上IPS屏比TN屏稍逊一筹,但得益于IPS屏出色的色彩表现,对于兼有办公娱乐多功能需求的普通游戏玩家,IPS屏仍然值得考虑。受制于IPS屏需要更多背光灯来提高亮度,功耗偏高的局限性,控制不好就会漏光是IPS屏的通病。不过专业的屏幕生产厂商在应对这个问题时通常有更规范的把控机制,更值得信赖。
  • TN屏: 就是较早前常见的软屏,用手能按出水波纹,这是较早使用的LCD面板之一,目前也在大量使用,因为它的技术成熟,成本低。TN屏响应速度快,可以达到1ms的响应时间,不会出现残影。使用这种材质的屏幕通常用来作为职业电竞屏,通过快速响应,TN屏可无损呈现高速变化的场景细节。相对地,TN面板的缺陷也很明显,输出灰阶少,原生只有6bit色彩,画面色彩偏白、可视角度小,显示效果一般,通过不同角度观看会出现偏色和亮度差别。
  • VA屏: VA类面板也属于软屏,只要用手指轻触面板,显现梅花纹的是VA面板,出现水波纹的则是TN面板。VA屏的特点是宽容度和对比度都更高,可达到3000:1的高对比度,画面中黑色和白色都更加纯净,且不会出现漏光等问题。VA面板的缺陷主要体现在响应时间方面,好在现在VA面板的响应时间已经大幅改善,可以低至6ms内,足够正常使用。

面板选购建议

普通办公:IPS、VA
游戏玩家:IPS>VA>TN

分辨率/尺寸

  • 分辨率 目前主流的有1080P、2K、4K。分辨率越高画面就越细腻。
  • 屏幕尺寸 有23.8-34寸,甚至更大。大屏幕最好选择2k/4k的分辨率,因为屏幕大而分辨率低的话会出现字体发虚、叠影等问题(本人踩过坑)

23寸选择:1080P
27寸选择:2K>1080P
34寸选择:4K>2K

刷新率

指的是每秒刷新画面的次数,刷新率越高,画面的稳定性越好。一般常见的是60~80Hz、144Hz、244Hz。办公+看视频用的话,60Hz也够了。

输入接口

老款显示屏都是VGA为主,现在新款的显示器是HDMI和DP。

显示器

本人目前也只使用过1000~1500左右的显示器,就推荐几款个人觉得还不错的千元显示器吧

1000元左右

明基BL2480T

  • 特性:内置音响、旋转升降底座、TUV爱眼认证、四边微边框
  • 尺寸/分辨率:23.5~24寸/1080p
  • 刷新率:60Hz
  • 面板:IPS
  • 使用感受:目前个人家用办公娱乐使用,用了大概两年多,感觉足以满足日常写代码、看文档、看视频之类的需求。
  • 京东链接:https://item.jd.com/8358211.html

戴尔P2422H

  • 特性:旋转升降底座
  • 尺寸/分辨率:23.5~24寸/1080p
  • 刷新率:60Hz
  • 面板:IPS
  • 使用感受:上一家公司配的戴尔的差不多型号的电脑,能满足日常写代码、看文档、看视频之类的需求,就是特性不多,感觉戴尔的牌子有点溢价。
  • 京东链接:https://item.jd.com/1604149839.html

飞利浦275S9DRL

  • 特性:旋转升降底座
  • 尺寸/分辨率:27寸/2k
  • 刷新率:75Hz
  • 面板:VA
  • 使用感受:没用过,看参数感觉可以,颜值也好看,性价比也ok。
  • 京东链接:https://item.jd.com/1604149839.html

优派(ViewSonic)VX2780-2K-HD

  • 特性:节能认证,旋转升降底座
  • 尺寸/分辨率:27寸/2k
  • 刷新率:60Hz
  • 面板:IPS
  • 使用感受:目前公司在用的,能满足日常写代码、看文档、看视频之类的需求,2k屏相比1080p文字细腻度更好点,其他也没有太多特性,中规中矩吧。
  • 京东链接:https://item.jd.com/100010568866.html

总结

  • 大屏幕(例如27寸)就选择2k或4k分辨率,小屏幕24寸左右,就选择1080p
  • 旋转可升降的特性个人认为对于办公党来说比较重要,方便调节到一个让颈椎比较舒适的位置,不然底部只能垫书了。其次关注有无 TUV爱眼认证,关系到长时间看屏幕会不会眼睛发酸。

基本排序的方式

发表于 2019-05-01 | 分类于 JavaScript

以下是 js 实现常用的基本排序,包括 快速排序、冒泡排序、堆排序、桶排序、插入排序、归并排序.

快速排序

排序过程只需要三步:
(1)在数据集之中,选择一个元素作为”基准”(pivot)。
(2)所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。
(3)对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function quickSort(array) {
if( arr.length <= 1 ) {
return arr;
}
// 找出数组中的基准值
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
// 定义左右两个个空数组
var left = [], right = [];
for(var i=0, len = arr.length; i < len; i++){
if(arr[i] < pivot) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
// 递归调用快排
return quickSort(left).concat([pivot], quickSort(right));
}

冒泡排序

数组中有 n 个数,比较每相邻两个数,如果前者大于后者,就把两个数交换位置;
这样一来,第一轮就可以选出一个最大的数放在最后面;
那么经过 n-1(数组的 length - 1) 轮,就完成了所有数的排序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function bubbleSort(arr){
for(var i = 0; i < arr.length - 1; i++){
// 声明一个变量,作为标志位
var done = true;
for(var j = 0; j < arr.length-1-i; j++){
if(arr[j] > arr[j+1]){
var smtp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = smtp;
// 若有交换过,标志位置为 false
done = false;
}
}
// 可以减少不必要的排序,提高性能
if(done){
break;
}
}
return arr;
}

插入排序

1.从第一个元素开始,该元素可以认为已经被排序;
2.取出下一个元素,在已经排序的元素序列中从后向前扫描;
3.如果该元素(已排序)大于新元素,将该元素移到下一位置;
4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
5.将新元素插入到该位置后;
重复步骤2~5。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function insertionSort(array) {
if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') {
for (var i = 1; i < array.length; i++) {
var key = array[i];
var j = i - 1;
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
return array;
} else {
return 'array is not an Array!';
}
}

选择排序

初始状态:无序区为R[1..n],有序区为空;
第i趟排序(i=1,2,3…n-1)开始时,当前有序区和无序区分别为R[1..i-1]和R(i..n)。该趟排序从当前无序区中选出关键字最 小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n)分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
n-1趟结束,数组有序化了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function selectionSort(array) {
if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') {
var len = array.length, temp;
for (var i = 0; i < len - 1; i++) {
var min = array[i];
for (var j = i + 1; j < len; j++) {
if (array[j] < min) {
temp = min;
min = array[j];
array[j] = temp;
}
}
array[i] = min;
}
return array;
} else {
return 'array is not an Array!';
}
}

桶排序

设置一个定量的数组当作空桶;
遍历输入数据,并且把数据一个一个放到对应的桶里去;
对每个不是空的桶进行排序;
从不是空的桶里把排好序的数据拼接起来。

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
/*方法说明:桶排序
@param array 数组
@param num 桶的数量*/
function bucketSort(array, num) {
if (array.length <= 1) {
return array;
}
var len = array.length, buckets = [], result = [], min = max = array[0], regex = '/^[1-9]+[0-9]*$/', space, n = 0;
num = num || ((num > 1 && regex.test(num)) ? num : 10);
for (var i = 1; i < len; i++) {
min = min <= array[i] ? min : array[i];
max = max >= array[i] ? max : array[i];
}
space = (max - min + 1) / num;
for (var j = 0; j < len; j++) {
var index = Math.floor((array[j] - min) / space);
if (buckets[index]) { // 非空桶,插入排序
var k = buckets[index].length - 1;
while (k >= 0 && buckets[index][k] > array[j]) {
buckets[index][k + 1] = buckets[index][k];
k--;
}
buckets[index][k + 1] = array[j];
} else { //空桶,初始化
buckets[index] = [];
buckets[index].push(array[j]);
}
}
while (n < num) {
result = result.concat(buckets[n]);
n++;
}
return result;
}

归并排序

把长度为n的输入序列分成两个长度为n/2的子序列;
对这两个子序列分别采用归并排序;
将两个排序好的子序列合并成一个最终的排序序列。

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
function mergeSort(array, p, r) {
if (p < r) {
var q = Math.floor((p + r) / 2);
mergeSort(array, p, q);
mergeSort(array, q + 1, r);
merge(array, p, q, r);
}
}
function merge(array, p, q, r) {
var n1 = q - p + 1, n2 = r - q, left = [], right = [], m = n = 0;
for (var i = 0; i < n1; i++) {
left[i] = array[p + i];
}
for (var j = 0; j < n2; j++) {
right[j] = array[q + 1 + j];
}
left[n1] = right[n2] = Number.MAX_VALUE;
for (var k = p; k <= r; k++) {
if (left[m] <= right[n]) {
array[k] = left[m];
m++;
} else {
array[k] = right[n];
n++;
}
}
}

堆排序

将初始待排序关键字序列(R1,R2….Rn)构建成大顶堆,此堆为初始的无序区;
将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,……Rn-1)和新的有序区(Rn),且满足R[1,2…n-1]<=R[n];
由于交换后新的堆顶R[1]可能违反堆的性质,因此需要对当前无序区(R1,R2,……Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2….Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*方法说明:堆排序
@param array 待排序数组*/
function heapSort(array) {
if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') {
//建堆
var heapSize = array.length, temp;
for (var i = Math.floor(heapSize / 2); i >= 0; i--) {
heapify(array, i, heapSize);
}

//堆排序
for (var j = heapSize - 1; j >= 1; j--) {
temp = array[0];
array[0] = array[j];
array[j] = temp;
heapify(array, 0, --heapSize);
}
} else {
return 'array is not an Array!';
}
}
/*方法说明:维护堆的性质
@param arr 数组
@param x 数组下标
@param len 堆大小*/
function heapify(arr, x, len) {
if (Object.prototype.toString.call(arr).slice(8, -1) === 'Array' && typeof x === 'number') {
var l = 2 * x, r = 2 * x + 1, largest = x, temp;
if (l < len && arr[l] > arr[largest]) {
largest = l;
}
if (r < len && arr[r] > arr[largest]) {
largest = r;
}
if (largest != x) {
temp = arr[x];
arr[x] = arr[largest];
arr[largest] = temp;
heapify(arr, largest, len);
}
} else {
return 'arr is not an Array or x is not a number!';
}
}

前端实现文件的下载和上传

发表于 2019-04-06 | 分类于 JavaScript

前言

最近项目中遇到文件的上传和下载,这部分的知识之前也是比较陌生的,借此机会熟悉了这方面的知识。对此做一个简单的总结。

文件下载

前端实现文件下载的方式主要是 3 种 window.open()、 form表单 、a标签

方式1 通过 window.open()

1
2
3
4
function windowOpen(){
// window.open('./static/thumb3.jpg')
window.open('./static/wendang.doc')
}

具体表现

img: 打开新网页,显示图片

word文档:下载该文件

方式2 通过 form表单提交

1
2
3
4
5
6
7
8
9
10
function formDownload(){
var form = document.createElement('form')
form.method = 'get'
form.style.display = 'none'
// form.action = './static/thumb3.jpg'
form.action = './static/wendang.doc'
document.body.appendChild(form)
form.submit()
document.body.removeChild(form)
}

具体表现

img: form 未设置 target 则在当前 url 显示图片

word文档:下载该文件

注:以上两种方式若请求的 url 对应的是 img、txt 等格式时,浏览器直接打开相应的文件,而不是下载

方式3 通过 a标签

1
2
3
4
5
6
7
function aDownload(){
var a = document.createElement('a')
// a.href = './static/wendang.doc'
a.href = './static/thumb3.jpg'
a.download = 'thumb'
a.click()
}

具体表现

未设置 download 属性,和上面两种表现形式一样
设置了 download 属性,图片也是会下载的

文件上传

我在项目中使用的是 type=”file” 的 input 标签,然后使用 formData 传输数据。
示例代码如下:

html 部分

1
2
3
4
5
6
7
8
9
<form class="layui-form" action="" id="formload">
<div class="layui-form-item">
<label class="layui-form-label">文件</label>
<div class="layui-input-block">
<input type="file" name="file" id="file" required lay-verify="required"
autocomplete="off">
</div>
</div>
</form>

js 部分 文件上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var formData = new FormData($('#formload')[0])
$.ajax({
url: api + '/web/file/uploadFile',
type: 'post',
cache: false,
data: formData,
processData: false,
contentType: false,
error: function(){
// 失败回调
},
success: function(res){
// 成功回调
}
})

文件对象的属性:lastModified、type、name 和 size,可根据需求自定义检查文档格式

文件对象 file 可通过 elem.files[0] 或者 elem.files.items[0] 获得。
其中 elem 为 type=”file” 的 input 对象

检查文档的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function checkoutFile(file){
const accept = ['.doc', '.docx']
const index = file.name.lastIndexOf('.')
const flag = true
// 文件格式不支持
if(index < 0 || accept.indexOf(file.name.substr(index).toLowerCase() < 0) {
flag = false
}
// 文件太大
if(file.size > 2 * 1024 * 1024) {
flag = false
}
return true
}

总结

前面提到的 下载 给定的都是文件地址,但项目中往往为了安全,后台返回的是 文件流。

针对这种情况:

之前的 form表单提交方式同样适用(我在项目中用过)
这种方式有一个缺点,拿不到后端处理这个过程的时机,无法根据回调函数做交互以及进度提示

还有一个是 html5 提供的新方式 借助 blob 实现文本信息的下载。感兴趣的可自行查阅

聊一聊 cookie

发表于 2019-04-05 | 分类于 JavaScript

说明

最近在项目中遇到 请求后台接口时的身份验证 问题,需要使用 cookie 存储用户登录信息,便于每次在请求后台接口时,带上 cookie 达到身份的校验。借此机会,恶补了一下 cookie 方面的知识

cookie 的工作方式

cookie 是浏览器提供的功能,它其实是存储在浏览器中的纯文本,浏览器的安装目录下会专门有一个 cookie 文件夹来存放各个域下的设置的 cookie

每当发送请求时,浏览器会自动检查是否有相应的 cookie, 有则添加到 request header 中的 cookie 字段中。

由于 cookie 存放的数据每次都会放到 http 请求头中,如果其中的数据没有必要发送给服务器,无疑增加了网络开销;但是这些数据每个请求到需要发送给服务器,那么免去了重复添加请求参数的操作。所以每个请求都需要携带的数据特别适合存放在 cookie 中(例如身份认证)

cookie 的格式

JS 原生的方法 document.cookie 能够获取到 cookie 。获取到的是一个字符串,这个字符串是有格式的, 由键值对 key=value 构成, 键值对之间有一个 分号 和一个 空格 隔开

cookie 的属性

expires

expires: 用来设置 cookie什么时间内有效。expires 是 cookie 的失效时间, 格式必须是 GMT 格式的时间(可以通过 new Date().toGMTString() 或者 new Date().toUTCString() 来获得)
如 expires=Thu, 25 Feb 2016 04:18:00 GMT 表示 cookie 将 在2016年2月25日4:18分之后失效,对于失效的cookie 浏览器会清空。如果没有设置该选项,则默认有效期为session,即会话 cookie。这种cookie在浏览器关闭后就没有了。

domain 和 path

domain: 是域名 若未设置,默认为 设置该cookie的网页所在的域名
path: 是路径 若未设置,默认为 设置该cookie的网页所在的目录
两者加起来限制 cookie 能够被哪些URL访问

secure

用来设置cookie只在确保安全的请求中才会发送。当请求是HTTPS或者其他安全协议时,包含 secure 选项的 cookie 才能被发送至服务器。
默认 secure 为空,所以默认按情况下,不管是 https 还是 http 请求, cookie 都能被发送到服务端
注:在http协议的网页中是无法设置secure类型cookie的。

httpOnly

这个选项用来设置cookie是否能通过 js 去访问
默认 httpOnly 为空,所以默认情况下 js 可以访问(读取、修改、删除)这个cookie 的
这种类型的 cookie 只能通过 服务端来设置
这个选项是 限制客户端去访问cookie 保障安全

如何设置 cookie

服务端设置 cookie

无论是请求资源文件还是发送一个 ajax 请求,服务端都会返回response。而response-header中有一个叫做 set-cookie,是服务端专门用来设置 cookie 的。

注意:

一个set-Cookie字段只能设置一个cookie,当你要想设置多个 cookie,需要添加同样多的set-Cookie字段
服务端可以设置cookie 的所有选项:expires、domain、path、secure、HttpOnly

客户端设置 cookie

通过 js 来设置 cookie

1
2
document.cookie = "name=jack; ";
document.cookie = "age=12; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=baidu.com; path=/";

下面的写法 无法创建多个 cookie ,只是添加了 “name=jack”,若是想添加多个 cookie 那么需要重复执行document.cookie = “key=name”。如上面所示

1
document.cookie = "name=jack; age=12; ";

如何修改、删除

修改 cookie

要想修改一个cookie,只需要重新赋值就行,旧的值会被新的值覆盖。但要注意一点,在设置新cookie时,path/domain这几个选项一定要旧cookie 保持一样。否则不会修改旧值,而是添加了一个新的 cookie。

删除 cookie

删除一个cookie 也挺简单,也是重新赋值,只要将这个新cookie的expires 选项设置为一个过去的时间点就行了。但同样要注意,path/domain/这几个选项一定要旧 cookie 保持一样。

跨域请求中的 cookie

在发同域请求时,浏览器会将cookie自动加在request header中。但大家是否遇到过这样的场景:在发送跨域请求时,cookie并没有自动加在request header中。

解决办法:

在跨域请求中,client端必须手动设置xhr.withCredentials=true,且server端也必须允许request能携带认证信息(即response header中包含Access-Control-Allow-Credentials:true),这样浏览器才会自动将cookie加在request header中。

注意: 一旦跨域request能够携带认证信息,server端一定不能将Access-Control-Allow-Origin设置为*,而必须设置为请求页面的域名。

cookie、sessionStorage、localStorage的区别

发表于 2019-04-05 | 分类于 JavaScript

基本概念

cookie

cookie 是小甜饼的意思。顾名思义,cookie 确实非常小,它的大小限制为4KB左右,是网景公司的前雇员 Lou Montulli 在1993年3月的发明。它的主要用途有保存登录信息,比如你登录某个网站市场可以看到“记住密码”,这通常就是通过在 cookie 中存入一段辨别用户身份的数据来实现的。

数据的生命周期: 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效
存放数据的大小: 4k 左右
与服务器端通信: 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
易用性:需要程序员自己封装,源生的Cookie接口不友好

sessionStorage

sessionStorage 将一部分数据在当前会话中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就会被清空。

数据的生命周期: 仅在当前会话下有效,关闭页面或浏览器后被清除
存放数据的大小: 一般为5MB
与服务器端通信: 仅在客户端(即浏览器)中保存,不参与和服务器的通信
易用性:源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

localStorage

localStorage 是 HTML5 标准中新加入的技术,它并不是什么划时代的新东西。早在 IE 6 时代,就有一个叫 userData 的东西用于本地存储,而当时考虑到浏览器兼容性,更通用的方案是使用 Flash。而如今,localStorage 被大多数浏览器所支持,如果你的网站需要支持 IE6+,那以 userData 作为你的 polyfill 的方案是种不错的选择。

数据的生命周期: 除非被清除,否则永久保存
存放数据的大小: 一般为5MB
与服务器端通信: 仅在客户端(即浏览器)中保存,不参与和服务器的通信
易用性:源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

应用场景

cookie: 每个 HTTP 请求都会带着 cookie 的信息,所以 cookie 当然是能精简就精简啦,比较常用的一个应用场景就是判断用户是否登录
sessionStorage: 如果遇到一些内容特别多的表单,为了优化用户体验,我们可能要把表单页面拆分成多个子页面,然后按步骤引导用户填写
localStorage: 保存用户在电商网站的购物车信息、存储一些 HTML5 游戏产生的本地数据

安全性的考虑

需要注意的是,不是什么数据都适合放在 Cookie、localStorage 和 sessionStorage 中的。使用它们的时候,需要时刻注意是否有代码存在 XSS 注入的风险。因为只要打开控制台,你就随意修改它们的值,也就是说如果你的网站中有 XSS 的风险,它们就能对你的 localStorage 肆意妄为。所以千万不要用它们存储你系统中的敏感数据。

初识 hadoop

发表于 2019-03-10 | 分类于 大数据

Google的三篇论文

Google FS (Google File System)

1.可扩展的分布式文件系统,用于大型的、分布式的、对大量数据进行访问的应用
2.对海量数据进程存储
3.后人根据此论文开发出 HDFS

本质: 文件被分割成很多块,使用冗余的方式(备份)储存于商用机器集群上。

MapReduce

大数据的分布式计算方式,主要思想是将任务分解然后在多台处理能力较弱的计算节点中同时处理,然后将结果合并从而完成大数据处理。
后人根据此论文开发出 MapReduce

BigTable

十几亿行,百万列的数据库
演变成后来的 Hbase

相关概念

分布式

相对于集中式
集中式:一台机器,将所有的东西(软件)放在一台机器上(安装)
分布式:多台机器,将东西进行划分,每台机器存储一部分

主从架构:
主节点:只有一个(管理者,调度)
从节点:多个(被管理者,干活的)

hadoop 模块

附上一张官网 hadoop 模块图

common

公共模块,工具,为其他模式提供支撑的。

HDFS (Hadoop Distributed File System)

功能: 存储数据
主节点: namenode 决定数据存储到哪个 datanode
从节点: datanode 真正存储数据的

YARN

分布式集群资源管理和任务调度
管理着整个集群的资源(内存、CPU)
主节点: resourceManager 管理整个集群资源的
从节点: nodeManager 管理当前机器资源

MapReduce

1.并行数据处理框架
2.分而治之思想:将海量的数据划分为多块,每块数据进行单独处理,最终将结果进行合并。
3.map: map task
  单独处理每一部分数据 各个Map Task是并行的,各跑各的,在不同的机器里面
4.reduce: reduce task
  合并所有的Map Task 结果

总结:
HDFS: namenode/datanode
YARN: resoureManager/nodemanager
都属于Java进程,启动JVM进程,运行服务

学习大数据的前期准备工作(三)

发表于 2019-03-07 | 分类于 大数据

本篇文章主要是讲 linux 命令下载并安装 jdk 和 mysql,为后面的大数据做准备

Linux 软件安装命令

rpm

安装 rpm 结尾的软件包
软件查询: rpm –qa: 列举所有当前安装rpm包
安装软件: rpm – ivh XXX.rpm
问题: A <-B <-C 需要自己手动解决依赖
卸载: rpm -e –nodeps XXXXX

yum

通过软件源进行安装,类似 软件软件 点击“安装”
查看所有yum支持的包:yum list
查看当前已经安装的包:yum list installed
卸载:yum remove XX
安装:yum install –y zip

绿色版本

绝大部分都是解压直接能用

Linux 虚拟机安装 jdk 并 配置环境变量

步骤 1
将 jdk 的包通过 远程控制工具 SearchSRC 上传到 Linux 虚拟机中

步骤 2
使用 tar –zxvf jdk-8u91-linux-x64.tar.gz -C ./ 解压到当前文件夹

查看 test 文件夹

步骤 3
sudo vi /etc/profile 配置环境变量

保存退出后 source /etc/profile 使其生效

安装 mysql

步骤 1
检查是否已经安装 mysql
命令: rpm -qa | grep mysql

卸载依赖
命令:sudo rpm -e –nodeps mysql-libs-5.1.66-2.el6_3.x86_64

安装mysql
命令:sudo yum install -y mysql-server

启动 mysql 服务
命令: sudo service mysqld start

修改 mysql 密码为 123456
命令:/usr/bin/mysqladmin -u root password ‘123456’

登录 mysql
命令:mysql -u root -p123456

展示数据库
命令:show databases

设置开机启动

经过以上步骤,jdk 和 mysql 都安装完成!

学习大数据的前期准备工作(二)

发表于 2019-03-06 | 分类于 大数据

Linux 常用命令

命令通用格式 : 命令 选项(参数) 操作的文件或者目录

普通命令

ls
格式:ls 目录
参数: a : 列举包含隐藏文件
l : 使用长格式查看 ls -l 等同于 ll

cd
改变目录

pwd
打印当前所在目录

clear
清屏 等同于 ctrl + l

history
查看命令的历史记录

文件操作命令

创建

创建文件
touch a.txt

创建一个空目录
mkdir dir1

递归创建一个非空目录
mkdir -p dir2/dir3

删除

删除文件
rm a.txt
-f 参数 命令是免确认

删除目录(只能删空目录)
rm -rf mkdir2

编辑

vi / vim

复制

复制文件
cp a.txt dir1/

复制目录
cp -r dir1 dir2/

移动

将 a.txt 文件移动到 dir2 目录
mv a.txt dir2

查看

more
分页查看 显示一屏数据,按“enter”往下翻页

less
分页查看 显示一屏数据,按方向上下键翻页 按“q”退出预览

head
查看文件头部内容,默认读取文件前10行
常用参数:**-n**: 查看行数

tail
查看文件尾部内容,默认读取文件后10行
常用参数:
-n:查看行数
-F:动态查看,监听一个文件的变化

用户管理

管理员

用户 id 是 0

普通用户

用户 id 从 500 开始,可以自己创建普通用户

用户信息文件

more /etc/passwd

标红意思
用户名:密码:uid:gid:所属组的名字:家目录:所用shell

用户组信息文件

more /etc/group

切换用户

切换到管理员

su -

切换到普通用户

su -用户名

退出

exit

创建用户

格式:useradd username
例: useradd LW

查看用户

格式:id username
例: id LW

设置密码

格式:passwd username
例: passwd LW

删除用户

格式:userdel username
参数:-r 既删除用户又删除该用户的家
例: userdel LW

权限管理

用户分类

所有者: u
同组用户: g
其他人: o

权限分类

读: r
写: w
执行: x
没有权限: -

文件权限详情

第一位:文件类型,d:目录,**-**:文件
剩下9位,3位一组
rwx:所有者拥有的 读 写 执行 权限
rwx:同组用户拥有的 读 写 执行 权限
r-x:其他人拥有的 读 执行 权限
huadian huadian:所有者 所属组
4096:文件大小
Mar 6 09:14: 日期
b: 文件名

修改权限

语法: Chmod [添加或者删除权限] 文件或者目录

通过字符修改

给其他人添加 写的 权限

给其他人删除 写的 权限

给任何人都添加上 可执行 权限

给所属者和同组用户删除权限

通过数组修改

说明
该位有权限用 1 表示,没有用 0 表示
rwx 111 => 7(十进制)
r-x 101 => 5(十进制)
rw- 110 => 6(十进制)

例子:让 任何用户 拥有 全部权限
例子:chmod 777 a.txt

例子:让 任何用户 拥有 读写 没有 执行 的权限
例子:chmod 666 a.txt

修改文件 所有者 和 所属组

语法格式:chown username:groupname 文件或者目录
参数: -R 递归修改所有的文件
例:chown -R root:root b

常见符号

.

表示当前目录

.

表示上一级目录

~

用户的家目录
例如: cd ~

|

表示管道符
例如:Ps –ef | grep java 过滤留下java的进程

>

覆盖重写某个文件

>>

追加到某个文件

文本编辑 vi / vim

语法格式

 vi 文件名
如果编辑一个不存在的文件,默认会创建一个文件

种模式

命令行模式

gg:跳转到第一行
G:跳转到最后一行
5gg:跳转到第5行
yy:复制当前行
p:在当前位置粘贴
dd:删除光标所在行
5dd:从当行开始,删除连续5行
99999999999999dd: 清除文档
u:撤销上一步
i:进入插入模式
o:在光标所在行 下一行 进入插入模式
O:在光标所在乎 前一行进入插入模式

插入模式

在命令模式下,输入“i”,进入插入模式

最后行模式

进入方式:
按下“ESC”进入命令模式
按下shift + : 进入最后行模式

命令:
wq:保存退出
q: 不保存退出
!: 强制
q!: 强制退出
set nu(number): 显示行号
/string 检索字符串 按“n”找下一个

常用工具命令

visudo (较重要)

在企业中,通常不会使用root,为了安全,一般使用普通用户。
普通用户有时候,也需要操作一些管理员需要的权限

例:让 huadian 用户拥有 root 所有权限 操作如下
切换到 root 用户
执行 visudo 命令
添加如下配置

普通用户如果使用额外赋予的权限
sudo 额外权限名

man

帮助命令
例: man ls

wc

文本统计工具
例: wc a.txt
结果:行 单词书 字符数 文件名

du

文件大小统计
du -a.txt/

系统管理命令

关机

shutdown -h now
halt
init 0

开机选项配置

Vi /etc/inittab
id:3:initdefault: 启动linux,不启动图形化界面
init 5:恢复图形化界面

重启

init 6
reboot

服务管理命令

语法: service s_name start|stop|status|restart|
查看防火墙: sudo service iptables status
查看网络:sudo service network status
Mysql数据:mysql/mysqld(低版本)

chkconfig 查看或设置开机是否启动

查看开机是否启动
chkconfig iptables –list
结果:2~5都是on :开机启动

设置开机是否启动
chkconfig iptables off|on

进程管理

查看进程 ps

 ps –ef |grep java
含义:查看所有 java 进程

杀死进程 kill

kill -9 进程id
含义:彻底杀死进程

Redhat的slinux安全机制

vi /etc/selinux/config
重启成效

压缩管理

zip

gzip

后缀: .gz
压缩: gzip file_path
解压: gunzip file.gz
特点: 压缩后源文件没有了, 不能对目录进行压缩

bzip2

适合较大文件压缩
后缀.bz2
压缩:bzip2 file_path
解压:bunzip2 file.bz2
特点:压缩后源文件没有了,不能对目录进行压缩

tar

打包命令,将多个文件或者目录打包成一个文件

格式:
打包:tar [选项参数] file.tar source
解包:tar [选项参数] file.tar –C source
参数:
-C: 指定解压的目录
-x: 解压
-v: 是否显示进度
-z: 是否使用gzip压缩
-j: 是否使用bzip2压缩

应用(使用最频繁):使用tar + gzip
压缩:tar –zcvf jdk-8u91-linux-x64.tar.gz source
解压:tar –zxvf jdk-8u91-linux-x64.tar.gz -C target

使用 tar + bzip2
压缩:tar –jcvf jdk-8u91-linux-x64.tar.gz source
解压:tar –jxvf jdk-8u91-linux-x64.tar.gz -C target

以上差不多是 Linux 工作中常用到的命令。

学习大数据的前期准备工作(一)

发表于 2019-03-05 | 分类于 大数据

Linux 基本环境配置

以下修改操作需要在 root 管理员权限下
所以先通过 su - 命令切换到 root 环境下

修改主机名

执行下面命令修改主机名(临时)

1
hostname bigdata01-huadian.com

修改主机名(永久)
1.执行下面命令进入相应文件
2.按下键盘的 “i” 键进入编辑模式

1
vim /etc/sysconfig/network

3.将 HOSTNAME 修改如下

1
HOSTNAME=bigdata01-huadian.com

4.按下 esc 输入 :wq 保存并退出

网络配置

修改虚拟机
1.打开 VMware -> 编辑 -> 虚拟网络编辑器
2.将 VMware 当成一个路由器使用,设置路由器网段 192.168.59.0

设置网络方式
1.打开 Linux 中 System -> Preferences -> Network Connections
2.使用图形化界面操作将 ip 设置成 192.168.59.250

重启机器

执行命令 reboot 命令
使用 ifconfig 查看

网络映射

(在 Linux 上执行)
目的:让linux的IP和主机名称一一对应,后期可以通过主机名找到机器
执行命令 进入 hosts 文件

1
vi /etc/hosts

添加以下内容

1
192.168.59.250 bigdata01-huadian.com

终端中 ping bigdata01-huadian.com
出现以下结果表示成功

(在 windows 上执行)
目的:在 window 下也能够通过主机名访问 linux
修改文件:C:\Windows\System32\drivers\etc\hosts
新增如下内容:

1
192.168.59.250 bigdata01-huadian.com

在 cmd 中 ping bigdata01-huadian.com

9 日志
2 分类
8 标签
© 2022 sheerLi
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4