【面试题】面试不面试,你都必须得掌握的vue知识_<template v-for="(slot, name) in $slots" key="nam

`为避免内存泄漏,需要销毁监听的自定义事件,有两种解决方案:`

(1) 在组件的`beforeDestroy`钩子函数中销毁监听的自定义事件:

beforeDestroy() {
  //销毁监听事件
  this.$bus.off("addProduct");
}

(2) 每次$on之前$off需要销毁的事件名称;

d. localStorage详解

e. 页面的路由传参

2. 父子组件之间通讯:

a. 父组件使用props向子组件传值, 子组件定义props接收父组件传递过来的值。特别注意: 如果props基本数据类型, 那么在子组件中,不能直接修改父组件传递过来的props

b. 子组件使用$emit向父组件传递事件和值,父组件使用@事件名接收事件和参数

1. 父子组件使用`$emit`和`@自定义事件`传递方法:

(1) `父组件中的方法按序接收传递过来的参数` 

子组件传递多个参数的情况:
this.$emit('test', 1, 2, 3)

父组件接收子组件的自定义事件:

@test="test"

test(a, b, c) {
  console.log('我是接收过来的参数', a, b, c)
}

`或`

test(...params) {
  console.log('我是接收过来的参数', params[0], params[1], params[2])
}

(2) `父组件使用函数中内置的arguments伪数组(且必须为这个内置参数),接收传递过来的参数` 

this.$emit('test', 1, 2, 3)

@test="test(arguments)"

test(params) {
  console.log('我是接收过来的参数', params[0], params[1], params[2])
}

(3) `使用对象的方式组装数据`

this.$emit('test', { age, sex, city })

@test="test"

test(params) {
  console.log('我是接收过来的参数', params.age, params.sex, params.city)
}

2. `$emit`的扩展: 使用`$on监听本组件的自定义事件`, 后文会讲到可以`使用$once只监听一次本组件的自定义事件`

mounted() {
    `// 在钩子函数中定义了一个方法,用于closeModal调用时再去执行`
    `// 至于$on调用的方法和父组件从子组件接收来的自定义方法执行的快慢就看它们的执行机制
    (同步状态下,处理相同条件,父组件更快,一方异步一方同步的状态下,同步的那方先执行,都是异步看谁先执行完)`
    this.$on('closeModal',res=>{
        console.log(res);
    })
},

destoryed() {
    `// 使用$off移除事件监听
    1)如果没有提供参数,则移除所有的事件监听器;
    2)如果只提供了事件,则移除该事件所有的监听器;
    3)如果同时提供了事件与回调,则只移除这个回调的监听器。
    `
    this.$off("closeModal");
},

closeModal(){ 
    this.$emit('closeModal')
}

3. `$emit`的扩展: 
   `this.$emit('update:visible',false)`, 使用双向绑定的`语法糖`,在父组件中使用`.sync`对传入的`props`进行
    双向绑定,更新父组`visible`的`prop`值;

c. 父组件使用this.$refs.子组件的ref名称获取子组件的vue实例,this.$refs.子组件的ref名称.$el是获取组件的dom元素;

d. 父组件使用this.$children(包含所有子组件(不包含孙子组件)的 VueComponent 对象数组) 获取子组件的数据,例如this.$children[0].someMethod()执行子组件的方法。对于子组件,则直接使用this.$parent获取父组件的值。

e. 插槽

3. 祖先跨级通讯:

a. 祖先组件使用provide返回需要传递的参数,后代组件使用inject接收参数

// 祖先组件
provide() {
    return {
        `// keyName: { name: this.name }, // value 是对象才能实现响应式,也就是引用类型`
          keyName: this.changeValue // 通过函数的方式也可以[注意,这里是把函数作为value,而不是this.changeValue()]
        `// keyName: 'test' value 如果是基本类型,就无法实现响应式`
    }
},

data() {
    return {
        name:'张三'
    }
},

methods: {
    changeValue(){
        this.name = '改变后的名字-李四'
    }
}  
  
// 后代组件
inject:['keyName']
create() {
    `因为是函数,所以得执行才能获取响应式的数据,改变后的名字-李四`
    const keyName = this.keyName() 
}

