Skip to content

2024面试题汇总

从浏览器输入到页面展现做了哪些操作

  • 在用户输入到展示的几秒钟里面,浏览器做了很多的操作,里面的细节有很多
  • 刚开始浏览器会对输入的url进行解析,提取出协议,主机名,路径等信息
    • 这里面涉及到http和https的一些概念,
    • 如果是https的话,为了安全,会去做一些处理
  • 接下来浏览器会将主机名转换成对应的ip,这个过程被称之为dns解析
    • 浏览器会首先检查本地的dns缓存,如果有匹配的ip直接进行访问,如果没有的话,会向dns服务器发送请求,来获取对应的IP地址
  • 转换成ip之后,浏览器会通过ip地址和端口号来与服务器建立tcp链接,这个过程是通过tcp的三次握手完成的,以确保双方可以正常通信
    • 第一次握手,客户端发送syn包到服务器,并且客户端进行syn_send状态,等待服务器确认
    • 第二次握手,服务器接收到syn包时,会发送一个syn+ack包给客户端,服务器进入syn_recv状态
    • 第三次握手,客户端接收到syn+ack包之后,向服务器发送确认ack的包,至此三次握手结束
  • 建立tcp连接之后,客户端与服务器就开始传输数据了
    • 首先浏览器会向服务器发送http请求,请求的内容包括方法,请求头部,和请求体等
    • 如果是get请求,请求体在url上
    • 请求头包括浏览器自带的请求头和自定义的请求头,自定义的请求头可以用于登陆等场景
    • 浏览器自带的请求头包括浏览器的一些信息,浏览器可接收的压缩算法,浏览器可接收的数据格式,content-type,accept等等
  • 服务器接收到浏览器发送的请求之后,会进行处理,包括读取数据库,处理一些业务逻辑,生成一些动态内容等
  • 服务器处理完请求,会对处理结果封装成http响应,包括状态码,响应头部,响应体等
    • 浏览器自带的响应头也包含content-type,除此之外还有返回数据的压缩算法格式等,服务器修改cookie时,通过set-cookie修改
  • 浏览器接收到服务器的响应后,会对这个响应进行解析,如果响应体是html文档,则会下载其中引用的其他资源,例如js,css,静态文件等
    • 响应结束之后,为了更彻底地释放双方的资源,引入了四次挥手
    • 四次挥手的时间,看是否设置了keep alive属性
    • 第一次挥手,客户端发送终止请求报文段
    • 第二次挥手,服务器接收到请求并发送确认报文
    • 第三次挥手,客户端收到确认并发送确认报文
    • 第四次挥手,服务器接收到确认报文并终止连接
  • 解析下载完资源之后,浏览器会将html解析器解析成dom树,然后使用css解析器将css文件解析成样式规则,接着,浏览器根据dom树和样式规则进行渲染,将页面内容显示在浏览器上
  • 解析完html和css之后,浏览器开始执行js文件,处理一些业务逻辑,这里也涉及到一些请求响应
  • html和css渲染是同步执行的,但中间如果遇到js的操作,不管是下载还是解析,都会阻塞整个html的渲染
  • js内部又分为同步任务和异步任务,异步任务又分为宏任务和微任务,像promise就是微任务
  • 最后浏览器根据渲染结果将页面呈现给用户
  • 在请求和响应的过程中,中间还有一个很重要的步骤,就是浏览器的缓存
    • 浏览器的缓存主要包括强制缓存和协商缓存,强制缓存的判断主要在客户端,协商缓存的判断主要在服务端
    • 强制缓存主要使用cache-control,浏览器初次请求到服务器时,服务器不止返回资源,还会返回一个cache-control,客户端如果看到有这个标识,会将资源缓存下来,后面请求的时候会看这个标识是否过期,不过期的话就不进行请求
    • 协商缓存主要使用last-modified和etag进行标识,服务端会对客户端请求的资源进行判断,如果请求的资源时一样的,就会返回304,否则就会返回200
    • http缓存不一定只用一种方式,经常会一起使用,这时候就要了解两种缓存的执行流程
    • 发送http请求,一般来说,首先是判断是否命中强制缓存,再判断是否命中协商缓存,如果有强制缓存,但缓存过期,就会进入协商缓存的过程,如果服务端判断缓存不可用,即没有last-modified和etag标识或者标识不一致,就不会命中协商缓存,手动刷新的时候,协商缓存还是有效的,只有强制刷新,才能使两个缓存都失效

