前端设计模式学习

news2024/11/17 2:31:54

UML类图
在这里插入图片描述
在这里插入图片描述

1.工厂模式

设计原则:最重要的就是开放封闭原则,对扩展开放,对修改封闭。
1.工厂和类分离,解耦
2.可以扩展多个类
3.工厂的创建逻辑也可以自由扩展

工厂模式可以拆分成三个,分别是工厂方法模式、抽象工厂模式和建造者模式。
1.1.简易工厂模式

// 简易工厂模式
class Product {
    name: string
    constructor(name: string) {
        this.name = name
    }
    fn1(){
        console.log('11111');
    }
    fn2(){
        console.log('22222');
    }
}

//工厂
class Creator {
    create (name:string):Product {
        return new Product(name)
    }
}
//test
const creator = new Creator()
const p1  = creator.create('p1')
const p2  = creator.create('p2')
const p3  = creator.create('p3')

UML类图
在这里插入图片描述

1.2 标准的工厂模式

interface IProduct {
    name: string
    fn1: () => void
    fn2: () => void
}
class Product1 implements IProduct {
    name:string
    constructor(name:string){
        this.name = name
    }
    fn1(){
        console.log('1111');  
    }
    fn2(){
        console.log('22222');
    }
}
class Product2 implements IProduct {
    name:string
    constructor(name:string){
        this.name = name
    }
    fn1(){
        console.log('1111');  
    }
    fn2(){
        console.log('22222');
    }
}
class Creator {
    create(type: string, name: string): IProduct {
        if (type === 'p1') {
            return new Product1(name)
        }
        if (type === 'p2') {
            return new Product2(name)
        }
        throw new Error('Invalid type')
    }
}
const creator = new Creator()
const p1 = creator.create('p1','name1')
const p2 = creator.create('p2','name2')

UML类图
在这里插入图片描述1.3 jQuery应用场景

// jQuery应用
declare interface Window {
    $: (selector: string) => Jquery
}
class Jquery {
    selector: string
    length: number
    constructor(selector: string) {
        const domList = Array.prototype.slice.call(document.querySelectorAll(selector))
        const length = domList.length
        for (let i = 0; i++; i < length) {
            //@ts-ignore
            this[i] = domList[i]
        }
        this.selector = selector
        this.length = length
    }
    append(elem: HTMLElement): Jquery {
        // append的具体操作
        return this
    }
    addClass(className: string): Jquery {
        //addClass 的操作
        return this
    }
}
// 不用工厂模式
// const $div = new Jquery('div')
// const $p = new Jquery('p')

//使用工厂模式
function $(selector: string) {
    return new Jquery(selector)
}
window.$ = $
const $div = $('div')
const $p = $('p')
console.log($p);
console.log($div);

1.4 Vue_createElementVNode和React createElement应用场景
工厂模式应用:从Render函数变成vnode的过程中运用

function createElement() {
    // 逻辑判断
    return VNode()
}
createElement(c,d)

2.单例模式

一个对象/实例,只能被创建一次
创建之后缓存起来,以后继续使用
即 一个系统只有一个
例:
登录框,遮罩层,一个系统只有一个即可,多了无用(创建好一个实例,哪个页面需要使用就直接从缓存里那过来使用即可)
Vuex Redux的store,一个系统中个只能有一个,多了就会出错

静态属性:

class Foo {
	// 实例/对象 属性
    name: string
    constructor(name: string) {
        this.name = name
    }
    getName() {
        return this.name
    }
    // 静态属性
    static flag: string = 'abc'
    static getFlag() {
        // this === Foo
        return Foo.flag
    }
}
const f1 = new Foo('zs')
f1.name // 'zs'
f1.getName() // 'zs'
console.log(Foo.flag);
console.log(Foo.getFlag);

UML类图
在这里插入图片描述
2.1 TS代码演示

class SingleTon {
    // private 无法在外面实例化
    private constructor() { }
    private static instance: SingleTon | null
    // 获取单例
    static getInstance(): SingleTon {
        if (SingleTon.instance == null) {
            SingleTon.instance = new SingleTon()
        }
        return SingleTon.instance
    }
}

const s1 = SingleTon.getInstance()
const s2 = SingleTon.getInstance()
console.log(s1 === s2);

2.2 登录框代码演示

