小满vue3笔记(含源码解读)

news2024/11/15 11:37:02

第一章

1.mvvm架构

 

2.回顾vue2对比vue3

 

区别:

vue2选项式api

vue3组合式api

关于这两个的区别,你可以不准确的理解为,选项式api更贴近原生标准html文件结构;

而组合式api就像在html标签中写css;当然做了优化,没准升华了

就这么个东西

3.vue3新特性

 

重写双向绑定

vue2和vue3都是用的js原生方法;

vue3重写了双向绑定,改为用ES6的新特性(好像是)proxy

 

vue2部分源码

 

 

 

vue3部分源码

由于vue2的劫持和特别是重写数组;对于数组(好像是劫持数组)不太友好(具体可能是劫持不到);所以用proxy重写了

 

vue3 tree shaking

 

vue3 composition api

setup语法糖

不懂😎

第二章

nvm 与node

nvm : node的版本管理工具,坑:空,中文路径,node版本重新添加或者卸载重安

nodejs部分架构

 

 

nodejs的源码好像包含些c

 

处理最总要的好像是io流,毕竟是对并发处理好的机制(优点)

 

 

第三章

关于vite项目的目录

待补充

vscode中vue2和vue3插件

智能提示书写语法会冲突,2,3要禁用一个

npm run dev 是如何执行的

在vite中查看packag.json

会发现软连接bin制定到...

之后这个文件做了linux系统,window系统的一些相关配置(🤔。。。)

第四章vue3模版语法

vue3书写风格

 

支持模版语法

api调用

 

三元表达

 

vue指令用法

v-html模板(也许是自定义模板???🤔)

。。。

v-if

关于v-if是如何在false下消失的,打开浏览器开发者模式查看,发现被注释掉了

为什么说v-show比v-if性能高

v-show在被设置为false后,是添加了display:none

看起来切换css要比注释性能高(look🤨)

@click点击

 

冒泡😅

v-bind绑定

简写:":"

 

常用动态绑定css,style,class,id....

v-model绑定

一般绑定的表单元素;

ref属性觉定v-model是否是响应式

v-for遍历数组

.....

 

v-once;v-memo

v-once,只渲染一次

 

 

v-memo如果跟空数组,效果和v-once是一致的

v-memo节省一小部分性能;大概是一万条数据,5s左右;不执行则跳过

 

第五章虚拟DOM和diff算法

介绍虚拟DOM

AST语法数:这个东西在ES6转ES5的插件babel;ts转js中会进行ast转换

根据满哥说的,我的理解是vue3在用js去描述DOM对象;这个描述和操作不一样(js操作dom)

 

正在上传…重新上传取消

为什么不直接操作dom:

原因:dom的属性太多,影响性能

 

我看是说这一次描述dom,会全部描述进去,影响性能

 

最长递增子序列

 

不清楚,刷算法再说喽

 

第六章ref全家桶

全家...

内置的特殊 Attributes | Vue.js

 

手写防抖

 

在 Vue 中,我们可以很轻松的实现防抖和节流。防抖指令 v-debounce:

html
<input @input="doSomething" v-debounce="500">

该指令会在用户输入完后 500ms 后再执行 doSomething 方法。我们也可以手工实现一个防抖的 debounce 方法:

js
export default {
  methods: {
    debounce(func, wait) {
      let timeout
      return function() {
        let context = this
        let args = arguments
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          func.apply(context, args)
        }, wait)
      }
    }
  }
}

然后在组件中这样使用:

html
<input @input="debounce(doSomething, 500)">

节流指令 v-throttle:

html
<input @scroll="doSomething" v-throttle="500">

该指令会在用户连续滚动 500ms 内只执行 doSomething 方法一次。我们也可以手工实现 throttle 方法:

js
export default {
  methods: {
    throttle(func, wait) {
      let timeout, context, args  
      return function() {
        context = this
        args = arguments   
        if (!timeout) {    
          timeout = setTimeout(() => {
            timeout = null
            func.apply(context, args)
          }, wait)
        }
      }
    }
  }
}