vue的双向绑定

  • vue的双向绑定,主要是讲数据和视图的双向绑定,当数据变化时,视图可以自动变化,同时用户在视图中进行操作,结果也会反映到数据中,vue的双向绑定原理是通过数据劫持和发布订阅模式进行实现的,在创建vue实例时,vue会对数据对象进行递归遍历,使用object.defineProperty方法对每个属性进行劫持,当数据变化时,会触发相应的getter和setter方法,通知订阅者更新视图,同时vue也会将数据和视图进行绑定,当视图中的表单元素发生变化时,会触发相应的事件,将新的数据同步到数据对象中,这样就完成了双向绑定

NextTick 是做什么的

  • $nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
  • 当你修改了data的值然后马上获取这个dom元素的值,是不能获取到更新后的值,你需要使用$nextTick这个回调,让修改后的data值渲染更新到dom元素之后在获取,才能成功。

Vue 组件 data 为什么必须是函数

  • 因为js本身的特性带来的,如果 data 是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue实例的数据。如果将 data 作为一个函数返回一个对象,那么每一个实例的 data 属性都是独立的,不会相互影响了

对 keep-alive 的了解

  • keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染
    • 即就是把一些经常使用的页面缓存起来,避免重复做加载渲染
  • keep-alive 运用了 LRU 算法,选择最近最久未使用的组件予以淘汰。

简述vue原理

  • Vue的模式是m-v-vm模式,即(model-view-modelView),通过modelView作为中间层(即vm的实例),进行双向数据的绑定与变化。
  • 通过建立虚拟dom树document.createDocumentFragment(),方法创建虚拟dom树。
  • 一旦被监测的数据改变,会通过Object.defineProperty定义的数据拦截,截取到数据的变化。
  • 截取到的数据变化,从而通过订阅——发布者模式,触发Watcher(观察者),从而改变虚拟dom的中的具体数据。
  • 最后,通过更新虚拟dom的元素值,从而改变最后渲染dom树的值,完成双向绑定

你都做过哪些 Vue 的性能优化?

  • 对象层级不要过深,否则性能就会差。
  • 不需要响应式的数据不要放在 data 中(可以使用 Object.freeze() 冻结数据)
  • v-if 和 v-show 区分使用场景
  • computed 和 watch 区分场景使用
  • v-for 遍历必须加 key,key最好是id值,且避免同时使用 v-if
  • 大数据列表和表格性能优化 - 虚拟列表 / 虚拟表格
  • 防止内部泄露,组件销毁后把全局变量和时间销毁
  • 图片懒加载
  • 路由懒加载
  • 异步路由
  • 第三方插件的按需加载
  • 适当采用 keep-alive 缓存组件
  • 防抖、节流的运用
  • 服务端渲染 SSR or 预渲染

