个人初级前端能想到的面试题

让盒子水平垂直居中

第一种方式 -> 使用flex布局方式

<style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .father {
            height: 100vh;
            width: 100vw;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: red;
        }
</style>


<body>
     <div class="father">
         <div class="son">

         </div>

     </div>
</body>

第二种方式 -> 使用定位

<style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .father {
            height: 100vh;
            width: 100vw;
            position: relative;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
            left: 50%;
            top: 50%;
        transform: translate(-50%,-50%);
        }
</style>

<body>
     <div class="father">
         <div class="son">

         </div>

     </div>
</body>

第三种方式 -> flex+margin

  <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .father {
            height: 100vh;
            width: 100vw;
            display: flex;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: red;
            margin: auto;
        }
 </style>

<body>
     <div class="father">
         <div class="son">

         </div>

     </div>
</body>

第四种方式 -> gird布局

 <style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }
        .father {
            height: 100vh;
            width: 100vw;
            display: grid;
            justify-content: center;
            align-items: center;
        }
        .son {
            width: 100px;
            height: 100px;
            background-color: red;
            margin: auto;
        }
 </style>

<body>
     <div class="father">
         <div class="son">

         </div>

     </div>
</body>

第五种方式 -> table布局

<style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: border-box;
        }

        .father {
            height: 100vh;
            width: 100vw;
            display: table-cell;
            vertical-align: middle;
            text-align: center;
        }

        .son {
            display: inline-block; //这个必须是内联元素,也就是行内块
            width: 100px;
            height: 100px;
            background-color: red;
        }
</style>

<body>
<div class="father">
    <div class="son">

    </div>

</div>
</body>

设置小于12px的文字

transform: scale(); 这个属性

1,scale会整体缩放,这样会造成块级元素也缩小,造成比例不协调。

2,缩放默认以中心点缩放,缩放后整体剧中,造成ui不协调。

<style>

p {
       transform: scale(0.5);
       transform-origin:0 0; // transform-origin属性表示在对元素进行变换的时候,设置围绕哪个点进行变化的
   }

</style>

<p>
    你好我是小于12px的文字
</p>
这就是小于12px的文字

 HTML5新加了那些元素

1. header标签 : 头部标签

2. footer标签:底部标签

3. nav标签:导航标签

4.Canvas属性:画布

5. 存储:增加了localstorage和sessionstorage两个客户端存储机制

6. indexDB:浏览器中存储结构化数据的方法,可以使用这个API来创建复杂的数据库应用程序

7. 语音和视频:audio video

8. 增加了语义化标签的好处

  • 没有css的时候也可以有清晰的页面结构
  • 有利于SEO和搜索引擎建立良好的沟通,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重
  • 方便团队开发和维护,语义化更具可读性,遵循W3C标准的团队都遵循这个标准,可以减少差异化

块级元素,行内块元素,行内元素三者区别

  1. 块级元素 ->   元素的宽度如果不设置的话,默认为父元素的宽度(父元素宽度100%),有自己的宽度和高度,可以自定义自己的宽高
    • 独占一整行
    • 可容纳全部元素
    • 高度,宽度,行高,外边距(margin)以及内边距(padding)都可以控制
    • 多个块状元素标签写在一起,默认排列方式为从上至下;
    • div   h1-h6 ul li p ol table 都是块级元素
  2. 行内元素 ->  行内元素不可以设置宽(width)和高(height),但可以与其他行内元素位于同一行,行内元素内一般不可以包含块级元素
    • 一般由文字大小控制宽高
    • 高宽、行高无效,对外边距(margin)和内边距(padding)仅设置左右方向有效,上下无效
    • span  a i em b 都是行内元素
  3. 行内块元素 -> 行内块级元素,它既具有块级元素的特点,也有行内元素的特点,它可以自由设置元素宽度和高度,也可以在一行中放置多个行内块级元素
    • 高度、行高、外边距以及内边距都可以控制
    • 默认宽度就是它本身内容的宽度,不独占一行,但是之间会有空白缝隙,设置它上一级的 font-size 为 0,才会消除间隙

        总结:

                1.块元素会独占一整行,行内块元素和行内元素可以在一行显示

                2. 块级元素和行内块元素可以控制自己的宽高,行内元素不可以