class LoginForm {
    private state: string = 'hide'
    private constructor() { }
    show() {
        //this 也能写成 LoginForm
        if (this.state === 'show') {
            console.log('show-----');
            return
        }
        console.log('显示LoginForm');
        this.state = 'show'
    }
    hide() {
        if (this.state = 'hide') {
            console.log('hide---');
            return
        }
        console.log('隐藏LoginForm');
        this.state = 'hide'
    }
    private static instance: LoginForm | null = null
    static getInstance(): LoginForm {
        if (this.instance == null) {
            this.instance = new LoginForm()
        }
        return this.instance
    }
}
// test
const loginForm1 = LoginForm.getInstance()
const loginForm2 = LoginForm.getInstance()
console.log(loginForm1 === loginForm2);


3.观察者模式

UML类图
在这里插入图片描述
3.1 源码

class Subject {
    private state: number = 0
    private observers: Observer[] = []
    getState(): number {
        return this.state
    }
    setState(newState: number) {
        this.state = newState
        this.noticy()
    }
    // 添加观察者
    attach(observers: Observer) {
        this.observers.push(observers)
    }
    // 通知
    private noticy() {
        this.observers.forEach(observer => {
            observer.update(this.state)
        })
    }
}
class Observer {
    name: string
    constructor(name: string) {
        this.name = name
    }
    update(state: number) {
        console.log(`${this.name} updated,state is ${state}`);
    }
}
const sub = new Subject()
const observer1 = new Observer('A')
const observer2 = new Observer('B')
sub.attach(observer1)
sub.attach(observer2)
sub.setState(1)

3.2 应用场景
3.2.1 场景1

const http = require('http')
function serverCallback(req, res) {
    console.log('url', req.url);
    res.end('hello')
}
http.createServer(serverCallback).listen(8081)
console.log("开始监听8081端口----");

3.2.2 场景2

const { log } = require('console')
const fs = require('fs')
const readStream = fs.createReadStream('./data/yarn.lock.txt')
//文件字符的length
let length = 0
readStream.on('data', function (chunk) {
    let streamLen = chunk.toString().length
    console.log('current length', streamLen);
    length += streamLen

})
readStream.on('end', function () {
    console.log(length);
})

3.3.3 场景3

const readLine = require('readline')
const fs = require('fs')

const rl = readLine.createInterface({
    input: fs.createReadStream('./data/yarn.lock.txt')
})

// 文件的行数
let lineNum = 0
rl.on('line', function (line) {
    lineNum++
})
rl.on('close', function () {
    console.log('lineNum', lineNum);
})

3.3 观察者模式和发布订阅模式的区别
在这里插入图片描述
在这里插入图片描述
3.4 发布订阅模式场景
在这里插入图片描述

import eventEmitter from "event-emitter";
const emitter = eventEmitter()

emitter.on('change', (value: string, name: string) => {
    console.log('change1', value, name);
})

emitter.on('change', () => {
    console.log('change2');
})

emitter.once('change', () => {
    console.log('change3');
})
emitter.emit('change', 'aaa', 'hello')
emitter.emit('change')
emitter.emit('change')

4.迭代器模式

4.1 迭代器概念
在这里插入图片描述
4.2代码

// 迭代器
class DataIterator {
    private data: number[]
    private index = 0
    constructor(container: DataContainer) {
        this.data = container.data
    }
    next(): number | null {
        if (this.hasNext()) {
            return this.data[this.index++]
        }
        return null
    }
    hasNext(): boolean {
        if (this.index >= this.data.length) {
            return false
        }
        return true
    }
}
class DataContainer {
    data = [10, 20, 30, 40, 50]
    getIterator() {
        // 获取迭代器
        return new DataIterator(this)
    }
}

const container = new DataContainer()
const iterator = container.getIterator() //获取迭代器

while (iterator.hasNext()) {
    const num = iterator.next()
    console.log(num);
}

4.3 UML类图
在这里插入图片描述
4.4 自定义简易迭代器

interface IteratorRes {
    value: number | undefined
    done: boolean
}
class CustomIterator {
    private length = 3
    private index = 0
    next(): IteratorRes {
        this.index++
        if (this.index <= this.length) {
            return { value: this.index, done: false }
        }
        return { value: undefined, done: true }
    }
    [Symbol.iterator]() {
        return this
    }
}
const iterator = new CustomIterator()
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

4.5 Generator + yield 遍历DOM树