在原理层面上讲vue2和vue3有什么区别

  • 对于vue而言,本质上我们可以将它们分成三大模块,响应性reactivity,运行时runtime,编译器compiler,
  • 先说响应性,vue2通过Object.definedProperty()去实现响应性,但是这种方法的核心是用来监听指定对象的指定属性的get、set行为,在这种情况下,就会出现一些问题,比如说在vue2的data中声明了一个对象,那么给这个对象在后期某一个时刻去新增属性的时候,因为js本身的限制,我们没办法监听到这个对象新增的这个属性,这个时候,我们就没办法通过Object.definedProperty()去监听对应的新增属性的行为,所以新增的这个属性就不是响应式的了,vue2为了解决这个问题,提供了vue.$set的方法,这个方法本质上就是把这个属性和对象过了一遍Object.definedProperty(),这种方案从程序设计的理念上看,不是很合理,所以在vue3的时候,他提供了es6新出现的反射和代理的概念,反射指的就是reflect,代理指的就是proxy,他通过proxy来代理了一个复杂的数据类型,通过这样复杂数据类型的代理,我们得到了一个代理对象,就是proxy的实例,然后通过reflect来确定了this上的一个指向,那么此时,vue3中实现这样的一套流程的方法就是我们常见的raactive,对于proxy而言,他只能去监听复杂数据类型的响应式,而没办法监听简单数据类型的响应式,比如基本的string和int,所以vue3里面又提供了ref的方法,ref的方法本质上其实就是把内容分成了两部分,第一部分就是复杂数据类型,在vue内部会直接通过toRective的方法指向reactive,第二部分的简单数据类型,其实在内部会去处理一个refImpl,也就是ref imploment的一个接口,通过这个接口内部,他实现了两个方法,一个叫做get标记的value,一个叫做set标记的value,通过ref这样的形式,当我们去触发.value这个属性的时候,本质上就是在触发他的value方法,这是响应性上的
  • 除此之外还涉及到运行时的runtime的行为,runtime其实大部分指的就是所谓的渲染器也就是render,在这个渲染器对象里面,包含了一个我们常见的渲染函数即render函数,这个render函数内部把宿主环境,也就是所谓的浏览器,或者说是uniapp,uniapp可以使用vue进行渲染的原因,本质上就是因为vue在runtime阶段去进行了一个宿主环境和渲染逻辑的分离
  • 第三个就是所谓的编辑器,编辑器我们一般情况下分成三个阶段parse阶段,transform阶段,generate阶段,编辑器本质上就是把template,编辑成为了一个render的函数,在vue3中,他将这个阶段进行了系统的划分,我们可以直接通过baseparse把template直接转化成ast,就是动态抽象语法树,然后利用transfrom把js转化为jsast,就是js标记的抽象语法树,然后再通过generator把jsast拼接成一个render的渲染函数
  • 在vue3里面,在项目中要用到的,甚至是一些生命周期,都需要import进行动态导入,这样做的目的是为了更好的 Tree-shaking,因此可以更好地剔除不需要的代码
  • vue3中可以没有根标签,实际上他会默认将多个根标签包裹在一个fragement虚拟标签中,有利于减少内存
  • Vue 3 的代码库已经全面采用 TypeScript 重写,提供了更好的类型推断和类型提示
  • 在vue2中v-for的优先级高于v-if,可以放在一起使用,但是不建议这么做,会带来性能上的浪费,在vue3中v-if的优先级高于v-for,一起使用会报错。可以通过在外部添加一个标签,将v-for移到外层
  • diff算法不同,vue2中的diff算法,遍历每一个虚拟节点,进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方。用patch记录的消息去更新dom
    • 缺点:比较每一个节点,而对于一些不参与更新的元素,进行比较是有点消耗性能的。
  • vue3中的diff算法,在初始化的时候会给每一个虚拟节点添加一个patchFlags,是一种优化的标识。只会比较patchFlags发生变化的节点,进行视图更新。而对于patchFlags没有变化的元素作静态标记,在渲染的时候会直接复用。
  • 在使用上,目前使用vue3的话,状态管理从vuex换成了pina,事件总线使用的是mitt

前端性能如何优化

  • 前端性能优化主要有两个大方向,一个是让加载更快,一个是让渲染更快
  • 加载更快其实就是尽可能地减少网络请求,类似使用雪碧图,代码压缩打包,减少http的请求次数,合并代码,ssr服务端渲染,使用cdn,使用缓存等等
  • 让渲染更快,主要就是改变资源的渲染方式或者顺序,类似css放在head,js放在body下面,使用懒加载,对dom查询进行缓存(createDocumentFragment),使用防抖(输入框-频繁输入等一段时间再触发)和节流(拖拽-保持固定频率,一段时间只执行一次)等等

