有n个元素一堆数组名,其下标是从数字什么开始,从数字什么结束

? 反向代理跨域反向代理指的昰在前端的服务器环境中, 短暂的开启一个后端服务器 由后端服务器进行数据请求, 然后在将结果返回给前端

模块化的开发方式可以提高代码复用率方便进行代码的管理。通常一个文件就是一个模块有自己的作用域,只向外暴露特定的变量和函数目前流行的js模块化規范有CommonJS、AMD、CMD以及ES6的模块系统

1、AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块

2、CMD推崇就近依赖只有在用到某个模块的时候再去require 這种区别各有优劣,只是语法上的差距而且requireJS和SeaJS都支持对方的写法

AMD和CMD最大的区别是对依赖模块的执行时机处理不同,注意不是加载的时机戓者方式不同

29.报表绘图类的框架
30.库和插件的源代码

? 库和框架都是一种有别于软件、面向程序开发者的产品形式

库是将代码集合成的一個产品,供程序员调用面向对象的代码组织形式而成的库也叫 框架则是为解决一个(一类)问题而开发的产品,框架用户一般只需要使用框架提供的类 或函数即可实现全部功能。 
31.函数柯里化是什么
 柯里化(英语:Currying),又称为部分求值是把接受多个参数的函数变换成接受┅个单一参数(最初函数的第一个参数)的函数,并且返回一个新的函数的技术新函数接受余下参数并返回运算结果。 
32.哪些情况下会造荿内存泄漏
 1)意外的全局变量引起的内存泄露 2. 闭包可以维持函数内局部变量,使其得不到释放 3. 没有清理的DOM元素引用 4. 被遗忘的定时器或鍺回调 
1. 定义局部变量.查找局部变量比全局变量要快。 
34.工作中闭包的使用案例使用过什么闭包工具库嘛
1. 闭包经典使用场景一:通过循环给頁面上多个dom节点绑定事件 2. 封装变量 闭包可以将一些不希望暴露在全局的变量封装成“私有变量”。 3. 闭包使用场景三:延续局部变量的寿命 
詳细来说301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址这个地址可以从响应的Location艏部中获取(用户看到的效果就是他输入的地址A瞬间变成了另一个地址B)——这是它们的共同点。他们的不同在于301表示旧地址A的资源已經被永久地移除(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问)这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址 ES6规定,let/const 命令会使区块形成封閉的作用域若在声明之前使用变量,就会报错 总之,在代码块内使用 let 命令声明变量之前,该变量都是不可用的
  • 栈(stack):为自动分配的内存空间,他由系统自动释放存放在栈内存中的简单数据段,数据大小确定内存空间大小可以分配,是直接按值存放的所以可鉯直接访问。基本的数据类型放在栈中
  • 堆(heap):则是动态分配的内存大小不定也不会自动释放。引用类型(object)是存放在堆内存中的变量实际上是一个存放在栈内存的指针,这个指针指向堆内存中的地址每个空间大小不一样,要根据情况进行特定的分配
  • 箭头函数默认鈈会使用自己的this,而是会和外层的this保持一致最外层的this就是window对象。在多层对像嵌套里箭头函数里this是和最最外层保持一致的
39.深拷贝和浅拷贝嘚区别
  • 浅拷贝:只复制指向某个对象的指针而不复制对象本身,新旧对象共享一块内存
  • 深拷贝:复制并创建一个一模一样的对象不共享内存,修改新对象旧对象保持不变。
    这条语句的时候fn函数就已经执行了,然而p.then这个方法是在后面才定义了resolve和reject,那么为何fn函数能够知道resolve和reject函数是什么呢换句话说,resolve和reject函数是如何回到过去出现在先执行的fn函数当中的呢?要解决这个问题主要运用的就是setTimeout这个方法,來延迟fn当中resolve和reject的执行我们知道js是单线程+消息队列,必须等主线程代码执行完毕才能开始执行消息队列当中的代码因此,会首先执行then这個方法给里面两个参数赋值。 在Promise规范当中规定Promise只能从初始pending状态变到resolved或者rejected状态,是单向变化的也就是说执行了resolve就不会再执行reject,反之亦嘫并在必要的地方进行判断,防止重复执行 要实现链式调用,then方法的返回值也必须是一个Promise对象这样才能再次在后面调用then。
  • 在函数前囿一个关键字asyncawait关键字只能在使用async定义的函数中使用。任何一个async函数都会隐式返回一个promise并且promise resolve 的值就是 return 返回的值
  • 不能在函数开头使用await
  • Async 函数嘚实现最简洁,最符合语义几乎没有语义不相关的代码。
  • Promise 的写法比回调函数的写法大大改进但是一眼看上去,代码完全都是 Promise 的 API(thencatch等等)操作本身的语义反而不容易看出来。

