常面常新-1019
写在前面:11:30 面试,好饿
项目相关
为什么选用OpenLayer
,了解其他地图框架吗
特性 | Mapbox | OpenLayers | Leaflet | Cesium |
---|---|---|---|---|
功能特点 | 自定义样式、数据可视化 | GIS 支持、可定制 | 轻量级、用户友好 | 3D 渲染、高性能 |
开源与否 | 非开源 | 开源 | 开源 | 开源(部分付费) |
包的体积 | ~1 MB | ~300 KB | ~40 KB | ~1.5 MB |
市场占有率 | 较高 | 特定领域(GIS) | 开源项目广泛 | 特定领域(空天等 3D 领域) |
适宜人群 | 企业开发者 | GIS 开发者 | 初学者 | 3D 开发者 |
进程和线程
进程(Process)
定义:进程是操作系统进行资源分配和调度的一个独立单位。它是应用程序运行的实例。
资源拥有:每个进程都有自己的一套独立的地址空间,一般来说,进程间的资源是不共享的。
创建和管理:操作系统负责进程的创建、调度和管理。创建一个新进程需要为其分配独立的内存空间。
通信:进程间通信
(IPC)
通常通过管道、信号、共享内存、消息队列、套接字等方式进行。独立性:一个进程崩溃不会直接影响到其他进程(除非是特权进程,如操作系统的关键部分)。
上下文切换:进程间的上下文切换开销相对较大,因为涉及到虚拟地址空间的切换。
线程(Thread)
定义:线程是进程中的一个实体,是被系统独立调度和分派的基本单位。线程自身不拥有系统资源,只拥有一点在运行中必不可少的资源(如执行栈),但它可以与同属一个进程的其他线程共享进程所拥有的全部资源。
资源拥有:同一进程内的线程共享进程的地址空间和资源,如内存、文件句柄和其他资源。
创建和管理:线程的创建和管理开销比进程小,因为它们不需要独立的地址空间。
通信:线程间可以直接读写共享变量来进行通信,因为它们共享相同的内存空间。
依赖性:线程之间是相互依赖的,同一进程下的一个线程崩溃可能会影响到该进程下的所有线程。
上下文切换:线程间的上下文切换开销较小,因为它们共享相同的地址空间。
JS 是单线程吗
JavaScript
通常被认为是单线程的,这是因为JavaScript
运行在单一的线程上,即主线程。这意味着在任何给定时间点,只能执行一段JavaScript
代码。这种模型有助于简化编程模型,因为开发者不需要担心并发执行的代码之间的同步问题。
然而,JavaScript
环境(如浏览器或Node.js
)通常提供了一种机制来处理高IO
等待操作,而不阻塞主线程,这就是异步编程。
TCP 和 UDP
TCP
(传输控制协议)和UDP
(用户数据报协议)是两种主要的传输层通信协议:
TCP
提供面向连接的、可靠的字节流服务。它确保数据正确无误地从源传送到目的地。TCP
通过三次握手建立连接,提供数据包排序、确认和重传机制,确保数据的完整性和顺序性。UDP
提供无连接服务,它在发送数据前不建立连接。UDP
发送的是数据报,它不保证数据的到达、顺序或完整性。UDP
适用于对实时性要求高的应用,如视频流和在线游戏。
position 有几种
static
:默认值。元素按照正常的文档流进行布局,即它原本应该在的位置。relative
:元素相对于它在正常文档流中的位置进行定位。它仍占据原来的空间。absolute
:元素相对于其最近的非static
定位祖先元素进行定位。如果一个绝对定位的元素没有非static
定位的祖先元素,那么它将相对于最初的包含块进行定位(通常是文档的<html>
元素)。fixed
:元素相对于浏览器窗口进行定位,即使页面滚动,它也会停留在相同的屏幕位置。固定定位的元素不会占据正常的文档流空间。sticky
:元素根据用户的滚动位置在相对定位和固定定位之间切换。它在元素在视口中的滚动范围的顶部时表现为相对定位,当页面滚动超出这个范围时表现为固定定位。
绝对定位和相对定位
绝对定位
定位基准:绝对定位的元素是相对于其最近的已定位(即非
static
)祖先元素进行定位的。如果没有已定位的祖先元素,那么它是相对于最初的包含块(通常是HTML
文档的<html>
元素)进行定位的。文档流:绝对定位的元素会从正常的文档流中被完全移除,这意味着它不会影响到其他元素的布局,其他元素会表现得好像这个元素不存在一样。
层叠上下文:绝对定位的元素会创建一个新的层叠上下文,这可能影响到其后代元素的层叠顺序。
位置控制:可以通过
top
、right
、bottom
、left
属性来控制元素的精确位置。
相对定位
- 定位基准:相对定位的元素是相对于它在正常文档流中的原始位置进行定位的。即使它被移动了,它仍然占据着原来的空间。
- 文档流:相对定位的元素部分地保持在正常的文档流中,这意味着它原来的空间会被保留,其他元素的布局不会受到它移动的影响。
- 层叠上下文:相对定位的元素不会创建新的层叠上下文。
- 位置控制:可以通过
top
、right
、bottom
、left
属性来微调元素的位置,但它不会从文档流中脱离。
this 指向
作为对象的方法调用: 当一个函数作为某个对象的方法被调用时,
this
指向该对象。作为普通函数调用:当一个函数作为普通函数被调用时,
this
指向全局对象(在浏览器中是window
对象,在Node.js
中是global
对象)构造函数中的
this
:当一个函数作为构造函数使用new
关键字调用时,this
指向新创建的对象。箭头函数中的
this
:箭头函数不绑定自己的this
,它会捕获其所在上下文的this
值,作为自己的this
值。事件处理器中的
this
:在事件处理器中,this
指向触发事件的对象。
compute 和 watch 属性
computed
computed
属性用于声明性地描述一个值是如何根据组件中其他数据计算得来的。它们具有以下特点:
- 缓存性:
computed
属性会根据它们的依赖进行缓存。只有当依赖项发生变化时,计算属性才会重新计算。如果依赖项没有变化,返回的将是之前的计算结果。 - 响应性:
computed
属性是响应式的,这意味着当计算属性的依赖发生变化时,任何依赖于该计算属性的都会更新。 - 无副作用:计算属性应该没有副作用,这意味着它们不应该产生其他操作,只负责计算值。
- 可读性:
computed
属性提供了一种简洁的方式来表达数据的转换或派生状态。
Watch
watch
属性用于执行副作用,响应数据的变化,并在数据变化时执行异步或开销较大的操作。它们具有以下特点:
- 无缓存性:
watch
属性没有缓存,每次侦听的属性发生变化时,都会执行回调函数。 - 立即执行:
watch
可以设置为在开始观察时立即执行回调函数。 - 深度监听:
watch
可以配置为深度监听对象的内部属性变化。 - 异步操作:
watch
可以处理异步操作,如在数据变化后调用API
或执行延时操作。
状态码快问快答
401
:Unauthorized
(未授权),这个状态码表示请求没有通过身份验证,用户需要提供有效的认证凭据才能访问请求的资源。通常需要用户名和密码,并且可能需要通过特定的认证方案,如基本认证或令牌认证。403
:Forbidden
(禁止访问),表示服务器理解请求但拒绝执行。服务器收到请求,但是拒绝提供服务,可能是由于服务器上资源的权限设置不允许你的访问,或者服务器配置禁止了你的请求。302
:Found
(临时重定向),这是一个重定向响应,表示请求的资源临时位于不同的 URI 下。304
:Not Modified
(未修改),当客户端发送了一个条件请求(带上了如If-Modified-Since
头),而请求的资源自上次请求以来没有被修改,服务器会返回304
状态码。这意味着客户端可以使用缓存中的版本,无需再次下载资源,这有助于减少带宽和提高性能。504
:Gateway Timeout
(网关超时),这个状态码表示服务器作为网关或代理,但是没有及时从上游服务器接收请求。这通常是因为上游服务器没有在规定时间内响应,导致网关超时。
同步和异步
写题:await
踩坑了
await
关键字在JavaScript
中用于等待一个Promise
的结果。尽管await
可以暂停函数的执行直到 Promise
被解决(resolved)
或拒绝(rejected)
,但它本身并不会使代码异步执行。
算法题
- LRU
<script>
class LRUCache {
constructor(lenght) {
this.length = lenght; // 存储长度
this.data = new Map(); // 存储数据
}
// 存储数据,通过键值对的方式
set(key, value) {
const data = this.data;
if (data.has(key)) {
data.delete(key)
}
data.set(key, value);
// 如果超出了容量,则需要删除最久的数据
if (data.size > this.length) {
const delKey = data.keys().next().value;
data.delete(delKey);
}
}
// 获取数据
get(key) {
const data = this.data;
// 未找到
if (!data.has(key)) {
return null;
}
const value = data.get(key); // 获取元素
data.delete(key); // 删除元素
data.set(key, value); // 重新插入元素
}
}
const lruCache = new LRUCache(5);
</script>