b. 使用$attrs$listeners实现祖先的跨级通讯(详见本文第一点)

e. 插槽

vue插槽官方文档

1. 在子组件A中使用`<slot></slot>`进行`占位`,父组件引入子组件A,在A下`添加的内容`会`自动转移`到`插槽占位的地方`;
2. 如果`<slot></slot>`中有内容,如果在父组件不给子组件添加内容,那么就会展示插槽的默认内容;
3. 如果未给`<slot></slot>`提供名称,那么该插槽的默认名称是`default`;
4. 如果需要给`插槽`指定名称,直接对子组件使用`name`命名即可;
   `<slot name="footer"></slot>`
   
   如果在父组件中,需要给对应`插槽`添加内容,则可以使用如下三种写法:
   <template v-slot:footer> 
       <!-- footer 插槽的内容放这里 --> 
   </template>
   
  <template #footer> 
       <!-- footer 插槽的内容放这里 --> 
   </template>
   
   <template slot="footer"> 
       <!-- footer 插槽的内容放这里 --> 
   </template>
   
   
 5. `插槽`是有`作用域`的,父组件中的`插槽`内容无法访问子组件的内容,除非通过`作用域插槽`的方式进行传递:
 
    子组件:
    `<slot name="footer" :row="row"></slot>`
   
    父组件:
    <template v-slot:footer="{ row }"> 
       <!-- footer 插槽的内容放这里 --> 
    </template>
    
    <template #footer="{ row }"> 
       <!-- footer 插槽的内容放这里 --> 
    </template>
     
    <template slot="header" slot-scope="{ row }">
        <!-- footer 插槽的内容放这里 --> 
    </template>
    
    在这里`扩展`一个代码的优化点,`v-if`可以使用`template`包裹,`语义`会更加清晰。
    
  6. 如果组件只有一个`插槽`,则在父组件上,可以直接使用`插槽`语法,而不需要`template`标签嵌套。
  7. 自定义组件内部的`$scopedSlots`记载了对应的`作用域插槽信息`,以`key(插槽名)-value(对应函数。指定key值,
  执行得到Vnode数组,对应$slots,一般更推荐使用$scopedSlots)`的形式出现。因此,根据这个特性,
  当`有多个具有插槽的组件`定义在`一个自定义组件中`时,可以通过`遍历的方式动态添加插槽`
  
<template>
  <div class="el-tree-select_component">
    <el-select
      ref="select"
      :class="[defaultText && 'has-default-text']"
      v-bind="selectProps"
      :value="valueTitle"
      :popperClass="concatPopperClass"
    >
      <template v-for="(val, key) in allSlots.inputScopedSlots" #[key]>
        <slot :name="key"></slot>
      </template>
      <el-option :label="valueTitle" :value="valueId">
        <el-tree
          ref="selectTree"
          :data="options || []"
          :node-key="props.value"
          :default-expanded-keys="defaultExpandedKey"
          v-bind="treeProps"
          @node-click="handleNodeClick"
        >
          <template v-for="(val, key) in allSlots.treeScopedSlots" #[key]="scope">
            <slot :name="key" v-bind="scope"></slot>
          </template>
        </el-tree>
      </el-option>
    </el-select>
    <span class="default-text" v-if="defaultText"> {{ defaultText }} </span>
  </div>
</template>

const INPUT_SLOT_LIST = ['prefix', 'empty']

computed: {
    // 获取select组件和tree组件的插槽
    allSlots({ $scopedSlots }) {
      const inputScopedSlots = {}
      const treeScopedSlots = {}
      for (let key in $scopedSlots) {
        const val = $scopedSlots[key]
        if (INPUT_SLOT_LIST.includes(key)) inputScopedSlots[key] = val
        else treeScopedSlots[key] = val
      }
      return {
        inputScopedSlots,
        treeScopedSlots
      }
    }
}

f. vueX

vueX黑马笔记

`在平时的项目中,为了代码看上去不是那么臃肿,一般会使用多个store文件来维护vueX,比如product.js, order.js...`
`并可以通过函数的方式拿到vueX中存储的数据`

