大厂技术  高级前端  Node进阶

点击上方 程序员成长指北,关注公众号

回复1,加入高级Node交流群

介绍

此篇属于前端算法入门系列的第一篇,主要介绍常用的数组方法字符串方法遍历方法高阶函数正则表达式以及相关数学知识

  • 前端算法入门一:刷算法题常用的JS基础扫盲[1]

  • 前端算法入门二:时间空间复杂度\&8大数据结构的JS实现[2]

  • 前端算法入门三:5大排序算法\&2大搜索\&4大算法思想[3]

  • 前端面试算法高频100题(附答案,分析思路,一题多解)[4]

文章主要包含以下内容:

  • 数组常用方法

  • 字符串常用方法

  • 常用遍历方法&高阶函数

  • 常用正则表达式

  • 数学知识

一、数组常用方法

1.push()

在尾部追加,类似于压栈,原数组会变。

const arr = [1, 2, 3]
arr.push(8)
console.log(arr) // [1, 2, 3, 8]
复制代码

2.pop()

在尾部弹出,类似于出栈,原数组会变。数组的 push & pop 可以模拟常见数据结构之一:栈。

const arr = [1, 2, 3]
const popVal = arr.pop()
console.log(popVal) // 3
console.log(arr) // [1, 2]// 数组模拟常见数据结构之一:栈
const stack = [0, 1]
stack.push(2) // 压栈
console.log(stack) // [0, 1, 2]const popValue = stack.pop() // 出栈
console.log(popValue) // 2
console.log(stack) // [0, 1]
复制代码

3.unshift()

在头部压入数据,类似于入队,原数组会变。

const arr = [1, 2, 3]
arr.unshift(0)
console.log(arr) // [0, 1, 2, 3]
复制代码

4.shift()

在头部弹出数据,原数组会变。数组的 push(入队) & shift(出队) 可以模拟常见数据结构之一:队列。

const arr = [1, 2, 3]
const shiftVal = arr.shift()
console.log(shiftVal) // 1
console.log(arr) // [2, 3]// 数组模拟常见数据结构之一:队列
const queue = [0, 1]
queue.push(2) // 入队
console.log(queue) // [0, 1, 2]const shiftValue = queue.shift() // 出队
console.log(shiftValue) // 0
console.log(queue) // [1, 2]
复制代码

5.concat()

concat会在当前数组尾部拼接传入的数组,然后返回一个新数组,原数组不变。

const arr = [1, 2, 3]
const arr2 = arr.concat([7, 8, 9])
console.log(arr) // [1, 2, 3]
console.log(arr2) // [1, 2, 3, 7, 8, 9]
复制代码

6.indexOf()

在数组中寻找该值,找到则返回其下标,找不到则返回-1

const arr = [1, 2, 3]
console.log(arr.indexOf(2)) // 1
console.log(arr.indexOf(0)) // -1
复制代码

7.includes()

在数组中寻找该值,找到则返回true,找不到则返回false

const arr = [1, 2, 3]
console.log(arr.includes(2)) // true
console.log(arr.includes(4)) // false
复制代码

8.join()

将数组转化成字符串,并返回该字符串,不传值则默认逗号隔开,原数组不变。

const arr = [1, 2, 3]
console.log(arr.join()) // ‘1, 2, 3’
console.log(arr) // [1, 2, 3]
复制代码

9.reverse()

翻转原数组,并返回已完成翻转的数组,原数组改变。

const arr = [1, 2, 3]
console.log(arr.reverse()) // [3, 2, 1]
console.log(arr) // [3, 2, 1]
复制代码

10.slice(start,end)

start 开始截取到end,但是不包括end

const arr = [1, 2, 3, 4, 5]
console.log(arr.slice(1, 4)) // [2, 3, 4]
console.log(arr) // [1, 2, 3, 4, 5]
复制代码

11.splice(start, deleteCount, item1, item2……)

  • start参数 开始的位置

  • deleteCount要截取的个数

  • 后面的items为要添加的元素

  • 如果deleteCount0,则表示不删除元素,从start位置开始添加后面的几个元素到原始的数组里面。

  • 返回值为由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。

  • 这个方法会改变原始数组,数组的长度会发生变化