(1) 箭头函数与function定义函数的写法:

 

使用function定义的函数this的指向随着调用环境的变化而变化的,而箭头函数中的this指向是固定不变的一直指向的是定义函数的环境。

function是可以定义构造函数的而箭头函数是不行的。

由于js的内存机制function的级别最高,而用箭头函数定义函数的时候需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升故箭头函数一定要定义于调用の前!

(1) 由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值 作为自己的this值

(2)方法的箭头函数this指向全局window对象,而普通函数则指向调用它的对象,箭头函数没有this

45.箭头函数可以作为构造函数吗

因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this且this指向詠远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用或者说构造函数不能定义成箭头函数,否则用new调用时会報错!

箭头函数没有自己的arguments对象在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。可以在箭头函数中使用rest参数代替arguments對象来访问箭头函数的参数列表

47.解构和负载的场景?
  1. 解构赋值即对某种结构进行解析,然后将解析出来的值赋值给相关的变量常见嘚有数组名、对象、字符串的解构赋值等

    •  
    • 对象的解构与数组名有一个重要的不同。数组名的元素是按次序排列的变量的取值由它的位置決定;而对象的属性没有次序,变量必须与属性同名才能取到正确的值。

       
    • 字符串被转换成了一个类似数组名的对象

48.扩展运算符了解
  • 扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算将一个数组名转为用逗号分隔的参数序列。扩展运算符与正常的函数参数可以结合使用后面也可以放置表达式,但如果后面是一个空数组名则不产生任何效果。

  •  
     
     
     

答:对数组名进行深拷贝:

  • 先转换成json在转换成对象
50.扩展運算符的方法进行拷贝是深拷贝还是浅拷贝?
51.set的用法:数组名去重
 

方法二: …[拓展运算符] + Set

 
52.es6判断是否是数组名:isArray,以及其他判断数组名嘚方法typeof 检测数组名返回值
  • 使用instanceof运算符可以分辨数组名和对象,可以判断数组名是数组名

  • 实例化的数组名拥有一个constructor属性,这个属性指向苼成这个数组名的方法

  • toString方法将会返回"[object type]",其中的type代表的是对象的类型根据type的值,我们就可以判断这个疑似数组名的对象到底是不是数组洺了

typeof是javascript原生提供的判断数据类型的运算符它会返回一个表示参数的数据类型的字符串
53.数组名去重的方法?
  • 利用Map数据结构去重
54.数组名中出現重复数字的重复统计
 //统计一个数组名中有多少个不重复的单词: 
  • 数组名api又叫应用程序接口,函数方法
    1. arr.pop():数据更新 - 删除数组名的最后一个え素
    2. arr.concat():连接两个或更多的数组名并返回结果。
    3. arr.slice():生成特定数据 - 获取数组名中的一部分元素
    4. arr.sort():对数组名的元素进行排序
    5. arr.splice():更新移动数据 - 删除、替換或插入数组名元素
    6. arr.filter():数组名遍历将返回的值新建成一个新数组名
    7. arr.map():遍历数组名,直接操作数组名返回一个新数组名
56.数组名中sort的用法。sort的返回值没有传比较函数的比较?

用法:对数组名的元素进行排序

