前端工程师一生必须拥有的一本工具书-JavaScript高级程序设计

为什么这样说呢,因为这本书在你不同的阶段重读都会有新的体会,作为工具书,它提供了足够的标准,作为提升,它也提供了很多高级用法

博主特别为大家提供了高清pdf,非扫描版

快去下载
继续阅读前端工程师一生必须拥有的一本工具书-JavaScript高级程序设计

前端开发面试题搜集大全–刷完能进bat

HTML

  • Doctype作用?标准模式与兼容模式各有什么区别?
      (1)、<!DOCTYPE>声明位于HTML文档中的第一行,处于 <html> 标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。
    
      (2)、标准模式的排版 和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
    
  • HTML5 为什么只需要写 <!DOCTYPE HTML>
       HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行);
    
       而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。
    
  • 继续阅读前端开发面试题搜集大全–刷完能进bat

写给那些想转行前端,或者犹豫是不是在前端干下去的同学

入前端断断续续的在这行也10年有余,当初因为上大学阴错阳差的当了网络部长,由于导员想法颇多,给网络部很多任务,其中就有做学校的网站,刚入大一,除了数理化什么都不会,只能硬着头皮自学起来,幸好 有一个学长教了一些,网络部长还有一些同学,学的时候是一起学习,但是其他人都兴趣缺缺,但是我身为网络部长如果学不会都话那做网站都任务就要泡汤了,所以也许是这一种责任,或者是天然的兴趣促使自己学习下去,刚入行这其中会碰到很多各种各样的问题,有些问题根本无从解决,毕竟这方面的知识一片空白,我想这也是很多同学刚开始都会碰到的情况,也是入行的拦路虎,会拦下90%想要入行的同学吧

所以对于想入行的同学我给的建议是给自己一个不得不去学习前端知识的目标,比如帮助朋友亲戚去做一个网页,或是给心爱的妹子做一个网页的生日祝福,这样你学习下去的动力就有了,比自己枯燥的去看教程要有趣的多,目标明确的多

当入坑了之后,很多同学又会有一些困惑,比如不知道方向是什么,该学一些什么才能达到工作的要求,或是已经工作了不知道怎么提高,成为大牛,其实在我看来单纯的为了工作挣钱而没有骨子里对于前端的兴趣是不能成事的,也许会有意外,但是我觉得对于大多数人来说是适用的

请各位前端同学自行体会,当遇到了前端的难题是突然兴奋,瞬间来了精神?当看到一个新的轮子是特别感兴趣还是避之不及?当有一个新的需求发现需要学习新的知识是不是迫不及待要去完成?如果你没有这种感觉,那么我可能悲伤的告诉你,你也许不适合这行,请转行,或者维持现状吧

前端相对于其他it技术来说,需要很多能力,也会遇到很多莫名其妙的问题,如果没有一种自我驱动,自我学习的能力那么肯定不会有所建树。能做一个好的前端开发肯定能成为一个优秀的后端开发,但是一个好的后端不一定能成为好的前端开发,个人体验勿喷

如果你也有困惑给我留言,知无不言,一起提高

前端资源大全,大家有需要的来拿