const arr3 = [1, 2, 3, 4, 5, 6, 7, "f1", "f2"];
const arr4 = arr3.splice(2, 3) // 删除第三个元素以后的三个数组元素(包含第三个元素)
console.log(arr4); // [3, 4, 5];
console.log(arr3); // [1, 2, 6, 7, "f1", "f2"]; 原始数组被改变const arr5 = arr3.splice(2, 0, "wu", "leon");
// 从第2位开始删除0个元素,插入"wu","leon"
console.log(arr5); // [] 返回空数组
console.log(arr3); // [1, 2, "wu", "leon", 6, 7, "f1", "f2"]; 原始数组被改变const arr6 = arr3.splice(2, 3, "xiao", "long");
// 从第 2 位开始删除 3 个元素,插入"xiao", "long"
console.log(arr6); // ["wu", "leon", 6]
console.log(arr3); //[ 1, 2, "xiao", "long", 7, "f1", "f2"]const arr7 = arr3.splice(2); // 从第三个元素开始删除所有的元素
console.log(arr7);// ["xiao", "long", 7, "f1", "f2"]
console.log(arr3); // [1, 2]
复制代码

12.sort()

  • 对数组的元素进行排序,并返回数组。

  • 默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。

  • 由于它取决于具体实现,因此无法保证排序的时间和空间复杂性。

可参考 MDN:Sort[5]

const arr = [1, 2, 3]
arr.sort((a, b) => b - a)
console.log(arr) // [3, 2, 1]
复制代码

13.toString()

将数组转化成字符串,并返回该字符串,逗号隔开,原数组不变。

const arr = [1, 2, 3, 4, 5]
console.log(arr.toString()) // ‘1, 2, 3, 4, 5’
console.log(arr) // [1, 2, 3, 4, 5]
复制代码

二、字符串常用方法

1.charAt()

返回指定索引位置处的字符。类似于数组用中括号获取相应下标位置的数据。

var str = 'abcdefg'
console.log(str.charAt(2)) // 输出 'c'
console.log(str[2]) // 输出 'c'
复制代码

2.concat()

类似数组的concat(),用来返回一个合并拼接两个或两个以上字符串。原字符串不变。

const str1 = 'abcdefg'
const str2 = '1234567'
const str3 = str1.concat(str2)
console.log(str3) // 输出 'abcdefg1234567'
复制代码

3.indexOf()、lastIndexOf()

indexOf,返回一个字符在字符串中首次出现的位置,lastIndexOf返回一个字符在字符串中最后一次出现的位置。

const str = 'abcdcefcg'
console.log(str.indexOf('c')) // 输出 '2'
console.log(str.lastIndexOf('c')) // 输出 '7'
复制代码

4.slice()

提取字符串的片断,并把提取的字符串作为新的字符串返回出来。原字符串不变。

const str = 'abcdefg'
console.log(str.slice()) // 输出 'abcdefg', 不传递参数默认复制整个字符串
console.log(str.slice(1)) // 输出 'bcdefg',传递一个,则为提取的起点,然后到字符串结尾
console.log(str.slice(2, str.length-1)) // 输出'cdef',传递两个,为提取的起始点和结束点
复制代码

5.split()

使用指定的分隔符将一个字符串拆分为多个子字符串数组并返回,原字符串不变。

const str = 'A*B*C*D*E*F*G'
console.log(str.split('*')) // 输出 ["A", "B", "C", "D", "E", "F", "G"]
复制代码

6.substr(), substring()

  • 这两个方法的功能都是截取一个字符串的片段,并返回截取的字符串。

  • substrsubstring这两个方法不同的地方就在于参数二,substr的参数二是截取返回出来的这个字符串指定的长度,substring的参数二是截取返回这个字符串的结束点,并且不包含这个结束点。而它们的参数一,都是一样的功能,截取的起始位置。

  • 注意事项substr的参数二如果为0或者负数,则返回一个空字符串,如果未填入,则会截取到字符串的结尾去。substring的参数一和参数二为NAN或者负数,那么它将被替换为0