前端的打包工具有了解过吗

  • 前端打包工具主要有grunt、glup、webpack、rollup、parcel、vite等
  • grunt出现的最早,他使用配置的思想来打包脚本,一切皆可配置,但缺点是只有一个配置文件,配置项太多,如果装很多插件会显得特别乱,不同的插件也会有自己的扩展字段,需要了解各种插件的配置规则和配合方式,学习成本比较高
  • glup是基于node的steam流进行打包的,定位是基于任务流的自动化构建工具,优点是写法简单直观,适合多页面的应用开发,缺点是因为是异步的,很难控制他的执行顺序,异常处理比较麻烦,不适用单页面开发,打包方面比较弱,要自己写任务,如果有各种文件,类似图标字体等,需要单独适配,不能像webpack一样一起处理,不适用复杂项目
  • webpack主要有四大核心功能,入口、出口、loader(加载器)和插件,webpack是打包工具,gulp和grunt属于构建工具,weboack可以代替他门的一些功能,学习成本比grunt小一些,但比gulp高一些
  • rollup最大的亮点是利用es6模块设计,用标准的es6格式写代码,通过减少死代码尽可能缩小包的体积,缺点是对代码拆分、静态资源、commonJs模块支持不太友好,一般对于应用使用webpack,对于类库使用rollup,vite就是使用rollup打包的
  • parcel是快速、零配置的web应用程序打包器,内置了常见的构建方案及其依赖,能以html为入口自动检测和打包依赖资源,真正做到开箱即用,但他的缺点也很明显,配置不是很灵活

loader和plugin不同点

  • webpack将一切文件视为模块,但webpack原生只能解析js文件,如果要打包其他文件,就要用到loader,所以loader的作用是让webpack拥有加载和解析非js文件的能力
  • plugin是插件,可以扩展webpack的功能,在webpack运行的生命周期中会有很多事件,插件可以监听这些事件,在合适的时机通过werbpack提供的api改变输出结果

webpack的热加载原理

  • webpack热更新简称hmr,,当代码修改后,webpack将会对代码重新打包,将新的模块发送到浏览器端,浏览器用新的模块替换掉旧的模块,以实现不刷新浏览器的前提下刷新页面
  • Webpack-dev-server文件中有一个server类,就是通过实例化这个server类来创建服务的,创建完服务之后,通过server的listen方法传入端口号来启动服务, 在new这个server类的时候,需要将webpack配置文件以参数的形式传入,即webpack.config.js,再通过webpack的方法构建出webpack实例即compiler,这个compiler就是需要传入server类的参数
  • 再到server类中,添加webpack-dev-middleware中间件,用来提供编译后产出的静态文件服务
  • 再使用sockjs启动websocket服务在服务器和浏览器之间建立一个长链接,不过服务端传递的主要信息还是新模块的hash值,后面主要根据这个hash值来进行模块热替换
  • 最后webpack以监听模式开始编译,就实现了热更新即 compiler.watch({}, ()=>{})

web安全基础

  • sql注入
  • xss攻击
    • 标签用特殊字符表示
  • xsrf攻击
    • 用post请求,并添加验证

简单讲一下js的原型链

  • js本身就是基于原型继承的语言,在es6之前,我们只能通过写原型来继承,不像java可以通过class来继承,不过在es6之后,我们也可以通过class来继承,但只是写法上相似,它真正的继承还是原型上的继承,即es6的class本质上是原型链的一种体现
  • class的原型本质是每个类都有一个显式原型,每个实例都有一个隐式原型,实例的显式原型指向对应类的隐式原型,即子类显式原型的隐式原型指向父类的显式原型,一层层往上找,就形成了原型链
    • People.prototype === Student.prototype.__proto__
  • 原型链他实际上是js特有的,所有对象都可以共享原型上的方法,他的优势就是可以节省内存,非常方便,像我们应用场景,比如jquery,源码上就可以看到这个$就放在了jquery原型上,当我们使用$的时候,就可以很方便的拿到一些属性,还有就是我们用vue开发的时候,我们axios就放在了vue的实例上,所以我们通过$axios就可以在任何一个文件上使用了