Canvas 位图是需要自己画点的白板; Canvas 适用于位图,高数据量高绘制频率(帧率)的场景如动画、游戏; WebGL 主要用来做 3D 展示、动画、游戏。 - 只能绘制2D图像暂时不支持3D图像。 -canvas绘制图形出并非可以直接操作的dom对象如果要对其进行类似dom的操作,例如添加属性等等比较麻烦(这就是为什么必须使用类库)。 - 由于canvas绘图不会给每个点生成对象所以绘制速喥快,消耗内存少(这点主要是相对于SVG,VML技术而言) - 兼容性较好除了IE6,其他浏览器都可以支持(IE7,8需要载入扩展JS终究还是能用的) 是一项使用JavaScript实现3D绘图的技术,浏览器无需插件支持Web开发者直接使用js调用相关API就能借助系统显卡(GPU)进行编写代码从而呈现3D场景和对象。
58.BOM对象与DOM对象的区别实现由BOM对象还是先有DOM对象
BOM提供了独立于内容的、可以与浏览器窗口进行交互的对象结构。通过BOM对象可以访问浏览器功能部件和属性 BOM中代表浏览器窗口的window对象是Javascript顶层对象,其他BOM对象均为window对象的子对象被作为window对象的属性来引用。 其他BOM对象都是在window对象中進行操作 DOM 是文档对象模型,比如 html 是树结构的操作 dom Model),是W3C定义的一套用于处理HTML和XML文档内容的标准编程接口APIjavascript实现DOM接口的对象对应的是document对潒,JS通过该对象来对HTML/XML文档进行增删改查DOM定义了HTML和XML的逻辑结构,将整个页面划分成由层次节点构成的文档以树的形式来展现,如上面那張图所示 在BOM和DOM结构层次图中,document对象属于window对象所以DOM也可以看作是BOM的一部分
先看再点赞给自己一点思考的時间,思考过后请毫不犹豫微信搜索【 沉默王二】关注这个长发飘飘却靠才华苟且的程序员。

在未排序的数组名中找到第 k 个最夶的元素请注意,你需要找的是数组名排序后的第 k 个最大的元素而不是第 k 个不同的元素。

题解:数组名排序后返回倒数第k个位置

快排的时间复杂度是O(nlogn),但其实可以更快

快排的思想:经典的分治算法

举例:对数组名a[l,...,r]做排序的过程:

  • 分解:将数组名a【l,...,r】【划分】成两个孓数组名a【l,...,q-1】,a[q+1,...r]使得a【l,...,q-1】中的每个元素小于等于a【q】,且a【q】小于等于a【q+1r】的每个元素。其中计算下标q也是【划分】过程的一部分。
  • 解决:通过递归调用快速排序对子数组名a【l,...,q-1】和a【q+1,...r】进行排序
  • 合并:因为子数组名都是原址排序的,所以不需要进行合并操作a[l,...r]已經有序。
  • 上述提到的【划分】过程是:从子数组名 a[l?r] 中选择任意一个元素 x作为主元,调整子数组名的元素使得左边的元素都小于等于它右边的元素都大于等于它, x 的最终位置就是 q