然后在组件中这样使用:

html 
<input @scroll="throttle(doSomething, 500)">

所以,在 Vue 中使用防抖和节流非常简单,既可以使用内置的 v-debounce 和 v-throttle 指令,也可以手动实现 debounce 和 throttle 方法,在组件方法中使用。希望这个介绍能帮助你在 Vue 项目中熟练使用防抖和节流技术。它们能有效优化组件的性能,提高用户体验,是 Vue 开发中很重要的技能。

第七章reactive全家桶

reactive

不可以绑定普通的数据类型这样是不允许 会给我们报错

绑定普通的数据类型 我们可以 使用昨天讲到ref

reactive基础用法

import{reactive} form"vue"
let person=reactive({
name:'xiaoman'
})
person.name="daman"

数组异步赋值问题

脱离响应式的情况

let person =reactive<number[]>([])
setTimeout(()=>{
person=[1,2,3]
console.log(person);
},1000)
​

解决方案1

使用push

import{reactive} from "vue"
let person =reactive<number[]>([])
setTimeout(()=>{
person.push(...arr)
console.log(person);
},1000)

方案2

包裹一层对象

ts

type Person={
list?:Array<number>
}
let person =reactive<Person>({
list:[]
})
setTimeout(()=>{
const arr =[1,2,3]
person.list=arr;
console.log(person);
},1000)

这创建了一个反应式变量person的类型Person,初始值为list的空数组。

1秒后,这个定时器函数会运行。它创建一个数组arr,[1, 2, 3]并将其分配给person.list。 由于person是反应性的,此赋值将触发反应性更新。 然后我们记录person并看到更新的值,列表[1, 2, 3]。总之,这显示了一个基本示例,创建一个反应性变量person并更新其中一个属性list,从而触发反应性更新,更新控制台日志。所以这个示例展示了在TypeScript中使用响应式变量的基础知识。定义一个带可选属性的接口,创建一个该接口的响应式变量,然后更新该变量的属性,触发更新并查看更新后的值。

readonly

拷贝一份proxy对象将其设置为只读??

import {reactive,readonly} from 'vue'
const person = reactive{{count:1}}
const copy = readonly(person)
//person.count++
copy.count++
​

shallowReactive

hallowReactive 是 Vue 中实现浅响应式 (shallow reactive) 的一个函数。正常来说,在 Vue 中数据对象的所有属性都是深度响应式的,也就是说,如果对象的嵌套属性改变了,此对象的 reactive 响应式代理也会产生变更通知。有时候我们只希望外层属性是响应式的,而不希望内部嵌套对象是响应式的。这种情况下可以使用 shallowReactive 函数来创建一个浅层响应式代理:

只能对浅层的数据 如果是深层的数据只会改变值 不会改变视图

<template>
<div>
{{state}}
<button @click="change1">
test1
</button>
<button @click="change1">
test2
</button>
</div>
</template>
​
<script setup lang="ts">
import{sahwllowReactive}from "vue"
const obj={
    a:1,
    first:{
        b:2,
        second:{
        c:3
        }
     }
}
​
const state = shallowReactive(obj)
function change1(){
state.a=7
}
function change2(){
state.first.b=8
state.first.second.c=9
consloe.log(state);
}
</script>

第八章to系列全家桶

toRef toRefs toRaw

<template>
<div>0
    <button @click="change">按</button>
    {{state}}
</div>
<template>
<script setup lang="ts">
import{reactive,toRef}from "vue"
const obj={
foo:1,
bar:1
}
const state = toRef(obj,'bar')
//bar 转化为响应式对象??
const change=()=>{
state.value++
console.log(obj,state);
}
<script>
​

如果原始对象是响应式的是会更新视图并且改变数据的