instanceof的工作原理

  • 就按照 xialuo instanceof Object来说
    • instanceof前面的变量(xialuo),顺着隐式原型,一层层往上找,找到student、people、object的显示原型
    • 如果这个隐式原型能对应到object的显示原型,那么xialuo instanceof Object成立
  • hasOwnProperty可以判断某个属性是否是某个对象的属性
    • hasOwnProperty属于object这个原型上的方法,js中object原型链的顶层,所以类的实例都可以使用这个方法

new Object()和Object.create()的区别

  • {}等同于new Object({}),原型都是Object.prototype
  • Object.create(null)没有原型
    • 他必须传参,可以传对象,也可以传null
    • null其实是一个空对象
    • Object.create({...})没有原型的原因是他可以指定原型
      • 传入一个null,就是告诉他不要有原型
      • 传入一个对象,就是告诉他去指定原型
  • Object.create()传参之后,对象中没有值,只是将参数的对象全部将放在空对象的原型中,这是和{}最大的区别
  • Object.create()是创建一个空对象,然后把空对象的原型指向了传入的对象

this的不同应用场景,如何取值

  • 当作普通函数被调用
    • 指向window
    • 谁调用指向谁
  • 使用call、apply、bind
    • 传入什么,指向什么
  • 作为对象方法调用
    • 指向对象本身
  • class的方法中调用
    • 指向当前实例本身
  • 箭头函数
    • 找上级作用域的值来确定

event loop的过程(详细)

  • 同步代码,一行行放在call stack(调用栈)执行,调用栈执行一行,清空一行
  • 遇到异步,会先记录下,等待时机(定时、网络请求等)
    • 微任务会被放到micro task queue(微任务队列)里面等待时机
    • 宏任务会被放到Callback Queue(任务队列)里面等待时机
  • 先执行micro task queue(微任务队列)中的微任务
  • 尝试DOM渲染
  • 时机到了,就移动到Callback Queue(回调函数队列)
  • 如果call stack(调用栈)为空(即同步代码执行完),Event Loop开始工作
  • 轮询查找回调函数队列,如果有则移动到执行栈执行
    • 即执行宏任务
  • 然后继续轮询查找(永动机一样)
    • 这样异步就可以永远执行下去
  • 微任务是ES6语法规定的
    • Promise、async/await
  • 宏任务是由浏览器规定的
    • setTimeout、setInterval、Ajax、DOM事件

css垂直居中的方法

  • 如果不考虑兼容性,用flex布局实现会比较方便,在大盒子里面设置display:flex,align-items,设置center,这样就会垂直居中了,横向的话,就是justify-content也指定为center,就会水平居中了,如果不考虑兼容性的话,可以设置margin值,给他左边距设置50%,再用transform -50给他拉回来

ts面试题

  • TypeScript 是 JavaScript 的超集,为该语言添加了静态类型。它允许开发人员定义变量、函数参数和返回值的数据类型,这有助于在编译时而不是运行时捕获错误
  • TypeScript 中的静态类型可以在开发过程中指定变量、函数参数和返回值的数据类型。这有助于及早捕获与类型相关的错误,从而提高代码质量和可维护性
  • 当无法自动推断类型时,TypeScript 中的类型断言允许您显式告诉编译器变量的类型。这是使用 <type> 或 as type 语法实现的
  • TypeScript 中的泛型允许您创建可与各种类型一起使用的可重用组件或函数。它们支持强类型,同时保持使用不同数据类型的灵活性