function* traverse(elemList: Element[]): any {
    for (const elem of elemList) {
        yield elem
        const children = Array.from(elem.children)
        if (children.length) {
            yield* traverse(children)
        }
    }
}
const container = document.getElementById('aaa')
if (container) {
    for (let node of traverse([container])) {
        console.log(node);
    }
}

5.原型模式

5.1 UML类图
在这里插入图片描述

5.2 代码演示

// 原型模式
class CloneDemo {
    name = 'clone demo'
    clone(): CloneDemo {
        return new CloneDemo()
    }
}   

5.3 原型链
继承的本质就是原型链
在这里插入图片描述
5.4 使用场景
Object.create()
在这里插入图片描述
创建对象的区别:
使用 Object.create() 是将对象继承到原型链上,然后可以通过对象实例的 _ proto _ 属性进行访问原型链上的属性。

new Object() 默认继承了 Object 对象上的 prototype 。

{} 本质上和 new Object() 没有区别,默认都是继承了 Object 对象上的 prototype 。
5.5 对象属性描述符
Object.getOwnPropertyDescriptor()方法获取指定对象指定的自有属性的属性描述符。

Object.defineproperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性
Object.defineproperty()可以接收三个参数
Object.defineproperty(obj, prop, desc)
obj : 第一个参数就是要在哪个对象身上添加或者修改属性
prop : 第二个参数就是添加或修改的属性名
desc : 配置项,一般是一个对象

原型属性的enumerable
在这里插入图片描述

只要enumerable为true,就可以遍历出来

遍历Symbol属性
通过Reflect.ownKeys()可以遍历获取到

6.装饰器模式

6.1 概念
在这里插入图片描述
6.2 UML类图
在这里插入图片描述

6.3 代码

class Circle {
    draw() {
        console.log('draw');
    }
}
class Decorator {
    private circle: Circle
    constructor(circle: Circle) {
        this.circle = circle
    }
    draw() {
        this.circle.draw()
        this.setBorder()
    }
    private setBorder() {
        console.log('setBorder');
    }
}

const circle = new Circle()
const decorator = new Decorator(circle)
decorator.draw()

6.4 应用场景

/**
 * readOnly 装饰器
 * @param target 实例
 * @param key key
 * @param descriptor 属性描述符 
 */
function readOnly(target: any, key: string, descriptor: PropertyDescriptor) {
    console.log(target, 'target');
    console.log(key, 'key');
    console.log(descriptor, 'descriptor');
    descriptor.writable = false
}
// 装饰器工厂函数
function configurable(val: boolean) {
    return function (target: any, key: string, descriptor: PropertyDescriptor) {
        descriptor.configurable = val
    }
}

class Foo {
    private name = 'zs'
    private age = 20

    @readOnly
    getName() {
        return this.name
    }
    @configurable(false)
    getAge() {
        return this.age
    }
}

const f = new Foo()
// @ts-ignore
console.log(Object.getOwnPropertyDescriptor(f.__proto__, 'getAge'));

7.代理模式

7.1 UMl类图
在这里插入图片描述
7.2 代码

/ 代理模式
class RealImg {
    fileName: string
    constructor(fileName: string) {
        this.fileName = fileName
    }
    display() {
        this.loadFromDist()
        console.log('display---');
    }
    private loadFromDist() {
        console.log('loadFromDist---');

    }
}
class ProxyImg {
    realImg: RealImg
    constructor(fileName: string) {
        this.realImg = new RealImg(fileName)
    }
    //代理
    display() {
        this.realImg.display()
    }
}

const proxyImg = new ProxyImg('xxx.png')
proxyImg.display()

7.3 场景
7.3.1 DOM事件代理概念
在这里插入图片描述
7.3.2 DOM事件代理代码


const container = document.getElementById('container')
if (container) {
    // DOM 事件代理(委托)
    container.addEventListener('click', event => {
        const target = event.target as Element
        if (target.nodeName === 'A') {
            alert(target.innerHTML)
        }
    })
}

7.3.3 Webpack devServer proxy
在这里插入图片描述
正向代理:又称客户端代理,由webpack来做代理,每一个开发者都需要配置webpack。
反向代理:又称服务端代理,nginx,由后端来进行代理到不同的端口,前端不需要做任何处理。

7.3.4 Proxy语法代码