个人整理来之不易请珍惜,如有错误请谅解,谢谢。。。
资源教程:

  1. 综合类
    - [前端知识体系](http://www.cnblogs.com/sb19871023/p/3894452.html)
    - [前端知识结构](https://github.com/JacksonTian/fks)
    - [Web前端开发大系概览](https://github.com/unruledboy/WebFrontEndStack)
    - [Web前端开发大系概览-中文版](http://www.cnblogs.com/unruledboy/p/WebFrontEndStack.html)
    - [Web Front-end Stack v2.2](https://raw.githubusercontent.com/unruledboy/WebFrontEndStack/master/Web%20Front%20End%20Stack.png)
    - [免费的编程中文书籍索引](https://github.com/justjavac/free-programming-books-zh_CN)
    - [前端书籍](https://github.com/dypsilon/frontend-dev-bookmarks)
    - [前端免费书籍大全](https://github.com/vhf/free-programming-books)
    - [前端知识体系](http://www.cnblogs.com/sb19871023/p/3894452.html)
    - [免费的编程中文书籍索引](https://github.com/justjavac/free-programming-books-zh_CN)
    - [智能社 - 精通JavaScript开发](http://study.163.com/course/introduction/224014.htm)
    - [重新介绍 JavaScript(JS 教程)](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript)
    - [麻省理工学院公开课:计算机科学及编程导论](http://v.163.com/special/opencourse/bianchengdaolun.html)
    - [JavaScript中的this陷阱的最全收集--没有之一](http://segmentfault.com/a/1190000002640298)
    - [JS函数式编程指南](https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/ch1.html)
    - [JavaScript Promise迷你书(中文版)](http://liubin.github.io/promises-book/)
    - [腾讯移动Web前端知识库](https://github.com/AlloyTeam/Mars)
    - [Front-End-Develop-Guide 前端开发指南](https://github.com/Front-End-Developers-Hunan/Front-End-Develop-Guide)
    - [前端开发笔记本](https://li-xinyang.gitbooks.io/frontend-notebook/content/)
    - [大前端工具集 - 聂微东](https://github.com/nieweidong/fetool)
    - [前端开发者手册](https://dwqs.gitbooks.io/frontenddevhandbook/content/)
  2. 入门类
    - [前端入门教程](http://www.cnblogs.com/jikey/p/3613082.html)
    - [瘳雪峰的Javascript教程](http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000)
    - [jQuery基础教程](http://www.imooc.com/view/11)
    - [前端工程师必备的PS技能——切图篇](http://www.imooc.com/view/506)
    - [结合个人经历总结的前端入门方法](https://github.com/qiu-deqing/FE-learning)
  3. 效果类
  4. 工具类
  5. 慕课专题
  6. 周报类

继续阅读前端资源大全,大家有需要的来拿

js中为什么你不敢用 “==”

前言

类型转换在各个语言中都存在,而在 JavaScript 中由于缺乏对其的了解而不慎在使用中经常造成bug被人诟病。为了避免某些场景下的意外,甚至推崇直接使用 Strict Equality( === )来代替 ==。这确实能避免很多bug,但更是一种对语言不理解的逃避(个人观点)。

引入

先抛出在 You Don’t Know JavaScript (中) 看到的一个例子

  [] == [] // false
  [] == ![] // true
  {} == !{} // false
  {} == {} // false

是不是很奇怪?本文将从书中看到的知识与规范相结合,来详细说明一下JavaScript在类型转换时候发生的故事。

类型转换

很多人喜欢说显示类型转换与隐式类型转换,但个人感觉只是说法上的不同,实质都在发生了类型转换而已,故不想去区分他们了(感觉一万个人有一万种说法)

仅在6大基本类型 null undefined number boolean string object 作讨论 symbol未考虑

继续阅读js中为什么你不敢用 “==”

写好一份技术简历很重要

转自:https://www.jianshu.com/p/99f890ef36d4?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

前一段时间写了一篇博文《每年应该更新你的简历》浏览的同学不少,所以想多写写和简历有关的文章,这篇主要说的是如何写简历,为了缩小描述范围,强调的是技术简历,时间段是从准备写简历到投递简历之间。

写简历的基本目的和策略

大部分情况下,写简历是找工作的第一步,考虑到第二步就是面试,那么简历就是敲门砖,为了让企业认识到你的价值,必须把自己的真实水平描述出来,展现出你有能力应对这份工作。甚至要体现出自己是某方面的杰出人才,因为只有足够优秀的人,企业才能更看重你,因为你会为企业带来不一样的价值,对应的待遇也将更好。

所以写简历的根本策略就是如实的体现出你的水平和阅历,那么如何体现呢?不是通过说,而是有一定的方法论去证明你具备足够的才华,简历虽然不是论文,但也要有一定的论证,让看简历的人觉得你优秀。简历上的每一点应该是经过精雕细琢的,可推敲的,具备一定意义的。

简历应该是变化的

很多人不管投递给那家公司,都是一成不变的,不建议这样,简历是很重要的资料,不应该四处投递,应该珍惜,你投递每一份简历应该是深思熟虑的,是想获得那份工作的。

要对你投递简历的那家公司有基本的了解,业务方向是什么,公司企业文化是什么,从事的行业是你看好的吗;假如有可能,你应该了解你投递简历的具体部门是干什么的,是技术研发部门,还是应用开发部门;假如有渠道甚至应该了解你未来的职位是什么。
继续阅读写好一份技术简历很重要

基数排序–js实现算法

基数排序

基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。

1. 基数排序 vs 计数排序 vs 桶排序

基数排序有两种方法:

这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:

  • 基数排序:根据键值的每位数字来分配桶;
  • 计数排序:每个桶只存储单一键值;
  • 桶排序:每个桶存储一定范围的数值;

2. LSD 基数排序动图演示

动图演示

3. JavaScript 代码实现

//LSD Radix Sort
var counter = [];
function radixSort(arr, maxDigit) {
    var mod = 10;
    var dev = 1;
    for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
        for(var j = 0; j < arr.length; j++) {
            var bucket = parseInt((arr[j] % mod) / dev);
            if(counter[bucket]==null) {
                counter[bucket] = [];
            }
            counter[bucket].push(arr[j]);
        }
        var pos = 0;
        for(var j = 0; j < counter.length; j++) {
            var value = null;
            if(counter[j]!=null) {
                while ((value = counter[j].shift()) != null) {
                      arr[pos++] = value;
                }
          }
        }
    }
    return arr;
}

桶排序–js实现算法

桶排序

桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效,我们需要做到这两点:

  1. 在额外空间充足的情况下,尽量增大桶的数量
  2. 使用的映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中

同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。

1. 什么时候最快

当输入的数据可以均匀的分配到每一个桶中。

2. 什么时候最慢

当输入的数据被分配到了同一个桶中。

3. JavaScript 代码实现

function bucketSort(arr, bucketSize) {
    if (arr.length === 0) {
      return arr;
    }

    var i;
    var minValue = arr[0];
    var maxValue = arr[0];
    for (i = 1; i < arr.length; i++) {
      if (arr[i] < minValue) {
          minValue = arr[i];                // 输入数据的最小值
      } else if (arr[i] > maxValue) {
          maxValue = arr[i];                // 输入数据的最大值
      }
    }

    //桶的初始化
    var DEFAULT_BUCKET_SIZE = 5;            // 设置桶的默认数量为5
    bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;
    var bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;   
    var buckets = new Array(bucketCount);
    for (i = 0; i < buckets.length; i++) {
        buckets[i] = [];
    }

    //利用映射函数将数据分配到各个桶中
    for (i = 0; i < arr.length; i++) {
        buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);
    }

    arr.length = 0;
    for (i = 0; i < buckets.length; i++) {
        insertionSort(buckets[i]);                      // 对每个桶进行排序,这里使用了插入排序
        for (var j = 0; j < buckets[i].length; j++) {
            arr.push(buckets[i][j]);                      
        }
    }

    return arr;
}

计数排序–js实现算法

计数排序

计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。

1. 动图演示

动图演示

2. JavaScript 代码实现

function countingSort(arr, maxValue) {
    var bucket = new Array(maxValue+1),
        sortedIndex = 0;
        arrLen = arr.length,
        bucketLen = maxValue + 1;

    for (var i = 0; i < arrLen; i++) {
        if (!bucket[arr[i]]) {
            bucket[arr[i]] = 0;
        }
        bucket[arr[i]]++;
    }

    for (var j = 0; j < bucketLen; j++) {
        while(bucket[j] > 0) {
            arr[sortedIndex++] = j;
            bucket[j]--;
        }
    }

    return arr;
}

堆排序–js实现算法

堆排序

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

  1. 大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
  2. 小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;

堆排序的平均时间复杂度为 Ο(nlogn)。

1. 算法步骤

  1. 创建一个堆 H[0……n-1];
  2. 把堆首(最大值)和堆尾互换;
  3. 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;
  4. 重复步骤 2,直到堆的尺寸为 1。

2. 动图演示

动图演示

3. JavaScript 代码实现

var len;    // 因为声明的多个函数都需要数据长度,所以把len设置成为全局变量

function buildMaxHeap(arr) {   // 建立大顶堆
    len = arr.length;
    for (var i = Math.floor(len/2); i >= 0; i--) {
        heapify(arr, i);
    }
}

function heapify(arr, i) {     // 堆调整
    var left = 2 * i + 1,
        right = 2 * i + 2,
        largest = i;

    if (left < len && arr[left] > arr[largest]) {
        largest = left;
    }

    if (right < len && arr[right] > arr[largest]) {
        largest = right;
    }

    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, largest);
    }
}

function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

function heapSort(arr) {
    buildMaxHeap(arr);

    for (var i = arr.length-1; i > 0; i--) {
        swap(arr, 0, i);
        len--;
        heapify(arr, 0);
    }
    return arr;
}