const str = 'ABCDEFGHIJKLMN'
console.log(str.substr(2))  // 输出 'CDEFGHIJKLMN'
console.log(str.substring(2)) // 输出 'CDEFGHIJKLMN'console.log(str.substr(2, 9))  // 输出 'CDEFGHIJK'
console.log(str.substring(2, 9))  // 输出 'CDEFGHI'
复制代码

7.match()

match()方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,并返回一个包含该搜索结果的数组。

const str = '2018年结束了,2019年开始了,2020年就也不远了'
const reg = /\d+/g  // 这里是定义匹配规则,匹配字符串里的1到多个数字
console.log(str.match(reg))  // 输出符合匹配规则的内容,以数组形式返回 ['2018', '2019', '2020']
console.log(str.match('20'))  // 不使用正则 ["20", index: 0, input: "2018年结束了,2019年开始了"]
复制代码

注意事项:如果match方法没有找到匹配,将返回null。如果找到匹配,则 match方法会把匹配到以数组形式返回,如果正则规则未设置全局修饰符g,则 match方法返回的数组有两个特性:inputindexinput属性包含整个被搜索的字符串。index属性包含了在整个被搜索字符串中匹配的子字符串的位置。

8.replace()

replace接收两个参数,参数一是需要替换掉的字符或者一个正则的匹配规则,参数二,需要替换进去的字符,仔实际的原理当中,参数二,你可以换成一个回调函数。

const str = '2018年结束了,2019年开始了,2020年就也不远了'
const rex = /\d+/g  // 这里是定义匹配规则,匹配字符串里的1到多个数字
const str1 = str.replace(rex, '****')
console.log(str1) // 输出:"****年结束了,****年开始了,****年也不远了"
const str2 = str.replace(rex, function(item){console.log(arguments)  // 看下面的图片const arr = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']let newStr = ''item.split('').map(function(i){newStr += arr[i]})     return newStr
})
console.log(str2) // 输出:贰零壹捌年结束了,贰零壹玖年开始了,贰零贰零年也不远了
复制代码

9.search()

在目标字符串中搜索与正则规则相匹配的字符,搜索到,则返回第一个匹配项在目标字符串当中的位置,没有搜索到则返回一个-1

const str = '2018年结束了,2019年开始了,2020年就也不远了'
const reg = /\d+/i  // 这里是定义匹配规则,匹配字符串里的1到多个数字
console.log(str.search(reg)) // 输出 0  这里搜索到的第一项是从位置0开始的
复制代码

10.toLowerCase(),toUpperCase()

toLowerCase把字母转换成小写,toUpperCase()则是把字母转换成大写。

const str1 = 'abcdefg'
const str2 = 'ABCDEFG'
console.log(str2.toLowerCase())  // 输出:'abcdefg'
console.log(str1.toUpperCase())  // 输出:'ABCDEFG'
复制代码

11.includes(), startsWith(), endsWith()

includesstartsWithendsWithes6的新增方法,includes 用来检测目标字符串对象是否包含某个字符,返回一个布尔值,startsWith用来检测当前字符是否是目标字符串的起始部分,相对的endwith是用来检测是否是目标字符串的结尾部分。

const str = 'Excuse me, how do I get to park road?'
console.log(str.includes('how')) // 输出:true
console.log(str.startsWith('Excuse')) // 输出:true
console.log(str.endsWith('?')) // 输出:true
复制代码

12.repeat()

返回一个新的字符串对象,新字符串等于重复了指定次数的原始字符串。接收一个参数,就是指定重复的次数。原字符串不变。

const str = 'http'
const str2 = str.repeat(3)
console.log(str) // 输出:'http'
console.log(str2) // 输出:'httphttphttp'
复制代码

三、常用遍历方法&高阶函数

1.for()

最常用的for循环,经常用的数组遍历,也可以遍历字符串。

const arr = [1, 2, 3]
const str = 'abc'
for (let i = 0; i < arr.length; i++) {console.log(arr[i])console.log(str[i])
}
复制代码

2.while() / do while()

