1.数据结构和算法
1)反转单词
export default (str) => {
// 字符串按空格进行分隔,保存数组,数组的元素的先后顺序就是单词的顺序
let arr = str.split(' ')
// 对数组进行遍历,然后每个元素进行反转
let result = arr.map(item => {
return item.split('').reverse().join('')
})
return result.join(' ')
}
2)冒泡排序
export default arr => {
// 冒泡排序
// 为什么 i = arr.lentgh - 1 因为j<i,假如i = len; 而下面又有j<i。会出现报错
for (let i = arr.length - 1, tmp; i > 0; i--) {
// 下面的for循环其实就是把最大的值一直往下放
// 1.tmp就是当前所认为最大的值
// 2.假如tmp比下一个还要大,那么交换
for (let j = 0; j < i; j++) {
tmp = arr[j];
if (tmp > arr[j + 1]) {
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
return arr;
};
import sort from '../../code/sort/lesson1-1';
test('冒泡排序', () => {
expect(sort([1, 9, 5, 3, 4])).toEqual([1, 3, 4, 5, 9]);
});
3)选择排序
export default arr => {
// 选择排序
for (let i = 0, len = arr.length, min; i < len; i++) { // 此处从0开始一个个比较
min = arr[i] // 最小值的初始值设为当前遍历到的这个值
// 下面整个for循环其实无非是从i的第二个开始遍历
// 1.如果发现该数比min小,那么min变成该数,该数变成min
// 2.遍历完成之后,i值就是最小的那个
// 总结: 进行上面的遍历之后,就可以找到i往后最小的值,这也就是选择排序的中心思想
for (let j = i + 1; j < len; j++) {
if (arr[j] < min) {
let c = min
min = arr[j]
arr[j] = c
}
}
arr[i] = min
}
return arr
}
4)快速排序
export default (arr) => {
let quickSort = (arr) => {
let len = arr.length
if (len < 2) {
return arr
} else {
// 选标尺元素
let flag = arr[0]
let left = []
let right = []
// 把剩余的元素遍历下,比标尺元素小的放左边,大的放右边
for (let i = 1, tmp; i < len; i++) {
tmp = arr[i]
if (tmp < flag) {
left.push(tmp)
} else {
right.push(tmp)
}
}
// 进行递归操作
return quickSort(left).concat(flag, quickSort(right))
}
}
return quickSort(arr)
}
5)时间复杂度
找时间复杂度的技巧
a.找出算法中的基本语句(算法中执行次数最多的那条语句就是基本语句,通常是最内层循环的循环体)
b.计算基本语句的执行次数的数量级(只要保证基本语句执行次数的函数中的最高次幂正确即可)
举例
a.一个简单语句的时间复杂度为O(1)。int count = 0;
b.100个简单语句的时间复杂度也为O(1)。(100是常数,不是趋于无穷大的n)。int count = 0;
c.一个循环的时间复杂度为O(n).
int n=8,count = 0;
for(inti=1;i<=10n+100;i++){
count++;
}
d.时间复杂度为的循环语句
int n=8,count=0;
for(int i=1;i<=n;i*=2){
count++
}
e.时间复杂度为
f
.
2.Javascript系列
*什么是跨域
跨域是指从一个域名的网页去请求另一个域名的资源。比如:A上的页面获取B上的资源。
概念:只要协议、主机、端口有任何一个不同,都被当作是不同的域。
*哪些办法可以实现跨域
a.JSONP 动态创建<script>标签,并利用其src属性提供一个callback参数构造回调函数来接收数据,从而达到与第三方网址建立通信的目的,这就是JSONP
简单理解
jsonp.html
运行一下就会弹出miaov
b)跨域资源共享(CORS)
目前客户端已经实现,需要服务端做配置(header
)
服务器端代码
<?php
header('Access-Control-Allow-Origin:http://www.a.com'); //这是允许访问该资源的域
echo 'hello';
这样就可以正常访问了
*表单可以跨域吗?
表单可以跨域。只不过无法返回请求数据。
*jsonp方案需要服务端怎么配合
在服务器端,需要对script的src进行url解析,将data作为参数放入回调函数中,最后通过res.end(callback(data))中将要执行的函数放入客户端的script中,在客户端对该函数进行执行。
*Ajax发生跨域要设置什么(前端)
基本上目前所有的浏览器都实现了CORS标准,其实目前几乎所有的浏览器ajax请求都是基于CORS机制的,只不过可能平时前端开发人员并不关心而已(所以说其实现在CORS解决方案主要是考虑后台该如何实现的问题)。后端设置看下面
*Access-Control-Allow-Origin在服务端哪里配置
使用headers属性
*加上CORS之后从发起到请求正式成功的过程
简单请求的流程:浏览器直接发送CORS跨域请求,并在header信息中增加一个Origin字段,表明这是一个跨域的请求。服务器根据这个值,决定是否同意这次请求。如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应,浏览器收到这个回应发现这个回应的头信息没有包含Access-Control-Allow-Origin字段,就知道错了,从而会抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意这种错误无法通过状态码识别,此时HTTP回应的状态码可能是200
非简单请求的过程:非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。下面是一段浏览器的JavaScript脚本。
*promise、async有什么区别
1.简洁
2.错误处理
在promise中,try/catch
不能捕获JSON.parse
抛出的异常,因为该操作是在promise的catch中处理的
在async/await中,catch
代码块现在可以捕获JSON.parse
抛出的异常了:
3.可读性提高
条件分支或者中间值的情况下使用async/await可读性大大提高
4.异常堆栈
假设有一段串行调用多个promise的代码,在promise串中的某一点抛出了异常:
从promise串返回的异常堆栈中没有包含关于异常是从哪一个环节抛出的信息。
5.方便每一步进行调试
*对async、await的理解,内部原理
async/await可以使异步代码在形式上更接近于同步代码。这就是它最大的价值。
async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
*介绍下Promise,内部实现
promise用来实现一步操作,
Promise
对象有以下两个特点。
(1)对象的状态不受外界影响。Promise
对象代表一个异步操作,有三种状态:pending
(进行中)、fulfilled
(已成功)和rejected
(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise
对象的状态改变,只有两种可能:从pending
变为fulfilled
和从pending
变为rejected
。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise
对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
解决了回调地狱的问题
*如何设计Promise.all()
Promise.all方法 多任务处理
Promise.all(iterable) iterable:包含多个 Promise 的迭代器对象,比如数组 当迭代器对象中的所有 Promise 状态都会 fulfilled/resolved 的时候,整体才是 fulfilled/resolved,否则就是 rejected
*使用Async会注意哪些东西
第一点,前面已经说过,await
命令后面的Promise
对象,运行结果可能是rejected
,所以最好把await
命令放在try...catch
代码块中。
第二点,多个await
命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
第三点,await
命令只能用在async
函数之中,如果用在普通函数,就会报错。
第四点,async 函数可以保留运行堆栈。
*Async里面有多个await请求,可以怎么优化(请求是否有依赖)
*Promise和Async处理失败的时候有什么区别
Promise中使用.catch,Async使用try/catch
*Promise和Callback有什么区别
1,callback函数处理异步:代码逻辑复杂,可读性差----回调地狱;不可return;
2,promise处理异步:对比callback,易读,可以return,不需要层层传递callback;处理多个异步等待合并
3,async,await--ES2017 ,promise的语法糖
*Promise构造函数是同步还是异步执行,then呢
Promise 构造函数是同步执行的,promise.then 中的函数是异步执行的