const star = {
    name: 'zs',
    age: 25,
    phone: 123456789,
    price: 0
}
const agent = new Proxy(star, {
    get(target, key) {
        if (key === 'phone') {
            return '13912345678'
        }
        if (key === 'price') {
            return 10 * 1000
        }
        return Reflect.get(target, key)
    },
    set(target, key, val): boolean {
        if (key === 'price') {
            if (val < 100 * 1000) {
                throw new Error('to low')
            } else {
                console.log('成交!');
                return Reflect.set(target, key, val)
            }
        }
        // 其他属性不可修改
        return false
    }
})
console.log(agent.name);
console.log(agent.age);
console.log(agent.phone);
agent.price = 110000
console.log(agent.price);

7.3.5 Proxy使用场景

1.跟踪属性访问
vue3数据响应式 Proxy

const user = {
    name: 'zs'
}
const proxy = new Proxy(user, {
    get(...args) {
        console.log('get...');
        return Reflect.get(...args)
    },
    set(target, key, val) {
        console.log('set...');
        return Reflect.set(target, key, val)
    }
})

proxy.name
proxy.name = 'lisi'

2. 隐藏属性

const hiddenProps = ['girlFriend']
const user = {
    name: 'zs',
    age: 23,
    girlFriend: 'lisi'
}
const proxy = new Proxy(user, {
    get(target, key) {
        if (hiddenProps.includes(key as string)) return undefined
        return Reflect.get(target, key)
    },
    has(target, key) {
        if (hiddenProps.includes(key as string)) return false
        return Reflect.has(target, key)
    },
    set(target, key, val) {
        if (hiddenProps.includes(key as string)) return false
        return Reflect.set(target, key, val)
    }
})
// proxy.girlFriend = 'hahahs'
console.log(proxy.girlFriend);
console.log('girlFriend' in proxy);

3.验证属性格式

const user = {
    name: 'zs',
    age: 23
}
const proxy = new Proxy(user, {
    set(target, key, val) {
        if (key === 'age') {
            if (typeof val !== 'number') {
                return false
            }
        }
        return Reflect.set(target, key, val)
    },
})
// 类型报错
proxy.age = '12'

4.记录实例

const userList = new Set()
class User {
    name: string
    constructor(name: string) {
        this.name = name
    }
}
const ProxyUser = new Proxy(User, {
    construct(...args) {
        const user = Reflect.construct(...args)
        userList.add(user)
        return user
    }
})
const user1 = new ProxyUser('zs')
const user2 = new ProxyUser('lisi')
console.log('userList', userList);


7.3.6 Proxy踩坑
1.捕获器不变式
无法改变自身属性导致的无法改变

const obj = { x: 100, y: 200 }
Object.defineProperty(obj, 'y', {
    value: 200,
    writable: false,
    configurable: false
})

const proxy = new Proxy(obj, {
    get() {
        return 'abc'
    }
})
console.log(proxy.x);
console.log(proxy.y);

2.this
proxy.getName()的this变成了proxy

const user = {
    name: 'zs',
    getName() {
        console.log('this...', this); //this是在执行时才确定
        return this.name
    }
}
const proxy = new Proxy(user, {})
proxy.getName()
user.getName()

8.职责链模式

8.1 概念
在这里插入图片描述

8.2 场景
jQuery链式操作
Promise链式调用

9.策略模式

解决大量的if else问题

interface IUser {
    buy: () => void
}
class OrdinaryUser implements IUser {
    buy() {
        console.log('普通用户');
    }
}
class MemberUser implements IUser {
    buy() {
        console.log('会员用户');
    }
}
class VipUser implements IUser {
    buy() {
        console.log('vip用户');
    }
}
const user1 = new OrdinaryUser()
user1.buy()

10.适配器模式


function getUsers() {
  return [
    {
      name: 'zs',
      age: 30
    },
    {
      name: 'ls',
      age: 20
    }
  ]
}

// 不想修改上面代码,但想获取 [{zs: 30}, {ls: 20}]格式的数据

/**
 * 适配器
 * @param {Array} users 
 */
function adaptor(users) {
  let result = [];
  users.forEach(user => {
    result.push({
      [user.name]: user.age
    })
  });
  return result;
}

let res = getUsers();
console.log(res);
// [ { name: 'zs', age: 30 }, { name: 'ls', age: 20 } ]
console.log(adaptor(res));
// [ { zs: 30 }, { ls: 20 } ]