whiledo while主要的功能是,当满足while后边所跟的条件时,来执行相关业务。这两个的区别是,while会先判断是否满足条件,然后再去执行花括号里面的任务,而do while则是先执行一次花括号中的任务,再去执行while条件,判断下次还是否再去执行do里面的操作。也就是说 do while至少会执行一次操作.

while(条件){执行...
}
------------
do{执行...
}
while(条件)
复制代码

3.forEach()

拷贝一份遍历原数组。

  • return无法终止循环。不过可以起到continue效果。

  • 本身是不支持的continuebreak语句的我们可以通过some和 every来实现。

const arr = [5,1,3,7,4]
arr.forEach((item, index) => {if (item < 2) returnconsole.log(`索引:${index},数值:${item}`)arr[5] = 0
})
console.log(arr)
// 打印结果:
// 索引:0,数值:5
// 索引:2,数值:3
// 索引:3,数值:7
// 索引:4,数值:4
// [5, 1, 3, 7, 4, 0]
复制代码

4.for...in

  • for...in 是 ES5 标准, 此方法遍历数组效率低,主要是用来循环遍历对象的属性。

  • 遍历数组的缺点:数组的下标index值是数字,for-in遍历的index"0","1","2"等是字符串。

  • Object.defineProperty,建立的属性,默认不可枚举。

const foo = {name: 'bar',sex: 'male'
}
Object.defineProperty(foo, "age", { value : 18 })
for(const key in foo){console.log(`可枚举属性:${key}`)
}
console.log(`age属性:${foo.age}`)
// 打印结果:
// 可枚举属性:name
// 可枚举属性:sex
// age属性:18
复制代码

5.for...of

for…ofES6新增的方法,但是for…of不能去遍历普通的对象,**for…of的好处是可以使用break跳出循环。**

  • for-of这个方法避开了for-in循环的所有缺陷

  • forEach()不同的是,它可以正确响应breakcontinuereturn语句

  • for-of循环不仅支持数组,还支持大多数类数组对象,例如DOM NodeList对象[6]

    • for-of循环也支持字符串遍历

// for of 循环直接得到的就是值
const arr = [1, 2, 3]
for (const value of arr) {console.log(value)
}
复制代码

面试官:说一下 for...infor...of 区别?

(1)for…in 用于可枚举数据,如对象、数组、字符串
(2)for…of 用于可迭代数据,如数组、字符串、Map、Set
复制代码

6.every / some

返回一个布尔值。当我们需要判定数组中的元素是否满足某些条件时,可以使用every / some。这两个的区别是,every会去判断判断数组中的每一项,而 some则是当某一项满足条件时返回。

// every
const foo = [5,1,3,7,4].every((item, index) => {console.log(`索引:${index},数值:${item}`)return item > 2
})
console.log(foo)
// every 打印:
// 索引:0,数值:5
// 索引:1,数值:1
// false
复制代码
// some
const foo = [5,1,3,7,4].some((item, index) => {console.log(`索引:${index},数值:${item}`)return item > 2
})
console.log(foo)
// some 打印:
// 索引:0,数值:5
// true
复制代码

7.filter()

  • filter方法用于过滤数组成员,满足条件的成员组成一个新数组返回。

  • 它的参数是一个函数,所有数组成员依次执行该函数,返回结果为true的成员组成一个新数组返回。

  • 该方法不会改变原数组。

const foo = [5,1,3,7,4].filter((item,index) => {console.log(`索引:${index},数值:${item}`)return item > 2
})
console.log(foo)
// 打印结果:
// 索引:0,数值:5
// 索引:1,数值:1
// 索引:2,数值:3
// 索引:3,数值:7
// 索引:4,数值:4
// [5, 3, 7, 4]
复制代码

8.map()

  • map即是 “映射”的意思 ,原数组被“映射”成对应新数组。

  • map:支持return,相当与原数组克隆了一份,把克隆的每项改变了,也不影响原数组。

const foo = [5,1,3,7,4].map((item,index) => {console.log(`索引:${index},数值:${item}`)return item + 2
})
console.log(foo)
// 打印结果:
// 索引:0,数值:5
// 索引:1,数值:1
// 索引:2,数值:3
// 索引:3,数值:7
// 索引:4,数值:4
// [7, 3, 5, 9, 6]
复制代码