computed: {
    ...mapState({
        has_image_gallery: (state) => state.customizer.has_image_gallery,
        library: (state) => state.myImage.library.list,
        meta: (state) => state.myImage.library.pagination,
        last_page: (state) => state.myImage.library.pagination.last_page
    })
}

g. 指令(以回到顶部组件说明)

指令的官方介绍

`自定义指令中的第三个参数vnode的context记载了组件的一些信息,这个是我们比较需要关注的`

`1. 使用自定义指令,实现回到顶部的效果:`

`添加全局公共样式:`
.scroll-top-class {
  position: fixed;
  bottom: 120px;
  right: 30px;
  opacity: 0;
  height: 40px;
  width: 40px;
  line-height: 40px;
  font-size: 30px;
  text-align: center;
  color: #ddd;
  opacity: 0;
  z-index: 2021;
  cursor: pointer;
  border-radius: 50%;
  box-shadow: 0px 0px 8px 1px #ccc;
  background-color: rgba($color: #666, $alpha: 0.5);
  transition: all 1s;
}

`指令挂载方法:在有滚动条的容器上,添加v-scrollTop指令, 并提供相应的值即可。如果不提供,则使用默认值`
<div class="topic-page" v-scrollTop> </div>

`指令注册方法: 同第k点, 先install, 在本文件暴露出去。然后在main.js文件中引入,并使用vue.use(引入的名称)全局注册`

`第一种方法:直接使用binding.value判断回到顶部图标出现的位置(相对推荐)`

Vue.directive('scrollTop', {
  inserted(el, binding) {
    `如果未设置binding.value的值,则默认为200`
    `滚动条移动超过200px的距离就显示,反之则隐藏`
    if (!binding.value) binding.value = 200

    el.style.scrollBehavior = 'smooth'

    const backEl = document.createElement('div')
    backEl.className = 'scroll-top-class el-icon-top'
    el.appendChild(backEl)
    backEl.addEventListener('click', () => (el.scrollTop = 0))

    el.addEventListener('scroll', () => {
      if (el.scrollTop >= binding.value) backEl.style.opacity = 1
      else backEl.style.opacity = 0
    })
  }
})

`第二种方法:使用binding.value,根据滚动条的总高度所占比例,间接判断回到顶部图标出现的位置`
`(不推荐,因为在产品列表无限滚动情况下,滚动条高度是动态变化的,无法适用,而且倍数不好控制)`

// 滚动条指令
Vue.directive('scrollTop', {
  inserted(el, binding) {
    if (binding.value >= 1 || binding.value <= 0) return new Error('v-scrollTop的绑定值需要介于0到1之间')

    `获取元素的整体高度`
    const elH = el.offsetHeight
    
    `也可以给visibilityHeight定值(不推荐,无法兼容所有需要滚动条的页面)`
    let visibilityHeight = 0
    if (binding.value) visibilityHeight = binding.value * elH
    `阈值默认为滚动区域整体高度的0.2倍`
    else visibilityHeight = 0.2 * elH

    `为滚动条返回顶部添加平滑的过渡效果`
    el.style.scrollBehavior = 'smooth'

    const backEl = document.createElement('div')
    backEl.className = 'scroll-top-class el-icon-top'
    `将创建的回到顶部图标作为孩子插入到el中`
    el.appendChild(backEl)
    
    backEl.addEventListener('click', () => (el.scrollTop = 0))

    el.addEventListener('scroll', () => {
      if (el.scrollTop >= visibilityHeight) backEl.style.opacity = 1
      else backEl.style.opacity = 0
    })
  }
})

`2. 自定义组件,实现回到顶部的效果:`
`使用这种方式,需要在每个有回到顶部需求的文件中引入该自定义组件,并指定高度阈值及滚动条dom容器对应的字符串`

<template>
  <el-button v-show="visible" class="back" @click="backTop">top</el-button>
</template>

<script>
export default {
  props: {
    height: {
      required: false,
      type: Number,
      default: 200
    },

    target: {
      required: false,
      type: String,
      default: '.topic-page'
    }
  },

  data() {
    return {
      container: false,
      visible: false
    }
  },

  mounted() {
    this.container = document.querySelector(this.target)
    if (!this.container) throw new Error('target is not existed: ' + this.target)
    this.container.style.scrollBehavior = 'smooth'
    `最保险的做法是,使用this.$nextTick包裹下面的代码,因为vue是异步更新机制,dom可能还未更新`
    this.container.addEventListener('scroll', this.scrollToTop)
    this.$once('hook:beforeDestory', () => {
      this.container.removeEventListener('scroll', this.scrollToTop)
    })
  },

  methods: {
    backTop() {
      this.container.scrollTo({
        top: 0,
        behavior: 'smooth'
      })
    },

    scrollToTop() {
      this.visible = this.container.scrollTop > this.height ? true : false
    }
  }
}
</script>

<style lang="scss" scoped>
.back {
  position: fixed;
  bottom: 100px;
  right: 100px;
}
</style>

h. 使用install和use进行全局注册
`lodopPrintPdf.js`

import Vue from 'vue'
import PrintBtn from './printBtn'
import merge from 'element-ui/src/utils/merge'

export default async function lodopPrintPdf(option) {
  const ExtendPrintBtn = Vue.extend(PrintBtn)
  `继承打印组件并初始化vue实例`
  const vm = new ExtendPrintBtn({})
  `合并option,等价于Object.assign(vm, option)`
  `相当于遍历添加传入vm的prop参数`
  merge(vm, option)
  `调用实例的方法,js动态加载完成`
  return vm.printHandler()
}
复制代码
`globalConst.js`

import lodopPrintPdf from '@/components/lodopPrint/lodopPrintPdf.js'

export default {
    install(Vue) {
        `在vue的原型对象上挂载$lodopPrintPdf,并暴露出去`
        Vue.prototype.$lodopPrintPdf = lodopPrintPdf //lodop打印pdf
    }
}

`main.js`

`Vue.use的用法: 安装Vue插件。
如果插件是一个对象,必须提供 install 方法。
如果插件是一个函数,它会被作为 install 方法。`

import globalConst from '@/commons/globalConst'

Vue.use(globalConst)
复制代码
`$lodopPrintPdf方法的使用`

`传入的五个参数就是前面定义的函数所接收的option值,相当于调用打印组件,传入对应的五个props`
this.$lodopPrintPdf({
    type: 'html',
    printable: this.$refs.label.$el,
    paperSize: [841.89, 595.28],
    onSuccess: this.resetLoading,
    onError: this.resetLoading
})

i. 混入 && 继承

混入: 对于具有相同逻辑的vue文件,其实可以抽取成一个混入,存放公共的js代码。在使用混入vue文件中,可以定义相同的变量或者方法来覆盖混入中的变量或者方法。

继承: 相比混入继承更加霸道,可以继承整个vue文件。同时在继承文件中,可以添加一些额外的js代码。如果在被继承的组件中存在这些js变量和方法,那么继承组件就会覆盖这些变量和方法,如果不存在则为添加。如果在继承组件中添加htmlcss代码,不管这些代码之前是否和被继承组件的htmlcss代码冲突,继承组件的htmlcss代码都会以自身代码为主,不会继承被继承组件的htmlcss代码。

<script>
import dialog from '@/extend/components/dialog/index'

export default {
  extends: dialog
 
}

</script>

j. $props三兄弟和inherits属性

$props:当前组件接收到的 props 对象。Vue 实例代理了对其 props 对象属性的访问。

$attrs: 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。

$listeners:包含了父作用域中的(不含.native 修饰器的)v-on事件监听器。

inherits属性的作用是禁止传入的属性添加到组件的根元素上。默认为true,即将传入的属性添加到组件的根元素上。

应用v-bind="$attrs"v-on="$listeners"一般用于组件封装上,必须得绑定在组件上。v-bind="$attrs"相当于一个展开运算符,将从父组件传来的props且未被当前组件props接收的prop挂载到组件上,使得组件具有可扩展性。如果未绑定,孙子组件可以通过this.$attrs拿到子组件的props,但是无法拿到父组件的props。如果要拿到父组件的props,则需要在子组件上绑定v-bind="$attrs",这样孙子组件中的this.$attrs就指向父组件的props

inherits属性-官方说明

inherits属性-掘金文章说明

$props-掘金文章说明

$listeners-掘金文章说明

k. v-model语法糖

官网双向绑定原理详解

l. 修饰符的顺序及理解

修饰符详解1

修饰符详解2

m. render函数 && 函数式组件
n. 路由守卫

2. vue的冷知识(vue间谍,大部分内容来自Sunshine_Lin的掘金博客。部分内容有自己的思考和扩展, 以扩展两字进行标注)

a. 为什么不建议v-for和v-if同时存在?
<div v-for="item in [1, 2, 3, 4, 5, 6, 7]" v-if="item !== 3">
    {{item}}
</div>

`拓展:`
`vue2中的v-for优先级高于v-if, vue3则相反。首先会把7个元素都遍历出来,然后再一个个判断是否为3,并把3的dom给隐藏掉,
这样的坏处就是,渲染了无用的3节点,增加无用的dom操作,建议使用computed来解决这个问题:`

<div v-for="item in list">
    {{item}}
</div>

computed() {
    list() {
        return [1, 2, 3, 4, 5, 6, 7].filter(item => item !== 3)
    }
}

b. 为什么不建议用index做key,为什么不建议用随机数做key?
<div v-for="(item, index) in list" :key="index">{{item.name}}</div>

list: [
    { name: '小明', id: '123' },
    { name: '小红', id: '124' },
    { name: '小花', id: '125' }
]

渲染为
<div key="0">小明</div>
<div key="1">小红</div>
<div key="2">小花</div>

现在我执行 list.unshift({ name: '小林', id: '122' })

渲染为
<div key="0">小林</div>
<div key="1">小明</div>
<div key="2">小红</div>
<div key="3">小花</div>


新旧对比

<div key="0">小明</div>  <div key="0">小林</div>
<div key="1">小红</div>  <div key="1">小明</div>
<div key="2">小花</div>  <div key="2">小红</div>
                         <div key="3">小花</div>

可以看出,如果用index做key的话,其实是更新了原有的三项,并新增了小花,虽然达到了渲染目的,但是损耗性能

现在我们使用id来做key,渲染为

<div key="123">小明</div>
<div key="124">小红</div>
<div key="125">小花</div>

现在我执行 list.unshift({ name: '小林', id: '122' }),渲染为

<div key="122">小林</div>
<div key="123">小明</div>
<div key="124">小红</div>
<div key="125">小花</div>

新旧对比

                           <div key="122">小林</div>
<div key="123">小明</div>  <div key="123">小明</div>
<div key="124">小红</div>  <div key="124">小红</div>
<div key="125">小花</div>  <div key="125">小花</div>

可以看出,原有的三项都不变,只是新增了小林这个人,这才是最理想的结果

index和用随机数都是同理,随机数每次都在变,做不到专一性,很渣男,也很消耗性能,所以,拒绝渣男,选择老实人

c. 为什么data是个函数并且返回一个对象呢?
`data`之所以是一个函数,是因为一个组件可能会多处调用,而每一次调用就会执行`data函数`并返回新的数据对象。
这样,可以避免多处调用的`数据污染`。

d. vue2的内部指令

`拓展:`

1. `v-text`的用法:

本质其实和`插值表达式`一样。不同的是,`v-text`后面必须得`赋值`,它只与`赋予的变量的值`有关。比如:

<div v-text="123"> {{ unsignedCountries }} </div>

此处只`渲染123`, 而不会渲染`计算属性`的值。

2. `v-once`:指令所绑定的`html标签`和`组件`中的变量只会渲染一次,`不会随着变量的变化而变化`,利用好这一点可以优化

e. vue2的生命周期

`拓展:`
`1. vue生命周期钩子函数的组成:`

`vue的生命周期`是一个`组件/实例`从`创建到销毁`的过程中自动执行的函数,主要分为:`创建、挂载、更新、销毁`四个模块。

`挂载`:`$el`和`$mount`都是为了将`实例化后的vue挂载`到指定的`dom元素`中,但是`$el`的优先级要高于`$mount`。

如果`实例化vue`的时候指定`el`,则`vue`将会渲染到`此el对应的dom`中,
反之,若没有指定`el`,则`vue实例`会处于一种`未挂载`的状态,此时可以通过`$mount`来手动`执行挂载`。

`2. 被keep-alive缓存的组件的生命周期:`

第一次进入,`created` -> `mounted` -> `activated`,
退出时触发`deactivated`。当再次进入时,只触发`activated`。

f. 如何设置动态class,动态style?

(1) 动态class(对象形式):

<div :class="{ 'is-active': true, 'red': isRed }"></div>

(2) 动态class(数组形式):

拓展: <div :class="['is-active', isRed && 'red' ]"></div>

(3) 动态style对象(其中的css属性必须使用驼峰命名):

<div :style="{ color: textColor, fontSize: '18px' }"></div>

(4) 动态style数组(使用多个对象包裹,对象之间的css属性使用逗号隔开):

<div :style="[{ color: textColor, fontSize: '18px' }, { fontWeight: '300' }]"></div>

g. 如何处理非响应式数据?

在我们的Vue开发中,会有一些数据,从始至终都未曾改变过,这种死数据,既然不改变,那也就不需要对他做响应式处理了,不然只会做一些无用功消耗性能,比如一些写死的下拉框,写死的表格数据,这些数据量大的死数据,如果都进行响应式处理,那会消耗大量性能。

// 方法一:将数据定义在data之外
data () {
    `拓展:这种非响应式的数据可以直接定义,包括在methods方法里`
    this.list1 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list2 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list3 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list4 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    this.list5 = { xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx }
    return {}
}

// 方法二:Object.freeze()
data () {
    return {
        list1: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list2: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list3: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list4: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
        list5: Object.freeze({xxxxxxxxxxxxxxxxxxxxxxxx}),
    }
}

h. 父子组件的生命周期?

挂载阶段: 父beforeCreate >父created > 父beforeMount > 子beforeCreate>子created子beforeMount > 子mounted >父mounted

扩展:

子组件更新过程: 父beforeUpdate > 子beforeUpdate > 子updated > 父updated

父组件更新过程(影响到子组件): 父beforeUpdate > 子beforeUpdate > 子updated > 父updated

父组件更新过程(不影响子组件): 父beforeUpdate > 父updated

销毁过程: 父beforeDestroy > 子beforeDestroy > 子destroyed > 父destroyed

h. Vue采用的是异步更新的策略,通俗点说就是,同一事件循环内多次修改,会统一进行一次视图更新,这样才会节省性能。
i. 关于props的自定义校验
props: {
    num: {
        default: 1,
        `// type:Number, 指定props的类型`
        `// required: true, 指定props是否为必填项`


## 算法

1. 冒泡排序

2. 选择排序

3. 快速排序

4. 二叉树查找: 最大值、最小值、固定值

5. 二叉树遍历

6. 二叉树的最大深度

7. 给予链表中的任一节点,把它删除掉

8. 链表倒叙

9. 如何判断一个单链表有环

   ![](https://img-blog.csdnimg.cn/img_convert/e740d32f9201373c3fbe3fde6360699e.webp?x-oss-process=image/format,png)

>由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

unted` >`父mounted`


  **扩展:**


  **子组件更新过程:** `父beforeUpdate` > `子beforeUpdate` > `子updated` > `父updated`


  **父组件更新过程(影响到子组件):** `父beforeUpdate` > `子beforeUpdate` > `子updated` > `父updated`


  **父组件更新过程(不影响子组件):** `父beforeUpdate` > `父updated`


  **销毁过程:** `父beforeDestroy` > `子beforeDestroy` > `子destroyed` > `父destroyed`


#### h. Vue采用的是`异步更新`的策略,通俗点说就是,`同一事件循环内`多次修改,会`统一`进行一次`视图更新`,这样才会节省性能。


#### i. 关于props的自定义校验



props: {
num: {
default: 1,
// type:Number, 指定props的类型
// required: true, 指定props是否为必填项

算法

  1. 冒泡排序

  2. 选择排序

  3. 快速排序

  4. 二叉树查找: 最大值、最小值、固定值

  5. 二叉树遍历

  6. 二叉树的最大深度

  7. 给予链表中的任一节点,把它删除掉

  8. 链表倒叙

  9. 如何判断一个单链表有环

    [外链图片转存中…(img-K59A406x-1714513414057)]

由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值