src和href区别

src属性是脚本文件,图像文件,音频,视频等,表示当前文档中嵌入资源

href属性是 只定超链接目标资源的地址,通常连接到其他html文档,样式表

src针对的标签有script audio vedio 用于引入相应资源

href用于a link  用于创建链接

src对文档有直接的影响,当运行到src指向的资源的时候,会暂停其他资源的加载和文档的渲染知道该资源被下载完成

href指向的资源再被运行到的时候是异步的不会阻塞文档的下载

可选性不同。src属性是必需的,如果没有指定src属性,则浏览器会认为该标签是无效的;href属性是可选的,如果没有指定href属性,则标签仍然是有效的。

link和@impoer区别

页面导入外部css文件的方法通常有两种,一种在网页中直接link标签加入,另一种在页面中@import引入css文件。两种引入形式如下:
link引入形式:

<link href="index.css" type="text/css" />


@import引用形式:

<style type="text/css">
    @import url("index.css");
</style>


1. @import可以在网页页面中使用,也可以在css文件中使用,用来将多个css文件引入到一个css文件中;而link只能将css文件引入到网页页面中。

2.link属于XHTML标签,而@import是CSS提供的一种方式,link标签除了可以加载CSS外,还可以定义rel连接属性,定义RSS等,@import就只能加载CSS。
3. 页面被加载的时候,link引用的CSS会同时被加载,而@import引用的CSS会等到页面全部被下载完再被加载。所以有时候浏览@import加载CSS的页面时开始会没有样式(就是闪烁)
4.@import是css2.1提出的,所以老的浏览器不支持,@import只有在IE5以上的才能识别,而link标签无此问题。
5. 使用link方式可以让用户切换CSS样式.现代浏览器如Firefox,Opera,Safari都支持rel=”alternate stylesheet”属性(即可在浏览器上选择不同的风格),当然你还可以使用Javascript使得IE也支持用户更换样式。
6. 当使用JavaScript控制DOM去改变样式的时候,只能使用link标签,因为@import不是DOM可以控制的。

display:none与visibility:hidden与overflow:hidden的区别?

overflow:hidden 让超出的元素隐藏,就是在设置该属性的时候他会根据你设置的宽高把多余的那部分剪掉

display:none 表示彻底消失,不在文档流中占位,浏览器也不会解析该元素(看不见摸不着);

visibility:hidden 表示视觉上消失了,可以理解为透明度为0的效果,在文档流中占位,浏览器会解析该元素(看不到摸不着);

opacity:0 表示看不见摸得着,元素隐藏,依然占据空间;

display:none 不会被继承直接消失了

visibility:hidden 和opacity:0 会被继承

display: none,会产生回流和重绘,性能较差。
visibility: hidden, 动态改变此属性会引起重绘,性能较高。
opacity: 0,提升为合成层,不会触发重绘,性能较高。

页面渲染过程 个人理解

  1. 解析HTML生成dom树 浏览器无法直接使用HTML需要转化为浏览器能理解的结-> Dom树 先读取HTML文档把字节转化为字符再转化为节点通过节点构建Dom树
  2. 解析CSS生成CSSOM树和HTML的解析过程同步执行,浏览器将识别所有的CSS样式信息,生成CSSOM树
  3. dom树和cssom树结合生成渲染树(render tree) 有Dom树和CSSOM合并成,计算大小,位置等布局信息
  4. 生成布局 将dom和cssom的样式信息结合,计算大小,位置等
  5. 绘制 根据渲染树和布局信息将页面绘制到屏幕上
  • 重排(回流):是布局或者几何属性需要改变就称为重排(回流)。
  • 但是如果过程中发生了元素样式改变,可能会触发页面的重排(reflow)和重绘(repaint)
  • 当元素的布局更改的时候会触发重排.重排一定会出发重绘但是重绘不一定会触发重排
  • 重绘是元素的样式变化而需要重新构建,但元素的位置和尺寸没有变化会触发

为了提高页面性能,可以采用优化方式,比如避免深层次嵌套,减少css层级等等