11.面试题——打车

抽象类:必须被子类实现,不能直接new出来
抽象属性:必须在抽象类里面,必须被子类重写


class Car {
    name: string
    number: string
    price = 0
    constructor(name: string, number: string) {
        this.name = name
        this.number = number
    }
}
class ExpressCar extends Car {
    price = 1
    constructor(name: string, number: string) {
        super(name, number)
    }
}
class SpecialCar extends Car {
    price = 2
    constructor(name: string, number: string) {
        super(name, number)
    }
}
class Trip {
    car: Car
    constructor(car: Car) {
        this.car = car
    }
    start() {
        console.log('开始行程了----');
    }
    end() {
        console.log('结束行程了----');
    }
}
const car = new ExpressCar('byd', '13476878787')
const trip = new Trip(car)
trip.start()
trip.end()

UML类图在这里插入图片描述

12. 面试题——停车场

在这里插入图片描述

//停车信息
interface IEntryInfo {
    number: string
    inTime: number
    place?: ParkPlace // 可有可无
}
class Car {
    number: string
    constructor(number: string) {
        this.number = number
    }
}
// 入口摄像头
class ParkCamera {
    shot(car: Car): IEntryInfo {
        return {
            number: car.number,
            inTime: Date.now()
        }
    }
}
//出口显示器
class ParkScreen {
    show(info: IEntryInfo) {
        const { number, inTime } = info
        const duration = Date.now() - inTime //停车时长
        console.log(`${number},停车时长${duration}`);
    }
}
// 车位
class ParkPlace {
    isEmpty = true
    getInfo() {
        this.isEmpty = false
    }
    out() {
        this.isEmpty = true
    }
}

// 层
class ParkFloor {
    index: number
    parkPlaces: ParkPlace[]
    constructor(index: number, places: ParkPlace[]) {
        this.index = index
        this.parkPlaces = places
    }
    get emptyPlaceNum(): number {
        let num = 0
        for (const place of this.parkPlaces) {
            if (place.isEmpty) num++
        }
        return num
    }
}
// 停车场
class Park {
    parkFloors: ParkFloor[]
    parkCamera = new ParkCamera()
    parkScreen = new ParkScreen()
    entryInfoList: Map<string, IEntryInfo> = new Map()
    constructor(floors: ParkFloor[]) {
        this.parkFloors = floors
    }
    getInfo(car: Car) {
        // 调用摄像头拍照
        const entryInfo = this.parkCamera.shot(car)
        // 某个车位
        const i = Math.round((Math.random() * 100) % 100)
        const place = this.parkFloors[0].parkPlaces[i] // 停在第一层的某个位置
        // 进入车位
        place.getInfo()
        // 记录停车信息
        entryInfo.place = place
        this.entryInfoList.set(car.number, entryInfo)
    }
    out(car: Car) {
        // 获取停车信息
        const entryInfo = this.entryInfoList.get(car.number)
        if (entryInfo == null) return
        const { place } = entryInfo
        if (place == null) {
            return
        }

        // 离开车位
        place.out()
        // 出口显示屏显示
        this.parkScreen.show(entryInfo)
        // 删除停车信息的记录
        this.entryInfoList.delete(car.number)
    }

    get emptyInfo(): string {
        return this.parkFloors.map(floor => {
            return `${floor.index}层还有${floor.emptyPlaceNum}个空闲车位`
        }).join('\n')
    }
}

// 初始化停车场
const floors: ParkFloor[] = []
// 3层
for (let i = 0; i < 3; i++) {
    const places: ParkPlace[] = []
    //每层100个车位
    for (let i = 0; i < 100; i++) {
        places[i] = new ParkPlace()
    }
    floors[i] = new ParkFloor(i + 1, places)
}
const park = new Park(floors)
const car1 = new Car('A1')
const car2 = new Car('A2')
const car3 = new Car('A3')


document.getElementById('btn-car1-into')?.addEventListener('click', () => {
    console.log('第一辆车进入');
    console.log(park.emptyInfo);
    park.getInfo(car1)
})
document.getElementById('btn-car1-out')?.addEventListener('click', () => {
    console.log('第一辆车离开');
    park.out(car1)
})

document.getElementById('btn-car2-into')?.addEventListener('click', () => {
    console.log('第二辆车进入');
    console.log(park.emptyInfo);
    park.getInfo(car2)
})