9. reduce() / reduceRight()

reduce 从左到右将数组元素做“叠加”处理,返回一个值。reduceRight 从右到左。

const foo = [5,1,3,7,4].reduce((total, cur) => {console.log(`叠加:${total},当前:${cur}`)return total + cur
})
console.log(foo)
// 打印结果:
// 叠加:5,当前:1
// 叠加:6,当前:3
// 叠加:9,当前:7
// 叠加:16,当前:4
// 20
复制代码

10.Object,keys遍历对象的属性

Object.keys方法的参数是一个对象,返回一个数组。该数组的成员都是该对象自身的(而不是继承的)所有属性名,且只返回可枚举的属性。

const obj = {p1: 123,p2: 456
};
Object.keys(obj) // ["p1", "p2"]
复制代码

11.Object.getOwnPropertyNames() 遍历对象的属性

Object.getOwnPropertyNames方法与Object.keys类似,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名。但它能返回不可枚举的属性。

const arr = ['Hello', 'World'];
Object.keys(arr) // ["0", "1"]
Object.getOwnPropertyNames(arr) // ["0", "1", "length"]
复制代码

以上遍历方法的区别:

一:map(),forEach(),filter()循环的共同之处:1.forEach,map,filter循环中途是无法停止的,总是会将所有成员遍历完。2.他们都可以接受第二个参数,用来绑定回调函数内部的 this 变量,将回调函数内部的 this 对象,指向第二个参数,间接操作这个参数(一般是数组)。二:map()、filter()循环和forEach()循环的不同:forEach 循环没有返回值;map,filter 循环有返回值。三:map()和filter()都会跳过空位,for 和 while 不会四:some()和every():some()只要有一个是true,便返回true;而every()只要有一个是false,便返回false.五:reduce(),reduceRight():reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员)。六:Object对象的两个遍历 Object.keys 与 Object.getOwnPropertyNames:他们都是遍历对象的属性,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名。但Object.keys不能返回不可枚举的属性;Object.getOwnPropertyNames能返回不可枚举的属性。
复制代码

四、常用正则表达式

这里罗列一些我在刷算法题中遇到的正则表达式,如果有时间可认真学一下正则表达式不要背[7]

1.判断字符

由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
复制代码

2.判断数字

数字:^[0-9]*$
复制代码

持续更新,敬请期待……

五、数学知识

1.质数

若一个正整数无法被除了1 和它自身之外的任何自然数整除,则称该数为质数(或素数),否则称该正整数为合数。

function judgePrime(n) {for (let i = 2; i * i <= n; i++) {if (n % i == 0) return false}return true
}
复制代码

2.斐波那契数列

function Fibonacci(n) {if (n <= 1) return n  return Fibonacci(n - 1) + Fibonacci(n - 2)
}
复制代码

持续更新,敬请期待……

参考文章

  • JavaScript 之字符串常用方法[8]

  • JavaScript 循环遍历大全[9]

  • 刷算法题必备的数学考点汇总[10]

关于本文

作者:摆草猿

https://juejin.cn/post/7087134135193436197

Node 社群我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。如果你觉得这篇内容对你有帮助,我想请你帮我2个小忙:1. 点个「在看」,让更多人也能看到这篇文章2. 订阅官方博客 www.inode.club 让我们一起成长点赞和在看就是最大的支持❤️

