前端面试提问(4)
1、手撕防抖与节流、树与对象的转换、递归调用,链表头插法
1.1、防抖
防抖函数用于延迟执行某个函数,直到过了一定的间隔时间(例如等待用户停止输入)后再执行。
即后一次点击事件发生时间距离一次点击事件至少间隔一定时间。
function debounce(fn, wait) {let timer = nullreturn function () {if (timer) {clearTimeout(timer)timer = null}timer = setTimeout(() => {fn.call(this, arguments)}, wait)}
}
1.2、节流
节流函数用于限制函数的执行频率,确保一定时间内只执行一次。
//时间戳版
function throttle(fn, wait) {let date = Date.now()return function () {let now = Date.now()if (now - date > wait) {fn.call(this, arguments)date = now}}
}
//定时器版
function throttle(fn, wait) {let timer = nullreturn function () {if (!timer) {timer = setTimeout(() => {fn.call(this, arguments)timer = null}, wait)}}
}
1.3、树与对象的转换
参考作者之前的文章
2、水平垂直居中方法
①flex布局,父元素display:flex; justify-content:center; align-items:center;
②父元素position:relative; 子元素position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
③父元素position:relative; 子元素position:absolute; left:0; top:0; bottom:0; right:0; margin:auto;
④文字的话, text-align:center; line-height 和 height 相等
3、 手写ajax(使用promise封装)
function getJSON(url) {let promise = new Promise((resolve, reject) => {let xhr = new XMLHttpRequest()xhr.open("GET", url, true)xhr.onreadystatechange = function () {if (this.readyState !== 4) returnif (this.status === 200) {resolve(this.response)} else {reject(new Error(this.statusText))}}xhr.onerror = function () {reject(new Error(this.statusText))}xhr.responseType = "json"xhr.setRequestHeader("Accept", "application/json")xhr.send(null)})return promise
}
4、扁平数组
const flatten = (arr) => {return arr.reduce((pre, cur) => {return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);}, []);
};arr1 = [1, [2, 3], [4, [5, [6, 7], 8]]];
5、setTimeout实现setInterval
function myInterval(func, time) {let ids = [];function fn() {let id = setTimeout(() => {func();fn();}, time);ids.push(id);}fn();return ids;
}let id = myInterval(() => {console.log("Hello World");
}, 500);function clearMyInterval(idList) {idList.forEach((id) => {clearTimeout(id);});
}setTimeout(() => {clearMyInterval(id);
}, 3000);
6、输入url发生了什么?
-
URL 解析: 浏览器解析输入的 URL。
-
DNS 解析: 如果域名需要解析,进行 DNS 解析。如果已经有缓存的 DNS 记录,可以跳过此步骤。
-
检查缓存: 浏览器检查缓存,看是否已经有了之前请求过的资源的副本。这包括检查浏览器缓存和可能存在的代理服务器缓存。
-
有缓存: 如果资源已经存在于缓存中,并且没有过期,浏览器可以跳过后续的步骤,直接使用缓存中的资源渲染页面。
-
无缓存或缓存过期: 如果资源不存在于缓存中,或者缓存已经过期,浏览器将按照正常的流程发起网络请求,
-
TCP 连接:拿到IP地址后,三次握手建立TCP连接,https的话还需要进行TLS加密协议的握手过程
-
发送请求,获取响应:连接建立成功之后,浏览器会构建请求行、cookie等数据附加到请求头中,发给服务器,服务器接受请求并解析,如果没有对应的资源就404;否则检查HTTP请求头有没有包含协商缓存信息(前面命中强缓存且已过期的话就会走这个步骤),如果验证缓存没有更新,过期的缓存依然可以使用,就返回304和空响应体;如果没有缓存或者资源更新了,就读取完整请求并准备http响应,进行查询数据库等操作,返回200和查询到的资源
-
TCP 连接: 浏览器接收到响应数据之后,如果是http1.1以下则直接关闭连接,否则双方都可以根据情况选择关闭TCP连接或者保留重用,现在浏览器默认都会保持连接(keep-alive)
-
浏览器渲染: 浏览器使用获取到的资源渲染页面。
缓存是一种重要的性能优化手段,可以减少网络请求,加快页面加载速度。缓存策略通常由服务器端和浏览器端一起决定,可以通过 HTTP 头部信息来进行配置。例如,使用 Cache-Control
头部可以控制缓存的行为,而 ETag
和 Last-Modified
头部可以用于验证缓存是否过期。
7、加载js和css会不会阻塞页面渲染
css用link和@import的情况
link标签引入css资源时在火狐浏览器中是异步加载的,在谷歌浏览器中是同步加载的。
但如果是通过style标签引入样式,则不论何种浏览器,均为同步加载。
@import是在网页完全载入后才加载,在关键路径上创造了更多的网络请求,阻塞渲染时间,影响浏览器的并行下载,多个@import导致下载顺序紊乱。
8、重排重绘
重排:当渲染树的一部分必须更新并且节点的尺寸发生了变化,浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。
①添加、删除可见的dom②元素的位置改变
③元素的尺寸改变(外边距、内边距、边框厚度、宽高等几何属性)
④页面渲染初始化
⑤浏览器窗口尺寸改变
重绘:是在一个元素的外观被改变所触发的浏览器行为,浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
如何减少reflow、repaint?
①不要一条一条的修改DOM的样式,可以先定义好css的class,然后修改DOM的className。
②不要把DOM结点的属性值放在一个循环里当成循环里的变量。
③为动画的HTML元件适用fixed或absolute的position,那么修改他们的css是不会reflow
9、深浅拷贝
浅拷贝:基本数据类型、扩展运算符()、slice()、concat()、Object.assign()深拷贝:JSON.parse(JSON.stringify())、手写深拷贝、lodash
手撕深拷贝
let obj = {lili: { name: "lili", person: ["lisan", "zhangsan"] },arr: [1, 2, 3, 4],fruit: "apple",
};
function deepclone(obj) {// 检查是否是基本数据类型,如果是则直接返回if (obj === null || typeof obj !== "object") {return obj;}if (Array.isArray(obj)) {let newArray = [];for (let i = 0; i < obj.length; i++) {newArray[i] = deepclone(obj[i]);}return newArray;} else {let newObj = {};for (const key in obj) {if (obj.hasOwnProperty(key)) {newObj[key] = deepclone(obj[key]);}}return newObj;}
}
console.log(deepclone(obj));
10、手撕合并函数
function deepMerge(target, source) {// 检查参数类型if (typeof target !== "object" || typeof source !== "object") {throw new Error("Both target and source must be objects");}// 遍历source对象的属性for (const key in source) {if (source.hasOwnProperty(key)) {// 如果属性是对象且存在于target中,递归深度合并if (typeof source[key] === "object" &&source[key] !== null &&target.hasOwnProperty(key) &&typeof target[key] === "object" &&target[key] !== null) {if (Array.isArray(target[key])) {target[key] = [].concat(target[key], source[key]);} else {target[key] = deepMerge(target[key], source[key]);}} else {// 否则直接赋值// target[key] = source[key];target[key] = [].concat(target[key], source[key]);}}}return target;
}// 使用例子
const targetObject = {name: "John",age: 30,address: {city: "New York",zip: "10001",people: { class: "1班" },},hobbies: ["shopping"],
};const sourceObject = {age: 31,address: {zip: "10002",},hobbies: ["reading", "traveling"],
};const resultObject = deepMerge(targetObject, sourceObject);
console.log(resultObject);
11、Object和map
共同点:键值对的动态集合,支持增删
不同点:
①构造方式不同
//map const map = new Map() const map1 = new Map([['a',1],['b',2]]) //obj const obj = new Object() const obj1 = Object.create()
②object键的类型必须是String或者Symbol、map键的类型可以是任意类型
③object中key是无序的,map中可以是有序的,按照插入的顺序返回
④object只能通过Object.key()方法或for in统计数量,map有map.size
⑤object可以通过点或中括号访问属性,map用map.get()
⑥object不具备Iterator特性,不能for of遍历,map的keys()、values()、entries()都具有迭代器
⑦object可以用JSON.stringify()进行序列化,map只能转化成JSON,不能被parse解析
⑧应用场景:object做数据存储,需要序列化时使用;map频繁更新键值对,key类型未知时使用
12、http和https的区别
①https协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
②http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl/tls加密传输协议。
③http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
④http的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
13、堆和栈
13.1、区别
①堆栈空间分配区别(操作系统):
栈由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;
堆 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
②堆栈缓存方式区别:
栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放;
堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。
③堆栈数据结构区别:
栈是一种先进后出(FILO)的数据结构;
堆可以被看成是一棵树,如:堆排序。
13.2、最大堆和最小堆?
最大堆:根结点的键值是所有堆结点键值中最大者,且每个结点的值都比其孩子的值大。
最小堆:根结点的键值是所有堆结点键值中最小者,且每个结点的值都比其孩子的值小。
13.3、 堆栈溢出
- JavaScript 的函数调用栈有一定大小限制,当函数调用的嵌套层数过多时,会导致栈溢出错误。
function recursive() {// 递归出现栈溢出recursive();
}
recursive();
- JavaScript 的堆也有大小限制。堆是用来存储变量和对象等数据的一段内存空间,当我们创建了大量数据或者数据太大而超过了堆的容量时,就会触发堆溢出错误。
let arr = [];
while (true) {// 堆溢出arr.push('a');
}
14、进程和线程
进程:一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间,一个进程可以有多个线程。
线程:进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程至少有一个线程,一个进程可以运行多个线程,多个线程可共享数据。
进程和线程的区别:
①进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位)
②进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。
而线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多。
③线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC) 进行。
④但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间。
15、promise.all,promise.any,promise.race,promise allsettled
Promise.allSettled
不会在其中一个 Promise 失败时立即 reject,而是等待所有 Promise 完成后再返回结果。
const promise1 = Promise.resolve(42);
const promise2 = Promise.reject("Oops!");
const promise3 = new Promise((resolve) => setTimeout(() => resolve("Done!"), 1000));Promise.allSettled([promise1, promise2, promise3]).then((results) => {console.log(results);// results 包含了每个 Promise 的状态和结果// [{ status: 'fulfilled', value: 42 }, { status: 'rejected', reason: 'Oops!' }, { status: 'fulfilled', value: 'Done!' }]}).catch((error) => {console.error("Error:", error);});
Promise.all
在所有 Promise 全部成功(resolved)时才会成功,但只要有一个 Promise 失败(rejected),整个 Promise.all
就会立即失败。这种行为被称为“一败俱败”。
传递给 Promise.all
的数组为空: 如果传递给 Promise.all
的 Promise 数组为空,返回的 Promise 会立即被解决为一个空数组。
如果在某一个promise中reject后,那一个函数捕捉catch,就不会报错。不然就会走all的catch
16、场景题:100000条数据渲染
const renderList = async () => {const list = await getList()const total = list.lengthconst page = 0const limit = 200const totalPage = Math.ceil(total / limit)const render = (page) => {if (page >= totalPage) returnsetTimeout(() => {for (let i = page * limit; i < page * limit + limit; i++) {const item = list[i]const div = document.createElement('div')div.className = 'sunshine'div.innerHTML = `<img src="${item.src}" /><span>${item.text}</span>`container.appendChild(div)}render(page + 1)}, 0)}render(page)
17、你做的项目如何部署到服务器
function myNew(constructor, ...args) {// 步骤 1:创建一个新的空对象const obj = {};// 步骤 2:将新对象的 __proto__ 指向构造函数的 prototype 属性obj.__proto__ = constructor.prototype;// 步骤 3:将构造函数的上下文传递给构造函数,并执行构造函数const result = constructor.apply(obj, args);// 步骤 4:如果构造函数返回一个对象,则返回该对象;否则,返回新创建的对象return result instanceof Object ? result : obj;
}
18、路由鉴权
18.1、请求数据
-
用户登录: 用户在登录时,通过用户名和密码等方式向后端发起登录请求。后端验证用户身份,并在登录成功后生成一个 Token。
-
Token 存储: 将生成的 Token 存储在前端,通常是通过 localStorage。axios请求拦截,如果存在token,在每次请求时自动附加到请求头。
-
请求时携带 Token: 在每次请求后端受保护资源时,将 Token 携带在请求头中,通常是通过 Authorization 头或自定义头。
-
后端验证 Token: 后端接收到请求后,通过解析 Token 验证用户身份和权限。如果 Token 有效且权限足够,则返回相应资源;否则,返回错误状态。
18.2、路由守卫
根据权限决定跳转: 如果用户拥有访问权限,正常放行,让用户访问受保护页面。如果用户没有权限,可以将其重定向到登录页或其他提示页面,或者显示相应的提示信息。
// 路由表
const routes = [{ path: '/', component: Home, meta: { requiresAuth: true } },{ path: '/admin', component: Admin, meta: { requiresAuth: true, requiresAdmin: true } },{ path: '/login', component: Login }
];// 创建路由实例
const router = new VueRouter({routes
});// 路由守卫
router.beforeEach((to, from, next) => {const isAuthenticated = /* 根据用户身份信息判断用户是否已登录 */;const isAdmin = /* 根据用户身份信息判断用户是否是管理员 */;if (to.meta.requiresAuth && !isAuthenticated) {// 用户未登录,重定向到登录页next('/login');} else if (to.meta.requiresAdmin && !isAdmin) {// 用户不是管理员,可以根据需要进行处理,例如重定向到首页next('/');} else {// 用户有权限,放行next();}
});// 在 Vue 实例中使用路由
new Vue({el: '#app',router,render: h => h(App)
});
18.3、不同等级的权限控制
-
获取用户权限信息: 在用户登录成功后,获取token与用户的权限信息,存储在Vuex或者localStorage
-
定义菜单权限配置: 在前端定义一个菜单权限配置,包含不同权限下允许访问的菜单项。这可以是一个简单的 JSON 对象或数组,其中每个菜单项都包含一个权限属性,表示需要的用户权限。
-
根据用户权限过滤菜单项: 根据用户拥有的权限,从菜单权限配置中筛选出符合条件的菜单项。
-
动态生成菜单: 使用框架或库的路由功能,根据过滤后的菜单项动态生成菜单。这可以在页面加载时或用户登录成功后执行。
// 菜单权限配置
const menuConfig = [{ path: '/dashboard', name: 'Dashboard', permission: 'view_dashboard' },{ path: '/users', name: 'Users', permission: 'manage_users' },// 其他菜单项
];// 获取用户权限信息(模拟)
const userPermissions = ['view_dashboard', 'manage_users']; // 实际中应该根据登录成功后的用户信息获取权限// 根据用户权限过滤菜单项
const userMenu = menuConfig.filter(item => userPermissions.includes(item.permission));// 在 Vue 实例中使用路由
const router = new VueRouter({routes: userMenu,
});// 示例组件中动态生成菜单
Vue.component('Sidebar', {template: `<div><router-link v-for="item in userMenu" :to="item.path" :key="item.path">{{ item.name }}</router-link></div>`,data() {return {userMenu,};},
});// 在 Vue 实例中使用路由和菜单组件
new Vue({el: '#app',router,render: h => h(App),
});
相关文章:
前端面试提问(4)
1、手撕防抖与节流、树与对象的转换、递归调用,链表头插法 1.1、防抖 防抖函数用于延迟执行某个函数,直到过了一定的间隔时间(例如等待用户停止输入)后再执行。 即后一次点击事件发生时间距离一次点击事件至少间隔一定时间。 …...

基于BEV+Transformer的地面要素感知+建模技术在高德的应用
导读 本文将主要介绍BEVTransformer端到端感知与建模技术在高德各项业务中的应用,如高精地图中地面要素(包含线要素和地面标识)自动化上的具体方案及其演化过程。该方案使用BEVTransformer技术来实现采集车上不同传感器(包含激光和…...

了解c++11中的新增
一,统一的初始化列表 在引入c11后,我们得出计划都可以用初始化列表进行初始化。 C11 扩大了用大括号括起的列表 ( 初始化列表 ) 的使用范围,使其可用于所有的内置类型和用户自 定义的类型, 使用初始化列表时,可添加等…...

104. 二叉树的最大深度(Java)
目录 解法: 官方解答: 方法一:深度优先搜索 方法二:广度优先搜索 思路与算法 复杂度分析 时间复杂度: 空间复杂度: 给定一个二叉树 root ,返回其最大深度。 二叉树的 最大深度 是指从根…...

SpringSecurity6 | 自定义认证规则
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏…...

浅析安科瑞电动机保护器在广州某地铁项目的设计与应用-安科瑞 蒋静
1 摘要 随着城市的发展,较多城市的轨道交通选择修建地下式车辆段(或停车场),即车辆段(或停车场)位于地下或设置有上盖(上盖上再做物业开发)。为了给工作人员提供良好的工作环境、给…...
LeetCode 2048. 下一个更大的数值平衡数
【LetMeFly】2048.下一个更大的数值平衡数 力扣题目链接:https://leetcode.cn/problems/next-greater-numerically-balanced-number/ 如果整数 x 满足:对于每个数位 d ,这个数位 恰好 在 x 中出现 d 次。那么整数 x 就是一个 数值平衡数 。…...

多线程(初阶七:阻塞队列和生产者消费者模型)
目录 一、阻塞队列的简单介绍 二、生产者消费者模型 1、举个栗子: 2、引入生产者消费者模型的意义: (1)解耦合 (2)削峰填谷 三、模拟实现阻塞队列 1、阻塞队列的简单介绍 2、实现阻塞队列 &#…...
区间价值 --- 题解--动态规划
目录 区间价值 题目描述 输入描述: 输出描述: 输入 输出 备注: 思路: 代码: 区间价值 J-区间价值_牛客竞赛动态规划专题班习题课 (nowcoder.com) 时间限制:C/C 2秒,其他语言4秒 空间限制:C/C 262144K&…...

计算机毕业设计 基于大数据的心脏病患者数据分析管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...

20:kotlin 类和对象 --泛型(Generics)
类可以有类型参数 class Box<T>(t: T) {var value t }要创建类实例,需提供类型参数 val box: Box<Int> Box<Int>(1)如果类型可以被推断出来,可以省略 val box Box(1)通配符 在JAVA泛型中有通配符?、? extends E、? super E&…...

我对迁移学习的一点理解(系列2)
文章目录 我对迁移学习的一点理解 我对迁移学习的一点理解 源域和目标域是相对的概念,指的是在迁移学习任务中涉及到的两个不同的数据集或领域。 源域(Source Domain)通常指的是已经进行过训练和学习的数据集,它被用来提取特征、…...

Spring MVC学习随笔-控制器(Controller)开发详解:控制器跳转与作用域(二)视图模板、静态资源访问
学习视频:孙哥说SpringMVC:结合Thymeleaf,重塑你的MVC世界!|前所未有的Web开发探索之旅 衔接上文Spring MVC学习随笔-控制器(Controller)开发详解:控制器跳转与作用域(一) SpingMVC中…...
原型模式(Prototype Pattern)
1 基本概念 1.1 大佬文章 设计模式是什么鬼(原型) 详解设计模式:原型模式-腾讯云开发者社区-腾讯云 1.2 知识汇总 (1)原型模式:先 new 一个实例,该实例符合需求,之后再根据这个实…...

IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket
文章目录 1. 引言2. 短轮询(Short Polling)2.1 原理2.2 代码示例2.2.1 服务器端(Node.js)2.2.2 客户端(HTML JavaScript) 3. 长轮询(Long Polling)3.1 原理3.2 代码示例3.2.1 服务器…...

04_W5500_TCP_Server
上一节我们完成了TCP_Client实验,这节使用W5500作为服务端与TCP客户端进行通信。 目录 1.W5500服务端要做的: 2.代码分析: 3.测试: 1.W5500服务端要做的: 服务端只需要打开socket,然后监听端口即可。 2…...

入门Redis学习总结
记录之前刚学习Redis 的笔记, 主要包括Redis的基本数据结构、Redis 发布订阅机制、Redis 事务、Redis 服务器相关及采用Spring Boot 集成Redis 实现增删改查基本功能 一:常用命令及数据结构 1.Redis 键(key) # 设置key和value 127.0.0.1:6379> set …...

SpringSecurity6 | 自定义登录页面
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏…...
从单向链表中删除指定值的节点
输入一个单向链表和一个节点的值,从单向链表中删除等于该值的节点,删除后如果链表中无节点则返回空指针。 链表的值不能重复。构造过程,例如输入一行数据为:6 2 1 2 3 2 5 1 4 5 7 2 2则第一个参数6表示输入总共6个节点,第二个参数…...

Vue2与Vue3的语法对比
Vue2与Vue3的语法对比 Vue.js是一款流行的JavaScript框架,通过它可以更加轻松地构建Web用户界面。随着Vue.js的不断发展,Vue2的语法已经在很多应用中得到了广泛应用。而Vue3于2020年正式发布,带来了许多新的特性和改进,同时也带来…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
django blank 与 null的区别
1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是,要注意以下几点: Django的表单验证与null无关:null参数控制的是数据库层面字段是否可以为NULL,而blank参数控制的是Django表单验证时字…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器
一、原理介绍 传统滑模观测器采用如下结构: 传统SMO中LPF会带来相位延迟和幅值衰减,并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF),可以去除高次谐波,并且不用相位补偿就可以获得一个误差较小的转子位…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...