Vue和React使用虚拟dom和diff算法 可能是因为可能要考虑到这个问题,既然是数据驱动视图,就要减少页面的回流重绘 所以将多次的更改变为一次

CSS优先级

  1. !important 它会覆盖页面内任何位置定义的元素样式。ie6不支持该属性。
  2. 内联样式 <div style="color:red;">  (1000)
  3. ID选择器 #app {} (0100)
  4. 类、伪类、属性选择器  .classname{} (0010)
  5. 标签、伪元素选择器 div{} (0010)
  6. 通配符、子类选择器、兄弟选择器 *{} (0000)

css优先级 : 内联样式(style="…")>ID 选择器(#box{…})>类选择器(.classname{…})>标签选择器(div{…})>通用选择器(*{…})

权重 : 行内样式(1000)>ID选择器(0100)>类选择器(0010)>标签选择器(0001)>通用选择器(0000)

Golang的数据类型

  1. 布尔型(bool):布尔型的值只可以是常量 true 或 false

  2. 整数型(int):根据不同的平台,int 类型的长度也不同,32位系统上通常是 32 位,64 位系统上是 64 位。

  3. 浮点型(float):有两种形式 float32 和 float64

  4. 复数型(complex):有两种形式 complex64 和 complex128

  5. 字符串型(string):字符串是 Unicode 字符的一个序列。

  6. 数组(array):数组是一个固定长度的数据类型。

  7. 切片(slice):切片是一种灵活的数据类型,可以按需增长或缩减。

  8. 映射(map):映射是一种存储无序键值对的集合。

  9. 结构体(struct):结构体是一种可以包含多个不同类型的数据项的复合类型。

  10. 接口(interface):接口是一种定义方法集合的类型,任何类型都可以实现这些方法。

  11. 指针(pointer):指针是一种存储变量内存地址的类型。

package main
 
import (
    "fmt"
    "math/cmplx"
)
 
func main() {
    // 布尔型
    boolValue := true
    fmt.Println("Bool:", boolValue)
 
    // 整数型
    intValue := 10
    fmt.Println("Int:", intValue)
 
    // 浮点型
    floatValue := 3.14
    fmt.Println("Float:", floatValue)
 
    // 复数型
    complexValue := cmplx.Sqrt(-5 + 12i)
    fmt.Println("Complex:", complexValue)
 
    // 字符串型
    stringValue := "Hello, World!"
    fmt.Println("String:", stringValue)
 
    // 数组
    arrayValue := [5]int{1, 2, 3, 4, 5}
    fmt.Println("Array:", arrayValue)
 
    // 切片
    sliceValue := []int{1, 2, 3, 4, 5}
    fmt.Println("Slice:", sliceValue)
 
    // 映射
    mapValue := map[string]int{"one": 1, "two": 2}
    fmt.Println("Map:", mapValue)
 
    // 结构体
    type structValue struct {
        field1 int
        field2 string
    }
    structValueInstance := structValue{10, "example"}
    fmt.Println("Struct:", structValueInstance)
 
    // 指针
    pointerValue := &intValue
    fmt.Println("Pointer:", *pointerValue)
}

make和new区别

它们的作用是为不同类型的变量分配内存并进行初始化.

//语法  Type 是一个类型,size 是一个或多个整数类型的参数,表示要创建的变量的大小或容量
func new(Type) *Type
func make(Type, size ...IntegerType) Type

new 和 make 函数的区别主要有以下几点

  1. new 函数可以用于任意类型的变量,而 make 函数只能用于切片(slice)、映射(map)和通道(channel)这三种引用类型的变量。
  2. new 函数返回的是指向类型零值的指针,而 make 函数返回的是类型的值,已经初始化为非零值。
  3. new 函数只是分配内存,不涉及内存的初始化,而 make 函数不仅分配内存,还会根据类型进行相应的初始化操作。

Make使用方式

package main

import "fmt"

func main() {
	// 使用 make 函数创建一个切片,并初始化长度为 2 的切片
	slice := make([]int, 2)
	fmt.Println(slice) // 输出 [0 0]

	// 使用 make 函数创建一个map,并初始化键值对
	m := make(map[int]string)
	m[1] = "foo"
	m[2] = "bar"
	fmt.Println(m) // 输出 map[1:foo 2:bar]

	// 使用 make 函数创建一个通道
	ch := make(chan int, 3)
	ch <- 1
	ch <- 2
	ch <- 3
	fmt.Println(<-ch) // 输出 1
	fmt.Println(<-ch) // 输出 2
	fmt.Println(<-ch) // 输出 3
	//从输出结果可以看出,make 函数创建的变量都是类型的非零值,并返回该变量的值。我们可以直接使用变量进行操作
}

New使用方式

package main

import "fmt"

func main() {
	type Person struct {
		Name string
		Age  int
	}
	var a = new(Person)
	a.Name = "里斯"
	a.Age = 14
	//从输出结果可以看出,new 函数创建的变量都是类型的零值,并返回该变量的指针。我们可以通过指针来访问或修改变量的值
	fmt.Println(a)
}

new 函数返回的是指向类型零值的指针,需要使用指针修改或者获取,适用于任意类型的变量;

make 函数返回的是类型的非零值,不需要指针之际返回值,适用于切片、映射和通道这三种引用类型的变量。

事件循环

事件循环机制(Event Loop)-CSDN博客

原型原型链

构造函数:可以使用new生成实力对象的函数就叫做构造函数

所有该构造函数创建的实例对象都指向都是用通过__proto__指向原型对象 -> person.__proto__ === Person.prototype  

原型:函数都有prototype属性 叫做原型(构造函数的显式原型) 因 声明了一个函数之后,浏览器会自动按照一定的规则创建一个对象,这个对象就叫做原型对象 为也是对象所以也叫做原型对象,原型对象其实是储存在了内存当中,原型对象在创建时候默认有一个constructor属性,指向属性本身.  prototype是函数的一个属性

作用 1. 存放属性和方法 2.继承

对象通过__proto__(也叫做隐式原型)属性可以访问到原型对象,__proto__是对象Object的属性

对象的__proto__保存着该对象的构造函数的Prototype

原型链就是 对象都有__proto__属性,这个属性指向原型对象,原型对象也有__proto__属性,也指向这个原型对象的原型对象,这样一层一层往上找的一整个链式结构就是原型链,原型链的最顶端找不到的话返回NULL

 原型继承:自己对象里面没有这个属性就会通过隐士原型慢慢往上找

函数是第一类对象

判断属性中是否存在的方法

hasOwnProperty("属性")  只能看当前实例上的 无法看原型链的

原型链上有无属性 --> in

console.log('a' in Person)

constructor

这个constructor就是构造函数本身  实例化对象的构造函数

person.constructor === Person // true

constructor这个也是可以更改的

function Person() {
    this.a = 1
}
function Person1(){}
person.constructor = Person1
console.log(person.constructor,"person") // [Function: Person1] person
console.log(person1.constructor,"person1") // [Function: Person] person1

原型链可以看这个博主

js的继承

通过原型链继承

这种继承写法方便简洁,容易理解,但一般用于一个子类继承的情况,因为多个子类继承,属性会被所有实例属性共享,容易造成属性的修改混乱,并且不能向父类的构造函数中传递参数

实例对象会修改原型里面的属性

我是通过call apply 这种方式修改的

ES6继承

组合继承

new操作符做了那些事

new操作符用于创建一个构造函数的实力对象

  1. 创建一个新的对象
  2. 将对象与构造函数通过原型链连接起来
  3. 将构造函数的this绑定到新的对象中
  4. 返回类型判断,原始值被忽略,对象正常处理

函数科里化

函数科里化
柯里化(Currying)又称部分求值,一个柯里化的函数首先会接收一些参数,接收了这些参数后,该函数并不会立即求值,而是继续返回另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来。待到函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。
固定部分参数,返回一个接受剩余参数的函数,也称为部分计算函数,目的是为了缩小适用范围,创建一个针对性更强的函数。核心思想是把多参数传入的函数拆成一个个的单参数(或部分)函数,内部再返回调用下一个单参数(或部分)函数,依次处理剩余的参数。有点类似俄罗斯套娃,一层包一层

  1. 参数复用:即如果函数有重复使用到的参数,可以利用柯里化,将复用的参数存储起来,不需要每次都传相同的参数
  2. 延迟执行:传入参数个数没有满足原函数入参个数,都不会立即返回结果,而是返回一个函数。(bind方法就是柯里化的一个示例)
  3. 函数式编程中,作为compose, functor, monad 等实现的基础
  4. 支持函数部分应用

redis缓存雪崩,穿透,击穿

雪崩

redis雪崩是由于大量的缓存数据在同一时间失效(例如,由于缓存过期时间设置相同),导致大量请求直接访问数据库,使数据库瞬间承受巨大压力,甚至导致服务崩溃

解决方案

  • 分散过期时间:为缓存数据设置随机的过期时间,避免大量数据同时失效。
  • 限流降级:对数据库访问进行限流,对超出阈值的请求进行排队、降级处理或返回默认结果。
  • 缓存预热:在系统启动时或低峰期,预先加载热点数据到缓存中。
  • 使用备份缓存:如果主缓存失效,可以从备份缓存中获取数据。

穿透

缓存穿透是指查询一个不存在的数据,由于缓存中也没有该数据,导致每次请求都会直接访问数据库,而数据库中也没有该数据。这样,大量无效的请求会给数据库带来压力。

解决方案

  • 布隆过滤器:使用布隆过滤器快速判断数据是否存在,如果不存在,则直接返回。
  • 空值缓存:当数据库查询结果为空时,也将空结果(或特殊标记)存入缓存,并设置较短的过期时间。
  • 请求参数校验:对请求参数进行合法性校验,避免非法请求直接访问数据库。

击穿

缓存击穿是指一个热点key在缓存中失效的瞬间,大量并发请求同时访问数据库,导致数据库瞬间承受巨大压力。

通过合理设置缓存过期策略、使用布隆过滤器、互斥锁等技术手段,可以有效避免Redis缓存雪崩、穿透和击穿问题,提高系统的稳定性和性能。

解决方案

  • 互斥锁:在缓存失效时,使用互斥锁(如Redis的setnx命令)保证只有一个请求去查询数据库,其他请求等待结果或获取默认数据。
  • 缓存预热:提前将热点数据加载到缓存中,避免缓存失效时直接访问数据库。
  • 缓存降级:在缓存失效时,可以返回一个降级的数据或默认结果,而不是直接查询数据库。

this的指向

  1. 全局上下文中的this:在浏览器环境下,this指向window对象;在Node.js环境下,this指向global对象。在严格模式下,全局上下文中的thisundefined

  2. 普通函数中的this:当函数以普通函数形式调用时(非方法调用或构造函数),this指向全局对象(浏览器中通常是window)。

  3. 对象内部的this:在对象的方法中,this指向该对象本身。

  4. 箭头函数中的this:箭头函数不绑定自己的this,而是继承外部的上下文中的this

  5. 构造函数的this:在构造函数中,this指向新创建的对象。

  6. 事件处理程序中的this:在事件处理程序中,this指向触发事件的对象。

  7. 定时器中的this:在定时器(如setTimeout或setInterval)中,this指向全局对象(浏览器中通常是window)。

  8. 使用.bind().call().apply()改变的`this:这些方法可以改变函数调用时的上下文,从而改变this的指向。

  9. 严格模式下的特殊情况:在严格模式下(使用'use strict'),全局上下文中的thisundefined,而普通函数中的this也是undefined

  10. 特殊情况:某些情况下,如使用.bind().call().apply()方法时,可以明确指定或改变函数的执行上下文,从而改变其内部的this指向。

什么是事件监听

Js闭包

let、var、const的区别

跨域

浏览器的缓存

http和https

http状态码

CSRF

XSS攻击

ES6新增的方法

事件模型

dom0事件模型  原始事件模型
dom2事件模型  分为三个阶段  目标阶段、捕获阶段、冒泡阶段    
dom3事件模型  只不过是在原来的事件上增加了一些事件类型

 gRPC四种通信模式

golang GC垃圾回收机制

CAP原则

pinia和vuex的区别

npm依赖冲突

圣杯模式

ES5和ES6加了哪些东西

null和undefined区别

window属于浏览器环境中的全局变量

  • 42
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值