有使用过原生js吗

  • 原生js的操作可以分为Dom操作和Bom操作,还有其他一些js api的操作,bom操作,其实就是浏览器相关的操作,比如获取浏览器信息的navigator,获取url信息的location,对浏览器url进行操作的history等
  • 对于dom操作的话,主要就是针对html元素的一些增删改查
    • 先说dom的新增,比如我们根据http请求,获取并处理好了一些数据,并组成了一段html代码片段,需要将他插入到dom里面的话,可以使用appendChild,但如果我们需要完全替换掉盒子里面的内容的话,可以使用innerHtml,如果我们为了在一个空的盒子里面需要创造一些元素的话,我们可以使用createElement,我们知道,DOM操作比较耗时,我们有时候为了避免频繁的操作dom元素,会对dom进行缓存,就需要使用到dom的代码片段,createDocumentFragment
    • 再说说dom的删除,dom的删除其实就是removeChild
    • 再说说dom的修改,dom节点的修改实际上就是将innerHtml与appendChild联合起来使用,dom节点上属性的修改,有修改对象属性property,和修改html属性两种,前者不会体现在html中,例如p.style.color,后者会改变html结构,需要使用setAttribute(键值对)、getAttribute
    • 最后说一说dom结构的查询,主要就是如何获取dom节点,比如根据id查找,根据类名查找,根据标签名查找,还有就是querySelector、querySelectorAll
  • 其他的非dom的原生js操作,有数组操作,xhr的一些操作,正则的一些操作等

map,filter,forEach的区别

  • 他们三个其实都是array的原型方法,也就是被挂载到array的prototype上面,对于foreach而言,他的本质实际上就是循环,他主要的一个作用就是可以循环一个数组,然后在循环的过程中去做一些事情,filter和map都包含返回值,对filter而言,他可以通过他的返回值来去筛选出我想要的数据,对于map而言其实也是循环,但他可以基于原数组的数据变成一个新的数组

闭包的理解

  • 闭包可用理解为能够读取其他函数内部变量的函数,或简单理解为定义在一个函数内部的函数,内部函数持有外部函数内变量的引用,闭包的话大致有两个作用,第一个是保护,第二个是保存
  • 保护的话是首选函数内部会产生一个私有作用域,不受外界干扰,在各种模块开发上实际上都可以看到闭包的影子
  • 保存的话就是,当一个函数返回了一个引用数据类型,并且被外界所接收,就会形成一个不销毁的作用域,他就会一直存在在堆内存中,但也很容易造成内存泄漏
  • 内存泄漏的话,其实就是浏览器无法回收这个代码的内存,比如说一个对象,或者是一个数组

什么时候用margin,什么时候用padding

  • 同级盒子一般使用margin
  • 父子盒子一般使用padding
  • 因为父子盒子用margin很容易造成塌陷问题
  • 最常用的方式就是超出部分进行隐藏,就是overflow hidden,
  • 超出部分隐藏的原理实际上就是产生一个块格式化上下文bfc,当我们产生一个bfc的时候,就会根据这个块级格式化上下文的规则去渲染我们的页面,他和我们html的渲染是分开的,他不存在margin塌陷,所以就可以解决这个问题

flex布局

  • 在最外部盒子中设置flex之后,在当前盒子可以设置一些属性,比如flex-direction可以改变items的流向,flex-wrap可以设置是否折行,justify-content可以设置主轴的对齐方式,align-items可以设置交叉轴对齐方式
  • 在子元素上可以使用align-self设置子元素的对齐方式