刷算法题常用的 JS 基础扫盲相关推荐

  1. 分享一些常用的 JS 基础面试题

    介绍 此篇属于前端算法入门系列的第一篇,主要介绍常用的数组方法.字符串方法.遍历方法.高阶函数.正则表达式以及相关数学知识. 前端算法入门一:刷算法题常用的JS基础扫盲[1] 前端算法入门二:时间空间 ...

  2. 牛客网刷算法题的输入输出(C++)

    内容简述 该篇文章将对牛客网刷题中关于输入输出的一些问题作一个总结.每年互联网公司的招聘都必不可少会有算法题,因此平时很多人都会去一些刷题网站进行刷题来学习.这里面用的比较多的刷题网站是leetcod ...

  3. 新手如何有效的刷算法题(LeetCode)

    点击关注上方"五分钟学算法", 设为"置顶或星标",第一时间送达干货. 来源:五分钟学算法 前言 作为一名非科班出身的程序员,我是参加工作之后才开始接触算法,学 ...

  4. 用Java刷算法题的常用数据结构(C++转Java)

    文章目录 一:前言 1:为何刷题从C++转java 2:如何上手呢? 二:输入 1:常规的输入 2:关于其他输入符在nextLine()之前用吃掉回车符的问题解决 3:常见输入之我们输入一串数到容器中 ...

  5. 【c/c++】刷算法题时常用的函数手册 持续更新--

    在做算法题的时候,有时候为了高效的做题,我们会使用一些函数,但是常用的函数确实太多了,时不时的会忘记一些 于是我整理了一些常用的函数,方便自己查找和别人使用. 都是超链接,点击直接跳转到对应的内容. ...

  6. 靠刷算法题,真的可以刷进大厂吗?

    我一直不知道我在大家心目中的定位是什么,但我内心其实是把自己定义为一个『工具人』的. 可能是因为我自己本身就是程序员,所以更能理解程序员的不易吧. 所以,我尽量不写水文,只分享干货. 就是希望大家看了 ...

  7. 刷算法题需要的java语法_蓝桥杯java b组需要重点刷什么算法呢?

    我觉得这个问题我很适合回答.不过距离我最后一次参赛,已经有了三年,所以回答的内容重点可能有点偏(建议你,可以到网上找找最新的获奖选手赛后总结看看),但是我觉得应该对你有用. 我本科也在湖北,并且参加过 ...

  8. 算法题常用技巧C++

    刷题常用技巧C++ 常用头文件 #include <iostream> #include <cstdio> #include <fstream> #include ...

  9. 字节跳动面试前端岗,刷算法题有救吗?

    在面试中,算法题目是必须的,通过算法能够看出一个程序员的编程思维,考察对复杂问题的设计与分析能力,对问题的严谨性都能够体现出来. 去年,有位学长参加秋招的时候,拿到了字节跳动.快手.阿里.美团--等等 ...

最新文章

  1. SD-WAN能带来什么好处?
  2. Python进阶02 文本文件的输入输出
  3. android中OnItemClickListener的参数解释
  4. 设置ubuntu下使用ls命令显示文件颜色显示
  5. 聚焦 | 阿里灵杰AI工程化峰会来了
  6. 深度学习中 epoch,[batch size], iterations概念解释
  7. 2019 年度十大 AI 安防热点事件丨年终盘点
  8. Mybatis中resultMap
  9. TCP 粘包和拆包及解决方案
  10. Linux入门之一Linux 系统启动
  11. Vue自定义指令—— 完美解决H5页面不同尺寸屏幕的适配问题
  12. 如何在.Netcore控制台应用中使用依赖注入(4)
  13. Item08. 多级指针(Pointers to Pointers)
  14. Oracle中索引的使用 索引性能优化调整
  15. webstrom使用es6语法报错
  16. 微信小程序云开发教程-手把手:小程序数据库设计
  17. el表达式遍历list中的list_js 遍历EL表达式 list对象
  18. c++“不允许使用不完整的类型“
  19. php捕捉Warning、Notice错误
  20. C语言程序设计-餐厅点餐系统

热门文章

  1. 一加6 win11 刷机教程及报错处理
  2. 《精通 ASP.NET MVC 4》----1.3 ASP.NET MVC的关键优点
  3. 第一个月实习总结 [大三四八九月实习]
  4. cmd命令快速切换电源模式-平衡模式/节能模式/高性能模式
  5. 详细讲解C语言经典例题:有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子, 问最后留下的是原来第几号的那位
  6. 在Excel中数据筛选后如何拷贝粘贴
  7. 面向对象的个人理解(封装/继承/多态实践)
  8. 大数据:正在到来的数据革命,以及它如何改变政府、商业与我们的生活 [2.0升级版] - 电子书下载(高清版PDF格式+EPUB格式)...
  9. GDAL 根据图版范围对影像进行提取 (C++篇)
  10. mac中pyinstaller 如何打包文件夹内文件