面试烦恼
面试题你是否有被问道以下代码如何执行?如果我们不清楚js在浏览器中运行的机制,那么就无从下手。 现在让我们深刻的理解js的运行机制,让我们在面试中如鱼得水,游刃有余。在理解js的运行机制前,我们大概梳理下需要了解的知识点,以便我们更好理解:
- 进程与线程的概念
- js为什么是单线程?
- 栈、堆、队列的概念
- 宏任务与微任务的概念
进程与线程的概念
我们都知道计算机的核心是CPU,它承担了所有的计算任务,操作系统是负责任务的调度,资源的分配和管理。
什么是进程? 进程是资源(CPU、内存等)分配的基本单位,具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
什么是进线程? 线程是进程的一个实体,是独立运行和独立调度的基本单位(CPU上真正运行的是线程)。线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
进程与线程的区别?
- 进程之间相互独立,是由于每开启一个进程,系统就会为它分配一个独立的内存空间,当一个进程崩溃后,在保护模式下不会影响其他进程,所以多进程的性能更为健壮。并且在同一进程下的各个线程之间共享程序的内存空间,某进程内的线程在其他的进程不可见。可以在任务管理器中看到打开一个谷歌浏览器程序,谷歌有多个进程,当一个页面崩溃后,并不会影响其他页面。
- 而一个线程崩溃后,整个进程都死掉,也是由于一个线程之间是共享进程的地址空间。
js为什么是单线程?
如果js是多线程,a线程进行删除c元素,b线程进行编辑c元素,这样浏览器该怎么执行呢?
栈与堆的概念
js的内存空间分为栈、堆。其中栈放变量,堆放复杂对象(数组,对象)。 堆和栈的区别主要有五大点,分别是:
- 1、申请方式的不同。栈由系统自动分配,而堆是人为申请开辟;
- 2、申请大小的不同。栈获得的空间较小,而堆获得的空间较大;
- 3、申请效率的不同。栈由系统自动分配,速度较快,而堆一般速度比较慢;
- 4、存储内容的不同。栈在函数调用时,函数调用语句的下一条可执行语句的地址第一个进栈,然后函数的各个参数进栈,其中静态变量是不入栈的。而堆一般是在头部用一个字节存放堆的大小,堆中的具体内容是人为安排;
- 5、底层不同。栈是连续的空间,而堆是不连续的空间。
栈
栈被用在编程语言的编译器和内存中保存变量、方法调用等。
栈的数据结构
栈(stack)是一种运算受限的线性表,其限制是指只仅允许在表的一端进行插入和删除操作,这一端被称为栈顶(Top),相对地,把另一端称为栈底(Bottom)。把新元素放到栈顶元素的上面,使之成为新的栈顶元素称作进栈、入栈或压栈(Push)把栈顶元素删除,使其相邻的元素成为新的栈顶元素称作出栈或退栈(Pop)。这种受限的运算使栈用友先进后出的特性,又称LIFO。就像是子弹盒(这个大概是我看到过最贴切的例子了),先压进去的子弹,后打出来。
栈的运行方式
调用栈表示函数像积木一样存放,以实现层层调用。
上面这段代码运行的时候,首先调用Student构造函数。在构造函数中,又调用到sayHello方法,最终打印出liana:hello!。
堆
堆的数据结构
堆(heap)是一种常用的树形结构,是一种特殊的完全二叉树,当且仅满足当且仅当满足所有节点的值总是不大于或不小于其父节点的值的完全二叉树被称之为堆。堆的这一特性称之为堆序性。因此,在一个堆中,根节点是最大(或最小)节点。如果根节点最小,称之为小顶堆(或小根堆),如果根节点最大,称之为大顶堆(或大根堆)。堆的左右孩子没有大小的顺序。下面是一个小顶堆示例:
堆的管理方式
堆主要存放的是大小不固定的内存结构,空间比栈大,因此,我们的数组和结构体经常被存放在堆上,由程序猿分配释放,若程序猿不释放,程序结束时由OS回收,分配方式倒是类似于链表。
队列
队列的数据结构
队列是遵循FIFO先进先出原则的一组有序的项,尾部添加新元素,一般叫做enQueue(入队),头部移除元素,一般叫做deQueue(出队)最新添加的元素必须排在队列的末尾。 在现实生活中最常见的例子就是排队,先来排在前面,先接受服务。