document.getElementById('btn-car2-out')?.addEventListener('click', () => {
    console.log('第二辆车离开');
    park.out(car2)
})

document.getElementById('btn-car3-into')?.addEventListener('click', () => {
    console.log('第三辆车进入');
    console.log(park.emptyInfo);
    park.getInfo(car3)
})

document.getElementById('btn-car3-out')?.addEventListener('click', () => {
    console.log('第三辆车离开');
    park.out(car3)
})


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

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

相关文章

C/C++图形库EasyX保姆级使用教程(二) 图形化窗口设置以及简单图形的绘制

C/C图形库EasyX保姆级使用教程 第一章 Microsoft Visual Studio 2022和EasyX的下载及安装使用 第二章 图形化窗口设置以及简单图形的绘制 文章目录 C/C图形库EasyX保姆级使用教程前言一、窗口&#xff01;1.如何生成一个图形化窗口&#xff1f;1.头文件2.初始化一个图形化窗口…

基于Java+Swing+Mysql人口普查登记系统

基于JavaSwingMysql人口普查登记系统 一、系统介绍二、功能展示1.主页2.新增人口信息3.查询人口信息 三、数据库四、其他系统实现五、获取源码 一、系统介绍 该系统实现了查看列表、新增人口信息、删除人口信息 运行环境&#xff1a;eclipse、idea、jdk1.8 二、功能展示 1.…

常州工学院数字图像处理及应用2022-2023第二学期实验报告 + 期末

《数字图像处理及应用》 课程 实验报告书 专业班级&#xff1a; 21计二 姓 名&#xff1a; 王梓权 学 号&#xff1a; 21030228 指导教师&#xff1a; 徐则中 计算机信息工程学院 《数字图像处理》实验 实验教学目的和要求 《数字图像处理》课程内容是一门综合…

Python MongoDB复习第一章

Python 可以在数据库应用程序中使用。 最受欢迎的 NoSQL 数据库之一是 MongoDB。 MongoDB MongoDB 将数据存储在类似 JSON 的文档中&#xff0c;这使得数据库非常灵活和可伸缩。 为了能够测试本教程中的代码示例&#xff0c;您需要访问 MongoDB 数据库。 您可以在 https:/…

论文学习笔记:增强学习应用于OS调度

【引子】周末&#xff0c;读了一篇同事推荐的论文《STUN: Reinforcement-Learning-Based Optimization of Kernel Scheduler Parameters for Static Workload Performance》&#xff0c;很有启发&#xff0c;遂加入个人思考编译成文。 从小型物联网设备到大型服务器&#xff0c…

VIM编辑器的命令使用总结

&#xff08;该图由AI绘制 关注我 学习AI画图&#xff09; 目录 一、VIM编辑器 1、vi概述 2、vim编辑器 3、vim编辑器的安装 4、vim编辑器的四种模式&#xff08;重点&#xff09; ☆ 命令模式 ☆ 编辑模式或输入模式 ☆ 末行模式 ☆ 可视化模式&#xff08;了解&am…

Apache Doris (十三) :数据存储模型之Duplicate数据存储模型

进入正文之前&#xff0c;欢迎订阅专题、对博文点赞、评论、收藏&#xff0c;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; 在某些多维分析场景下&#xff0c;数据既没有主键&#xff0c;也没有聚合需求&#xff0c;只需要将数据原封不动的存入表中&#xff0c;数据有…

神经网络初谈

文章目录 简介神经网络的发展历程神经网络的初生神经网络的第一次折戟神经网络的新生&#xff0c;Hinton携BP算法登上历史舞台命途多舛&#xff0c;神经网络的第二次寒冬神经网络的重生&#xff0c;黄袍加身&#xff0c;一步封神神经网络的未来&#xff0c;众说纷纭其他时间点 …

【实战】 四、JWT、用户认证与异步请求(下) —— React17+React Hook+TS4 最佳实践,仿 Jira 企业级项目(五)

文章目录 一、项目起航&#xff1a;项目初始化与配置二、React 与 Hook 应用&#xff1a;实现项目列表三、TS 应用&#xff1a;JS神助攻 - 强类型四、JWT、用户认证与异步请求1~56.用useAuth切换登录与非登录状态7.用fetch抽象通用HTTP请求方法&#xff0c;增强通用性8.用useHt…