在开发中遇到的最大问题是什么

  • 考核你解决项目问题的能力
    • avue项目
      • 之前有家公司做项目用的avue,avue里面的api比较简单,也有些bug
      • avue主要是element-ui的集成,主要是针对一些简单的表格的,他的筛选、表格、分页都是写在一起的
      • 但对于复杂的表格,比如一个tab页里面有两个表格全是前端维护的,表格里面有按钮,按钮点进去会触发另一个表格,表格里面还有文本框下拉框以及还有各种校验,一个下拉菜单有很多限制,触发一个下拉菜单会对表格文本框做一些禁用或者显示隐藏,点击提交会在父表格增加一条记录同时影响另外的表格,这种avue坑就有很多
    • git方面有
      • 由于我有段时间有管理团队,团队开发用的是git,我那时候git基本都可以用,但分支这块用的不熟,所以找时间把分支系统了解了一下
      • 还有就是我的博客用的是github page,但现在github使用https上传很麻烦,会经常push不上去,捣鼓了很久,用ssh上传解决了
      • 还有的就是我的博客,vuepress里面加上评论和阅读量找了一些插件
    • 部署项目
      • 做管理的那段时间,领导要求我去部署前后端项目,在安装nginx的时候出了点问题,导致他不能访问,后来排查出来时防火墙的问题
      • 在客户端部署nginx服务的时候,有时候因为vue项目里面的接口是走代理的,nginx也要配置相应的代理
      • 服务器上有些东西需要加密,可以在nginx上配置密码
      • 部署三维模型的时候,模型和项目是分开部署的,都是在nginx里面,模型的请求一直出现跨域,后来配置了nginx-cros才解决问题
    • 新东西
      • 之前公司在做数据中台的时候需要用elk
      • 使用es存储数据最大的问题是es如何与前端框架结合,我后来使用proxy代理的方法,然后在某个js里面封装es增删改查语法,才在项目里用起来
      • 用node做爬虫的时候,由于有很多反爬虫机制,后来我用nightmare这个库来模拟浏览器操作,才解决了问题
    • 剩下的就是模型上的一些问题了
      • 更多的是模型数据上的处理以及模型如何与硬件设备一一对应
        • 最大的问题是模型数据如何在场景里面去使用,后面了解到3dtiles,后面慢慢摸索,可以把各种类型的像dae、obj、oggb、bim转换成3dtiles,并在页面中渲染
        • 3维场景里面的最大问题是浏览器崩溃和锯齿,通过了解一系列cesium配置,可以把影响降低到最小
        • 在业务场景中有的不是点击标注做的交互,要直接点击模型,后面了解到模型的单体化,和数据进行沟通交流,才把问题解决
    • 最后是项目管理的一些坑
      • 其实也不能说是坑,项目把控的时候要做excel表格,主要是我那时候不熟悉,后面excel熟练了一些

三维相关的一些东西

2.1.1.2. 三维可视化有哪些主要的引擎
  • webgl
    • three.js
    • cesium.js
      • marsv.js => 火星科技,在cesium的基础上封装
2.1.13. 我了解到的三维可视化知识点