在这段代码中,bar 实际上并没有转化为响应式对象。这段代码做了以下几件事:1. 定义了一个普通对象 obj,包含 foo 和 bar 属性2. 使用 toRef 从 obj 中获取 bar 属性的响应式引用,赋值给 state3. 定义一个 change 方法,对 state.value 进行更改4. 在模板中使用 state 显示数据,并绑定 click 事件到 change 方法当我们点击按钮,调用 change 方法时,会发生以下事情:1. state.value 由于是响应式的,所以更改它会触发界面更新2. 但是 obj 中的 bar 属性本身并不是响应式的,所以 obj 对象自己并不会更新3. 我们在 change 方法中 console.log 了 obj 和 state,会看到:- obj 中的 bar 仍然是更改前的值 - state.value 已经更新了所以,关键的是要理解:- toRef 创建的响应式引用 state 与原对象 obj 中的属性 bar 实际上不是同一个东西 - state 是响应式的,会触发更新 - obj 的 bar 属性本身仍然是普通属性,不具有响应性只有当我们 wieder 给 obj.bar 赋值时,state.value 才会跟着更新,因为它 internally 还是连接着 obj.bar 的。所以 toRef 并没有使 obj 中的 bar 属性本身变为响应式的,它只是创建了一个 bar 属性的响应式引用 state 而已。

toRefs

可以帮我们批量创建ref对象主要是方便我们解构使用

import {reactive,toRefs} from "vue"
const obj = reactive({
foo:1,
bar:1
})
let {foo,bar} = toRefs(obj)
foo.value++
console.log(foo,bar);

toRaw

将响应式对象转化为普通对象

import {reactive,toRaw} from "vue"
const obj=reactive({
    foo:1,
    bar:1
})
const state= toRaw(obj)
//响应式对象转换为普通对象
cosnt change()=>{
    console.log(obj,state);
}

源码解析toRef

如果是ref 对象直接返回 否则 调用 ObjectRefImpl 创建一个类ref 对象