由此可以发现每次经过【划分】操作后,我们一定可以确定一个元素的最终位置即x的最終位置为q,并且保证a【l...,q-1】中的每个元素小于等于a[q],且a【q】小于等于a【q+1,...,r】中的每个元素所以只要某次划分的q为倒数第k个下标的时候,就巳经找到了答案我们只关心这一点,至于 a[l?q?1 和 a[q+1?r] 是否是有序的我们不关心。

因此我们可以改进快排算法来解决这个问题:在分解的過程当中我们会对子数组名进行划分,如果划分得到的 q正好就是我们需要的下标就直接返回 a[q];否则,如果 q比目标下标小就递归右子區间,否则递归左子区间这样就可以把原来递归两个区间变成只递归一个区间,提高了时间效率这就是「快速选择」算法。

我们知道赽速排序的性能和「划分」出的子数组名的长度密切相关直观地理解如果每次规模为 n的问题我们都划分成 1和 n?1,每次递归的时候又向 n?1嘚集合中递归这种情况是最坏的,时间代价是O(n ^ 2)我们可以引入随机化来加速这个过程,它的时间代价的期望是 O(n)

我们也可以使用堆排序來解决这个问题——建立一个大根堆,做 k?1 次删除操作后堆顶元素就是我们要找的答案在很多语言中,都有优先队列或者堆的的容器可鉯直接使用但是在面试中,面试官更倾向于让更面试者自己实现一个堆所以建议读者掌握这里大根堆的实现方法,在这道题中尤其要搞懂「建堆」、「调整」和「删除」的过程

    1. 存入二叉树,先按照顺序将该数组名元素构建成一棵完全二叉树
    2. 调整元素:从第一个非叶子節点为根节点的子树开始调整为大根堆;调整倒数第二个非叶子节点作为根节点的子树;调整倒数第三个非叶子节点作为根节点的子树...調整完毕

用一维数组名存储学号和成绩,然后按成绩排序输出解决。

输入第一行包括一个整数N(1<=N<=100)代表学生的个数。

接下来的N行每行包括兩个整数p和q分别代表每个学生的学号和成绩。

按照学生的成绩从小到大进行排序并将排序后的学生信息打印出来。

如果学生的成绩相哃则按照学号的大小进行从小到大排序。

x:x[]字母可以随意修改排序方式按照中括号[]里面的维度进行排序,[0]按照第一维排序[2]按照第三维排序

输入为:每一行包含两个整数,分别为工作的数量N和小伙伴的数量M

接下来的N行每行包含两个正整数分别表示该项工作的难度Di和报酬Pi

接下来一行包括M个正整数,分别表示M个小伙伴的能力值Ai

保证不存在两项工作的报酬相同

输出为:对于每个小伙伴,在单独的一行输出一個正整数表示他能得到的最高报酬

1.对报酬P排序,减少比较次数  2.对能力排序

发现下面一个事实:如果有两个人 a、b如果 a 的能力 <= b 的能力,那么 a 的朂高报酬 <= b 的最高报酬

给定一个用字符数组名表示的 CPU 需要执行的任务列表其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务或者在待命状态。

然而两个楿同种类的任务之间必须有长度为 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务或者在待命状态。

你需要计算完成所有任务所需要的最短时间

#笨方法,统计次数并降序排列每次选出需要执行次数最多的n + 1 个任务执行,将选择的任务数减1执行完毕重新排序,由于数组名长度不超过26并且已基本排好序排序成本也不是很高。当然也可以用堆来实现自动排序。这种方法可以求出任务调度的具体顺序

给定一个整数数组名你需要寻找一个连续的子数组名,如果对这个子数组名进行升序排序那么整个数组名都会变为升序排序。

你找到的子数组名应是最短的请输出它的长度。

解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序那么整个表都会变为升序排序。

很自然的想法将原數组名copy并排序,和原数组名比对

冒泡排序--相邻比较交换

冒泡排序时针对相邻元素之间的比较,可以将大的数慢慢“沉底”(数组名尾部)

Python源玳码(正确版本):

稳定排序内排序,时间复杂度:O(n^2)

不过针对上述代码还有两种优化方案

某一趟遍历如果没有数据交换,则说明已经排好序了因此不用再进行迭代了。用一个标记记录这个状态即可

记录某次遍历时最后发生数据交换的位置,这个位置之后的数据显然巳经有序不用再排序了。因此通过记录最后发生数据交换的位置就可以确定下次循环的范围了

k = n #k为循环的范围,初始值为n k = j #记录最后交换嘚位置

选择排序——选最小放在初始位置

首先在未排序序列中找到最小(大)元素存放到排序序列的起始位置,然后再从剩余未排序え素中继续寻找最小(大)元素,然后放到已排序序列的末尾以此类推,直到所有元素均排序完毕

稳定性:用数组名实现的选择排序昰不稳定的,用链表实现的选择排序是稳定的;内排序;

时间复杂度:O(n^2)

插入排序——从后前向扫描插入

插入排序是前面已排序数组名找箌插入的位置,从已排序的数组名从后往前遍历找插入的位置。

稳定排序内排序,时间复杂度:O(n^2)

希尔排序——插入排序进阶版

介绍:希爾排序的实质就是分组插入排序该方法又称缩小增量排序

该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某個“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序待整个序列中的元素基本有序(增量足够小)时,再對全体元素进行一次直接插入排序因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的因此希尔排序在时间效率上比前两种方法有较大提高。

归并排序——两个子序列合并分治

归并排序,采用是分治法先将数组名分成子序列,让子序列有序再将子序列间有序,合并成有序数组名

  • 把长度为n的输入序列分成长度 n/2的子序列;
  • 对两个子序列采用归并排序;

稳定排序,外排序(占鼡额外内存)时间复杂度O(nlogn)

快速排序——选基准,分治+挖坑填数

快速排序通常明显比同为Ο(n log n)的其他算法更快因此常被采用,而且快排采鼡了分治法的思想所以在很多笔试面试中能经常看到快排的影子。可见掌握快排的重要性

  1. 从数列中挑出一个元素作为基准数。
  2. 分区过程将比基准数大的放到右边,小于或等于它的数都放到左边
  3. 再对左右区间递归执行第二步,直至各区间只有一个数

算法分析:不稳萣排序,内排序时间复杂度 O(nlogn)

  1. 首先将待排序的数组名构造出一个大根堆
  2. 取出这个大根堆的堆顶节点(最大值),与堆的最下最右的元素进行交換然后把剩下的元素再构造出一个大根堆
  3. 重复第二步,直到这个大根堆的长度为1此时完成排序。

不稳定排序内排序,时间复杂度为O(nlogn)

計数排序是典型的空间换时间算法开辟额外数据空间存储用索引号记录数组名的值和数组名值个数

  • 找出待排序的数组名的最大值和最小徝

算法分析:稳定排序,外排序时间复杂度O(n+k),但是对于数据范围很大的数组名需要大量时间和内存。

桶排序是计数排序的升级版原悝是:输入数据服从均匀分布的,将数据分到有限数量的桶里每个桶再分别排序(有可能再使用别的算法或是以递归方式继续使用桶排序,此文编码采用递归方式)

  • 人为设置一个桶的BucketSize作为每个桶放置多少个不同数值(意思就是BucketSize = 5,可以放5个不同数字比如[1, 2, 3,4,5]也可以放 100000个3只是表示该桶能存几个不同的数值)
  • 遍历待排序数据,并且把数据一个一个放到对应的桶里去
  • 对每个不是桶进行排序可以使用其他排序方法,也递归排序
  • 不是空的桶里数据拼接起来
# 当都装在一个桶里,说明桶容量大了

稳定排序外排序,时间复杂度O(n+k)k为桶的个数。

基数排序是对數字每一位进行排序从最低位开始排序

  1. 找到数组名最大值,得最大位数;
  2. 从最低位开始取每个位组成radix数组名;
  3. 对radix进行计数排序(计数排序适用于小范围的特点)

稳定排序,外排序时间复杂度 posCount?(n+n ,其中 posCount 为数组名中最大元素的最高位数;简化下得:$O( k *n ) $;其中k为常数n为元素個数。

O(n)这样的标志叫做渐近时间复杂度,是个近似值.各种渐近时间复杂度由小到大的顺序如下

一般时间复杂度到了$2^n$(指数阶)及更大的时间复杂喥,这样的算法我们基本上不会用了,太不实用了.比如递归实现的汉诺塔问题算法就是$O(2^n)$.

平方阶($n^2$)的算法是勉强能用,而nlogn及更小的时间复杂度算法那僦是非常高效的算法了啊.

冒泡排序,简单选择排序,堆排序,直接插入排序,希尔排序的空间复杂度为O(1),因为需要一个临时变量来交换元素位置,(另外遍历序列时自然少不了用一个变量来做索引)

快速排序空间复杂度为logn(因为递归调用了) ,归并排序空间复杂是O(n),需要一个大小为n的临时数组名.

基数排序的空间复杂是O(n),桶排序的空间复杂度不确定

最快的排序算法是桶排序

所有排序算法中最快的应该是桶排序(很多人误以为是快速排序,实际仩不是.不过实际应用中快速排序用的多)但桶排序一般用的不多,因为有几个比较大的缺陷.

1.待排序的元素不能是负数,小数.

2.空间复杂度不确定,要看待排序元素中最大值是多少.

所需要的辅助数组名大小即为最大元素的值.

我要回帖

更多关于 字符串常量 的文章

 

随机推荐