主要是cesium

  • 加载地球
    • 加载地球底图
      • 底图类型
        • 天地图
        • 高德地图
        • 谷歌地图
        • 百度地图
        • 微软地图 => bingMap
      • 底图功能
        • 基础底图
          • 可显示所在点的经度、纬度、海拔、方向以及视高
        • 复位底图
          • 点击后回到指定视区
        • 视图
          • 可切换三维视图、二维视图、哥伦布视图
        • 全屏
        • 方向盘操作
          • 按下鼠标左键并向四周拖拽不释放可修改视图角度,双击重置视图;单击并拖拽旋转,修改视角方向
        • 鼠标右键
          • 可显示此处经纬度、显示当前视角信息、开启光照效果、开启深度检测、绕此处环绕飞行、移动到此处、第一视角站到此处
      • 注意事项
        • 主要是一些地图的底图,每个地图加密算法不一样,坐标点不一样,天地图未经过加密,其他地图坐标都是通过天地图的坐标转换而来的
    • 加载地球模型
      • 主要用3dtiles来加载模型
        • 主要用cesiumlab工具处理导出
        • 3D Tiles是用于流式传输大规模异构3D地理空间数据集的开放规范。为了扩展Cesium的地形和图像流,3D Tiles将用于流式传输3D内容,包括建筑物,树木,点云和矢量数据。
        • 3D Tiles是由一个从一开始就使用WebGL的团队设计的,而OpenGL在此之前已经使用了很多年。因此,与glTF一样,从接收3D Tile到使用WebGL渲染3DTF的流程简化为快速简单,并最大限度地减少客户端处理。为了减少WebGL绘制调用的数量,可以预先批量处理或批量处理切片。
        • 3dtiles有两种方法直接获取模型数据,第一个是用geojson盖在上面,第二个是处理模型的时候分开,然后用单体化的类去获取
    • 加载模型数据格式(这里的都是较大场景)
      • 单模型场景
        • 即把所有场景效果改成false
      • 倾斜摄影
        • 原格式为osgb,由无人机飞行得来,用cesiumlab可以转化成3dtiles
      • 城市建筑白模
        • 原格式为dae,因为没有贴图,模型较小,用cesiumlab可以转化成3dtiles
      • 人工模型
        • 原格式为dae,在白模的基础上加上贴图,有精模和简模之分,模型很大
      • bim数据
        • 建筑模型,单体化比较好做,原格式为dae,用cesiumlab可以转化成3dtiles
    • 小模型加载 => gltf
      • GLTF——3D图形界的JPEG
      • glTF(GL TransmissionFormat),即图形语言交换格式,它是一种3D内容的格式标准,由Khronos Group管理(Khronos Group还管理着OpenGL系列、OpenCL等重要的行业标准);
      • glTF的设计是面向实时渲染应用的,尽量提供可以直接传输给图形API的数据形式,不再需要二次转换
      • glTF对OpenGL ES、WebGL非常友好
      • glTF的目标是:3D领域的JPEG
      • 作为一个标准,自2015年10月发布(glTF 1.0)以来,已经得到了业界广泛的认可,你可以相信它的水平
      • GLTF具体的信息可以去官方网站上看:https://www.khronos.org/gltf/
  • 地球标注
    • 单个点
      • 点、图标点、文字、小模型
    • 二维空间、二维贴地
      • 有深度检测功能
      • 线、曲线、面、圆、矩形
    • 三维空间
      • 墙、立体、圆柱体、矩形体
  • 场景控制
    • 开场动画
    • 旋转的地球
    • 双屏对比
      • 加载不同的地球底图
    • 鹰眼
      • 小地图
      • 大部分是二维地图
  • 巡更漫游
    • 显示隐藏巡更线
    • 增删改巡更路线
    • 开始巡更、停止巡更、暂停巡更
    • 打开关闭深度检测
    • 开启摄像头
      • 巡更到某个位置会打开摄像头
      • 监控视频格式主要是*.w3u8
      • 主要使用videojs插件

2.1.2 三维可视化业务场景

2.1.2.1 模型部分
  • 加载模型
  • 标注的增删改查
  • 视点的增删改查
  • 巡更的增删改查
    • 关键点事件处理(一般是加载视频)
  • 其他
    • 单体化……
    • 视频投影……
2.1.2.2 硬件设备
  • 需要对接一些硬件设备信息
    • 展现方式为标注
    • 硬件设备信息详情主要是:
      • 文字信息(大部分不是实时的)
      • 图片信息(需要实时或者普通接口)
      • 视频-摄像头(一般使用hls进行对接【对方提供*.m3u8格式视频流】)
2.1.2.3 统计图
  • 二维或者三维,统计设备信息
2.1.2.4. 布局
  • 设备报警信息放哪里
  • 相关统计图放的位置
  • 哪些页面放哪些模块

2.2. 后台管理

  • 封装了axios
  • 配置了nginx,使vue使用proxy之后打包可以正常运行
  • 封装了若干插件
    • 进度条、上传、 quill 富文本、使用 i18n 实现国际化等

最近有看过什么书,有什么心得

介绍最近两个公司的工作经历

javascirpt中的数字在计算机内存储为多少Byte?