​
export function toRef<T extends object, K extends keyof T>(
  object: T,
  key: K,
  defaultValue?: T[K]
): ToRef<T[K]> {
  const val = object[key]
  return isRef(val)
    ? val
    : (new ObjectRefImpl(object, key, defaultValue) as any)
​

- T 表示对象的类型,它必须是 object 或 object 的子类型 - K 表示对象的键的类型,它必须是 T 的键之一 - defaultValue 是一个可选参数,表示默认值这个函数的作用是:- 检查 object[key] 是否已经是一个 ref 对象,如果是的话直接返回 - 否则创建一个 ObjectRefImpl 的实例,它实现了 ToRef 接口,并将 object、key 和 defaultValue 作为构造函数的参数 - 最后将这个 ObjectRefImpl 的实例作为 ToRef<T[K]> 的实例返回所以简而言之,这个函数的作用是:如果对象的某个键还没有关联的 ref,那么为其创建一个 ref,从而让使用者可以对这个键所指向的属性进行响应式监测。这个函数看起来像是 Vue3 中创建 ref 的工具函数,它通过检查属性是否已经是 ref 来防止重复创建 ref 的情况出现。

类ref 对象只是做了值的改变 并未处理 收集依赖 和 触发依赖的过程 所以 普通对象无法更新视图

class ObjectRefImpl<T extends object, K extends keyof T> {
  public readonly __v_isRef = true
 
  constructor(
    private readonly _object: T,
    private readonly _key: K,
    private readonly _defaultValue?: T[K]
  ) {}
 
  get value() {
    const val = this._object[this._key]
    return val === undefined ? (this._defaultValue as T[K]) : val
  }
 
  set value(newVal) {
    this._object[this._key] = newVal
  }
}

源码解析toRefs

其实就是把reactive 对象的每一个属性都变成了ref 对象循环 调用了toRef

export type ToRefs<T = any> = {
  [K in keyof T]: ToRef<T[K]>
}
export function toRefs<T extends object>(object: T): ToRefs<T> {
  if (__DEV__ && !isProxy(object)) {
    console.warn(`toRefs() expects a reactive object but received a plain one.`)
  }
  const ret: any = isArray(object) ? new Array(object.length) : {}
  for (const key in object) {
    ret[key] = toRef(object, key)
  }
  return ret
}

toRaw 源码解析

通过 ReactiveFlags 枚举值 取出 proxy 对象的 原始对象

export const enum ReactiveFlags {
  SKIP = '__v_skip',
  IS_REACTIVE = '__v_isReactive',
  IS_READONLY = '__v_isReadonly',
  IS_SHALLOW = '__v_isShallow',
  RAW = '__v_raw'
}
 
export function toRaw<T>(observed: T): T {
  const raw = observed && (observed as Target)[ReactiveFlags.RAW]
  return raw ? toRaw(raw) : observed
}

枚举是什么

枚举(Enum)是 TypeScript 中的一种类型,它定义了一些带名字的常量。枚举可以使代码更易读和理解。TypeScript 支持数字的和基于字符串的枚举。数字枚举:

ts
enum Direction {
  Up = 1,
  Down,
  Left,
  Right 
}

这里,Up 的初始值为 1,其他成员会从 2 开始自动增长。我们可以这样使用枚举成员:

ts
let dir = Direction.Up;

字符串枚举:

ts
enum Message {
  Success = "SUCCESS",
  Fail = "FAIL"
}

我们也可以不给枚举成员赋初始值,此时第 0 个成员默认为 0,之后的成员值会自动增 1:

ts
enum Response {
  No = 0,
  Yes 
}
​
let res: Response = Response.Yes;  // res = 1

枚举也可以拥有常数成员和计算成员:

ts
enum Color {
  Red,     // 常数成员,默认值为 0
  Green,   // 1
  Blue,    // 2 
  Cyan = Blue + 2  // 计算成员,值为 4
}

枚举类型也可以被混入到接口和类型别名中:

ts
interface WindowState {
  state: WindowStates  // 枚举类型
}
​
type WindowStates = "open" | "closed" | "minimized";  // 字符串类型

总之,枚举是 TypeScript 中一种简单但非常实用的类型,它常用于属性值域的定义和替换魔法字符串。

魔法字符串

魔法字符串指的是在代码中嵌入的不可读的字符串值。例如:

ts
function handleMessage(message) {
  if (message === "SUCCESS") {
    // ...
  } else if (message === "FAIL") {
    // ...
  }
}

这里的 "SUCCESS" 和 "FAIL" 就是魔法字符串。魔法字符串有以下几个问题:1. 不易理解:魔法字符串的意思不容易被人理解,阅读者无法从字符串值本身推导出其语义。2. 容易拼写错误:由于字符串值不具有自我描述性,所以很容易拼写错误却不被检测出来。3. 难以改变:如果需要改变字符串值,需要改变所有使用该字符串的地方,这很容易遗漏某些位置而导致 bug。4. 没有类型安全:字符串可以随意修改,而它所代表的语义却没有变化,这会导致类型错误。所以,通常我们会使用枚举来替换魔法字符串:

ts
enum Message {
  Success = "SUCCESS",
  Fail = "FAIL" 
}
​
function handleMessage(message: Message) {
  if (message === Message.Success) {
    // ...
  } else if (message === Message.Fail) {
    // ...
  }
}

这样可以解决上述所有的问题:1. 易于理解:枚举成员的名字本身就具有语义。

  1. 没有拼写错误:我们操作的都是枚举成员,拼写是由编译器保证的。

  2. 易于改变:如果需要改变枚举的值,只需要改变枚举定义处的内容,使用处不需要修改。

  3. 类型安全:枚举是一个类型,用它来约束变量可以实现类型安全。所以,通过使用枚举,我们彻底消除了魔法字符串,使代码更健壮、易于理解和维护。

第九章 computed计算属性

computed用法

计算属性就是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值

1.函数形式

import{ computed,reactive,ref} from"vue"
let m =computed<string>(()=>{
return `$`+ price.value
})
price.value=500

2.对象形式

<template>
 <div>{{mul}}</div>
 <div @click="mul=100">
 click
 </div>
</template>
<script setup lang="ts">
import {computed,ref} from "vue"
let price = ref<number| string>(1)//$0
let mul=computed({
get:()=>{
return price.value
},
set:(value)=>{
price.value='set'+value
}
})
​
</script>

computed购物车案例

<template> <div> <input placeholder="请输入名称" v-model="keyWord" type="text"> <table style="margin-top:10px;" width="500" cellspacing="0" cellpadding="0" border> <thead> <tr> <th>物品</th> <th>单价</th> <th>数量</th> <th>总价</th> <th>操作</th> </tr> </thead> <tbody> <tr v-for="(item, index) in searchData"> <td align="center">{{ item.name }}</td> <td align="center">{{ item.price }}</td> <td align="center"> <button @click="item.num > 1 ? item.num-- : null">-</button> <input v-model="item.num" type="number"> <button @click="item.num < 99 ? item.num++ : null">+</button> </td> <td align="center">{{ item.price * item.num }}</td> <td align="center"> <button @click="del(index)">删除</button> </td> </tr> </tbody> <tfoot> <tr> <td colspan="5" align="right"> <span>总价:{{ total }}</span> </td> </tr> </tfoot>

    </table>
</div>

</template>

<script setup lang='ts'> import { reactive, ref,computed } from 'vue' let keyWord = ref<string>('') interface Data { name: string, price: number, num: number } const data = reactive<Data[]>([ { name: "小满的绿帽子", price: 100, num: 1, }, { name: "小满的红衣服", price: 200, num: 1, }, { name: "小满的黑袜子", price: 300, num: 1, } ])

let searchData = computed(()=>{ return data.filter(item => item.name.includes(keyWord.value)) })

let total = computed(() => { return data.reduce((prev: number, next: Data) => { return prev + next.num * next.price }, 0) })

const del = (index: number) => { data.splice(index, 1) }

</script>

<style scoped lang='less'></style>

手写源码 effect.ts

interface Options { scheduler?: Function } let activeEffect; export const effect = (fn: Function,options:Options) => { const _effect = function () { activeEffect = _effect; let res= fn() return res } _effect.options = options _effect() return _effect }

const targetMap = new WeakMap() export const track = (target, key) => { let depsMap = targetMap.get(target) if (!depsMap) { depsMap = new Map() targetMap.set(target, depsMap) } let deps = depsMap.get(key) if (!deps) { deps = new Set() depsMap.set(key, deps) }

deps.add(activeEffect) }

export const trigger = (target, key) => { const depsMap = targetMap.get(target) const deps = depsMap.get(key) deps.forEach(effect => { if(effect?.options?.scheduler){ effect?.options?.scheduler?.() }else{ effect() } }) } reactive.ts

import { track, trigger } from './effect'

const isObject = (target) => target != null && typeof target == 'object'

export const reactive = <T extends object>(target: T) => { return new Proxy(target, { get(target, key, receiver) { const res = Reflect.get(target, key, receiver) as object

        track(target, key)
 
        if (isObject(res)) {
            return reactive(res)
        }
 
        return res
    },
    set(target, key, value, receiver) {
        const res = Reflect.set(target, key, value, receiver)
 
        trigger(target, key)
 
        return res
    }
})

}

computed.ts

import { effect } from './effect'

export const computed = (getter: Function) => { let value = effect(getter, { scheduler: () => { _dirty = true } }) let catchValue let _dirty = true class ComputedRefImpl { get value() { if (dirty) { catchValue = _value() _dirty = false; } return catchValue } }

return new ComputedRefImpl()

} html

​​

<script type="module">
    import {computed} from './computed.js'
    import {reactive} from './reactive.js'
    window.a = reactive({name: 'a', age: 18})
    window.b = computed(() => {
        console.log('重新计算')
        return a.age + 10
    })
    
</script>

</body> </html>

第九章代码选自大佬小满博客,资料参考小满博客和视频

小满zs的博客_CSDN博客-Vue3,typeScript,nest-js领域博主

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/684213.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最新大麦网抢票脚本-Python实战

学习时候的一个小例子&#xff0c;python挺有趣的&#xff0c;希望技术可以更进步 我也不多说啥了直接上图 系统:win10 python 版本:3.8.10 需要安装的库:selenium 安装方法: pip install selenium 抢H5版本也写了&#xff0c;但是速度有点慢2…5 就不发了 不如用autojs写感…

前端vue入门(纯代码)15

【16.Vue的过渡与动画】 1.点击切换按钮&#xff1a;实现某一元素的显示/隐藏 Test.vue文件中 <template><div><!-- 点击事件触发后&#xff0c;isShow取反 --><!-- 通过点击按钮让h1标签出现或者消失 --><button click"isShow !isShow&qu…

哈工大计算机网络课程网络层协议详解之:DHCP协议

哈工大计算机网络课程网络层协议详解之&#xff1a;DHCP协议 文章目录 哈工大计算机网络课程网络层协议详解之&#xff1a;DHCP协议如何获得IP地址&#xff1f;硬编码动态主机配置协议-DHCP&#xff1a;&#xff08;Dynamic Host Configuration Protocol&#xff09; 动态主机配…

设计模式篇(Java):前言(UML类图、七大原则)

编写软件过程中&#xff0c;程序员面临着来自耦合性&#xff0c;内聚性以及可维护性&#xff0c;可扩展性&#xff0c;重用性&#xff0c;灵活性等多方面的挑战&#xff0c;设计模式是为了让程序(软件)&#xff0c;具有更好&#xff1a; 代码重用性 (即&#xff1a;相同功能的…

Web自动化测试平台的设计与落地

目录 前言 一、目标和定位 二、平台特点 三、系统架构 四、相关技术栈 五、UI概览 六、待完善部分 总结&#xff1a; 前言 我最初开始接触Web自动化测试的时候&#xff0c;没有直接的领路人&#xff0c;测试行业知识也远不及如今这么丰富和易获取&#xff0c;当时我对于…

Hello算法学习笔记之搜索

一、二分查找 1.从数组中找到target的索引 注意&#xff1a;while条件是< O&#xff08;logn&#xff09; 二分查找并非适用于所有情况&#xff0c;原因如下&#xff1a; 二分查找仅适用于有序数据。若输入数据无序&#xff0c;为了使用二分查找而专门进行排序&#xff…

视频处理器对LED显示屏的作用

视频处理器在LED显示屏中扮演着重要的角色&#xff0c;其作用如下&#xff1a; 图像和视频信号处理&#xff1a;视频处理器负责对输入的图像和视频信号进行处理和优化&#xff0c;以确保在LED显示屏上呈现出高质量的图像和视频内容。它可以对图像进行去噪、锐化、色彩校正、亮度…

【数据结构】复杂度

目录 &#x1f4d6;什么是数据结构&#xff1f;&#x1f4d6;什么是算法&#xff1f;&#x1f4d6;算法效率&#x1f4d6;时间复杂度&#x1f516;大O的渐进表示法&#x1f516;常见时间复杂度计算举例&#x1f516;面试题&#xff1a;消失的数字 &#x1f4d6;空间复杂度&…

I2C协议应用(嵌入式学习)

I2C协议&应用 0. 前言1. 概念2. 特点&工作原理3. 应用示例代码模板HAL模板 0. 前言 I2C是Inter-Integrated Circuit的缩写&#xff0c;它是一种广泛使用的串行通信协议。它由飞利浦&#xff08;现在是NXP Semiconductors&#xff09;开发&#xff0c;并已成为各种电子…

无迹卡尔曼滤波在目标跟踪中的作用(一)

在前一节中&#xff0c;我们介绍了扩展卡尔曼滤波算法EKF在目标跟踪中的应用&#xff0c;其原理是 将非线性函数局部线性化&#xff0c;舍弃高阶泰勒项&#xff0c;只保留一次项 &#xff0c;这就不可避免地会影响结果的准确性&#xff0c;除此以外&#xff0c;实际中要计算雅各…

软件测试面试试卷,答对90%直接入职大厂

一&#xff0e;填空 1、 系统测试使用&#xff08; C &#xff09;技术, 主要测试被测应用的高级互操作性需求, 而无需考虑被测试应用的内部结构。 A、 单元测试 B、 集成测试 C、 黑盒测试 D、白盒测试 2、单元测试主要的测试技术不包括&#xff08;B &…

Linux 如何刷新 DNS 缓存

Linux 如何刷新 DNS 缓存 全文&#xff1a;如何刷新 DNS 缓存 (macOS, Linux, Windows) Unix Linux Windows 如何刷新 DNS 缓存 (macOS, FreeBSD, RHEL, CentOS, Debian, Ubuntu, Windows) 请访问原文链接&#xff1a;https://sysin.org/blog/how-to-flush-dns-cache/&#…

Elasticsearch:install

ElasticSearch Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。 Elasticsearch结合Kibana、Logstash、Beats&#xff0c;也就是elastic stack(ELK)。被广泛应用在日志分析、实时监控&#xff08;CPU、Memory、Program&#xff09;等领域。 elasticsearch是…

【Linux 驱动篇(一)】字符设备驱动开发

文章目录 一、字符设备驱动简介二、字符设备驱动开发步骤1. 驱动模块的加载和卸载2. 字符设备注册与注销3. 实现设备的具体操作函数3.1 能够对 chrtest 进行打开和关闭操作3.2 对 chrtest 进行读写操作 4. 添加 LICENSE 和作者信息 三、Linux 设备号1. 设备号的组成 一、字符设…

网工内推 | 2023应届生专场,上市公司招网工,CCNP以上认证优先

01 浙江宇视科技有限公司 招聘岗位&#xff1a;IT网络工程师 职责描述&#xff1a; 1、负责公司内部核心网络建设&#xff0c;进行网络架构的规划、设计、调整、性能优化&#xff1b; 2、负责公司网络环境的管理&#xff0c;配置&#xff0c;监控、排错&#xff0c;维护&#…

津津乐道设计模式 - 适配器模式详解(家里电器电源标准不统一的问题都解决了)

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Micro麦可乐的博客 &#x1f425;《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程&#xff0c;入门到实战 &#x1f33a;《RabbitMQ》…

Servlet 相关内容

1. Servlet 1.1 Servlet概述 Servlet 是 SUN 公司提供的一套规范&#xff0c;名称就叫 Servlet 规范&#xff0c;它也是 JavaEE 规范之一&#xff0c;可以通过API来学习。目前在Oracle官网中的最新版本是JavaEE8&#xff0c;该网址中介绍了JavaEE8的一些新特性。当然&#xff…

【C语言初阶】带你轻松玩转所有常用操作符(2) ——赋值操作符,单目操作符

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,这里是君兮_&#xff0c;今天给大家带来的是有关操作符的第二部分内容&#xff0c;废话不多说&#xff0c;咱们直接开始吧&#xff01; 在正式开始之前&#xff0c;我们还是借助一张思维导图帮助大致简单回忆一下有…

Docker-compose的使用

目录 Docker-compose 简介 docker-compose的安装 docker-compose.yaml文件说明 compose的常用命令 总结 Docker-compose 简介 Docker-compose 是用于定义和运行多容器的 Docker 应用程序的工具。可以使用YAML文件来配置应用程序的服务。&#xff08;通俗讲是可以通过yml文…