基于Hadoop的网上购物行为分析设计与实现

有需要本项目的可以私信博主&#xff0c;提供部署和讲解服务&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 本研究基于淘宝用户行为的开源数据展开大数据分析研究&#xff0c;通过Hadoop大数据分析平台对阿里天池公开的开源数据集进行多维度的用户行为分析&a…

4.1ORB-SLAM3之处理缓存队列中的关键帧

0.简介 该函数主要包括以下几个部分&#xff1a; 计算该关键帧特征点的Bow信息更新当前关键帧新增地图点的属性更新共视图中关键帧间的连接关系将该关键帧插入到地图中 1.计算该关键帧特征点的Bow信息ComputeBoW() vector<cv::Mat> vCurrentDesc Converter::toDescr…

ModaHub魔搭社区:向量数据库功能主要特点和应用场景

目录 主要特点 向量数据库功能 高性能向量搜索 低延迟高召回率 多向量搜索索引 向量数据库可以帮助的领域 图像相似性搜索 视频相似性搜索 音频相似性搜索 主要特点 向量数据库功能 高性能向量搜索 存储、索引和管理由深度神经网络和其他机器学习&#xff08;ML&…

Matlab论文插图绘制模板第106期—带误差棒的堆叠柱状图

在之前的文章中&#xff0c;分享了Matlab带误差棒的折线图绘制模板&#xff1a; 带误差棒的柱状图绘制模板&#xff1a; 进一步&#xff0c;再来分享一下带误差棒的堆叠柱状图的绘制模板。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源…

管理类联考——数学——技巧篇——公式——几何题

三角形 三角形面积公式 S 1 2 b c s i n A 1 2 a c s i n B 1 2 a b s i n C S\frac{1}{2}bcsinA\frac{1}{2}acsinB\frac{1}{2}absinC S21​bcsinA21​acsinB21​absinC(正弦定理)&#xff1b; S p ( p − a ) ( p − b ) ( p − c ) S\sqrt{p(p-a)(p-b)(p-c)} Sp(p−a)…

JAVA-编程基础-06-数组

Lison <dreamlison163.com>, v1.0.0, 2023.03.22 JAVA-编程基础-06-数组 什么是数组 ​ 数组是一种线性数据结构&#xff0c;是一个使用连续的内存空间存放相同的数据类型的集合容器&#xff0c;与其他容器相比&#xff0c;数组的区别主要在于性能与保存基本类型的能力…

ASUS华硕天选air笔记本FX516P原装出厂原厂Win10系统镜像

ASUS华硕笔记本天选air FX516P原厂Windows10系统恢复原装出厂OEM预装自带系统 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、华硕电脑管家、奥创控制中心等预装程序 链接&#xff1a;https://pan.baidu.com/s/150QimXQfATAhzxNCl690Nw?pwdhvj6 提取码&#xff1a;h…

10年来测试行业所遇问题,功能/接口/自动化测试?

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 10年来测试行业发…

Apache Doris (八) :Doris分布式部署(五) Broker部署及Doris集群启动脚本

目录 1.Broker部署及扩缩容 1.1 BROKER 部署 1.2 BROKER 扩缩容 2. Apache Doris集群启停脚本 进入正文之前&#xff0c;欢迎订阅专题、对博文点赞、评论、收藏&#xff0c;关注IT贫道&#xff0c;获取高质量博客内容&#xff01; 1.Broker部署及扩缩容 Broker 是 Doris 集…

【系统架构】第六章-数据库设计基础知识(数据库基本概念、关系数据库)

软考-系统架构设计师知识点提炼-系统架构设计师教程&#xff08;第2版&#xff09; 数据库基本概念 数据库的基础结构是数据模型&#xff0c;数据模型的三要素是数据结构、数据操作和数据的约束条件 数据库三级模式&#xff1a;视图层、逻辑层、物理层 视图层&#xff1a;最高…

Day.2 LeetCode刷题练习(螺旋矩阵)

题目&#xff1a; 例子&#xff1a; 分析题目&#xff1a; 本题给了一个值n要生成一个n*n的矩形&#xff0c;并且是螺旋的生成值。 这样我们可以把它分层来看如n 4时生成一个4*4的矩形由两层矩形构成&#xff0c;这样就能先遍历生成最外面的一层后再去生成里面的一层 那如何…