继承-安全-设计模式

news2024/11/13 13:03:24

继承 与 原型、原型链

1. 继承是什么?

  • 继承就是一个对象可以访问另外一个对象中的属性和方法

2. 继承的目的?

  • 继承的目的就是实现原来设计与代码的重用

3. 继承的方式

  • java、c++等:class
  • **javaScript: 原型链 ** ES2015/ES6 中引入了 class 关键字,但那只是语法糖,JavaScript 的继承依然和基于类的继承没有一点关系

4. 原型与原型链

JavaScript 只有一种结构:对象。

JavaScript 的每个对象都包含了一个隐藏属性__proto__,我们就把该隐藏属性 proto 称之为该对象的原型 (prototype),proto 指向了内存中的另外一个对象,我们就把 proto 指向的对象称为该对象的原型,那么该对象就可以直接访问其原型对象的方法或者属性。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pzx6Lxsa-1666612964587)(02.png)]

看到使用 C.name 和 C.color 时,给人的感觉属性 name 和 color 都是对象 C 本身的属性,但实际上这些属性都是位于原型对象上,我们把这个查找属性的路径称为原型链

每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

总结:继承就是一个对象可以访问另外一个对象中的属性和方法,在JavaScript 中,我们通过原型和原型链的方式来实现了继承特性。

5. 继承的方式

5.1 构造函数如何创建对象

function DogFactory(type, color) {
    this.type = type;
    this.color = color
}

var dog = new DogFactory('Dog','Black')

创建实例的过程

var dog = {};
dog.__proto__ = DogFactory.prototype;
DogFactory.call(dog,'Dog','Black');

观察上图,我们可以看到执行流程分为三步:

首先,创建了一个空白对象 dog;

然后,将 DogFactory 的 prototype 属性设置为 dog 的原型对象,这就是给 dog 对象设置原型对象的关键一步;

每个函数对象中都有一个公开的 prototype 属性,当你将这个函数作为构造函数来创建一个新的对象时,新创建对象的原型对象就指向了该函数的 prototype 属性,所以通过该构造函数创建的任何实例都可以通过原型链找到构造函数的prototype上的属性

最后,再使用 dog 来调用 DogFactory,这时候 DogFactory 函数中的 this 就指向了对象 dog,然后在 DogFactory 函数中,利用 this 对对象 dog 执行属性填充操作,最终就创建了对象 dog。

实例的proto属性 == 构造函数的proyotype

5.2 原型链继承

原理: 实现的本质是通过将子类的原型指向了父类的实例,

优点:

  • 父类新增原型方法/原型属性,子类都能访问到
  • 简单容易实现

缺点:

  • 不能实现多重继承
  • 来自原型对象的所有属性被所有实例共享
  • 创建子类实例时,无法向父类构造函数传参
    在这里插入图片描述
//父类型
function Person(name, age) {
    this.name = name,
    this.age = age,
    this.play = [1, 2, 3]
    this.setName = function () { }
}
Person.prototype.setAge = function () { }
//子类型
function Student(price) {
    this.price = price
    this.setScore = function () { }
}
Student.prototype = new Person('wang',23) // 子类型的原型为父类型的一个实例对象
var s1 = new Student(15000)
var s2 = new Student(14000)
console.log(s1,s2)

5.3 借用构造函数实现继承

原理:在子类型构造函数中通用call()调用父类型构造函数

特点

  • 解决了原型链继承中子类实例共享父类引用属性的问题
  • 创建子类实例时,可以向父类传递参数
  • 可以实现多重继承(call多个父类对象)

缺点

  • 实例并不是父类的实例,只是子类的实例
  • 只能继承父类的实例属性和方法,不能继承父类原型属性和方法
  • 无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
function Person(name, age) {
    this.name = name,
    this.age = age,
    this.setName = function () {}
  }
  Person.prototype.setAge = function () {}
  function Student(name, age, price) {
    Person.call(this, name, age) 
    // 相当于: 
    /*
    this.Person(name, age)
    this.name = name
    this.age = age*/
    this.price = price
  }
  var s1 = new Student('Tom', 20, 15000)

5.4 原型链+借用构造函数的组合继承

原理:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用。

优点

  • 可以继承实例属性/方法,也可以继承原型属性/方法
  • 不存在引用属性共享问题
  • 可传参
  • 父类原型上的函数可复用

缺点

  • 调用了两次父类构造函数,生成了两份实例
function Person(name, age) {
    this.name = name,
    this.age = age,
    this.setAge = function () { }
}
Person.prototype.setAge = function () {
    console.log("111")
}
function Student(name, age, price) {
    Person.call(this,name,age)
    this.price = price
    this.setScore = function () { }
}
Student.prototype = new Person()
Student.prototype.constructor = Student//组合继承也是需要修复构造函数指向的
var s1 = new Student('Tom', 20, 15000)
var s2 = new Student('Jack', 22, 14000)
console.log(s1)
console.log(s1.constructor) //Student

5.5 ES6 class继承

**原理:**ES6中引入了class关键字,class可以通过extends关键字实现继承,还可以通过static关键字定义类的静态方法,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

优点

  • 语法简单易懂,操作更方便

缺点

  • 并不是所有的浏览器都支持class关键字
class Person {
    //调用类的构造方法
    constructor(name, age) {
        this.name = name
        this.age = age
    }
    //定义一般的方法
    showName() {
        console.log("调用父类的方法")
        console.log(this.name, this.age);
    }
}
let p1 = new  Person('kobe', 39)
console.log(p1)
//定义一个子类
class Student extends Person {
    constructor(name, age, salary) {
        super(name, age)//通过super调用父类的构造方法
        this.salary = salary
    }
    showName() {//在子类自身定义方法
        console.log("调用子类的方法")
        console.log(this.name, this.age, this.salary);
    }
}
let s1 = new Student('wade', 38, 1000000000)
console.log(s1)
s1.showName()

安全

1. CSRF攻击

1.1 什么是CSRF攻击?

​ CSRF全称为跨站请求伪造(Cross-site request forgery)

​ 攻击者盗用了你的身份信息,以你的名义发送恶意请求,

​ 对服务器来说这个请求是你发起的,却完成了攻击者所期望的一个操作

1.2 危害

​ 修改用户信息,修改密码,以你的名义发送邮件、发消息、盗取你的账号等

1.3 攻击条件

​ 用户已登录存在CSRF漏洞的网站

​ 用户需要被诱导打开攻击者构造的恶意网站

1.4 防范

1.4.1 验证HTTP Referer字段

​ referer字段表明了请求来源,通过在服务器端添加对请求头字段的验证拒绝一切跨站请求,

​ 但是请求头可以绕过,XHR对象通过setRequestHeader方法可以伪造请求头

1.4.2 添加token验证

​ 客户端令牌token通常作为一种身份标识,由服务器端生成的一串字符串,当第一次登录后,

​ 服务器生成一个token返回给客户端,以后客户端只需带上token来请求数据即可,无需再次带上用户名和密码。

​ 如果来自浏览器请求中的token值与服务器发送给用户的token不匹配,或者请求中token不存在,

​ 则拒绝该请求,使用token验证可以有效防止CSRF攻击,但增加了后端数据处理的工作量

1.4.3 验证码

​ 发送请求前需要输入基于服务端判断的验证码,机制与token类似,

​ 验证码强制用户与web完成交互后才能实现正常请求,最简洁而有效的方法,但影响用户体验

2. XSS攻击

2.1 什么是xss攻击

XSS又叫CSS(Cross Site Script),跨站脚本攻击:攻击者在目标网站植入恶意脚本(js / html),用户在浏览器上运行时可以获取用户敏感信息(cookie / session)、修改web页面以欺骗用户、与其他漏洞相结合形成蠕虫等。

对特殊字符进行转译就好了(vue/react等主流框架已经避免类似问题,vue举例:不能在template中写script标签,无法在js中通过ref或append等方式动态改变或添加script标签)

2.2 危害

  • 使网页无法正常运行
  • 获取cookie信息
  • 劫持流量恶意跳转

2.3 攻击条件

  • 网页内部有输入框,内容可存储在服务器上

2.4 防御措施(对用户输入内容和服务端返回内容进行过滤和转译)

  • 现代大部分浏览器都自带 XSS 筛选器,vue / react 等成熟框架也对 XSS 进行一些防护
  • 过滤,对诸如

3. iframe

3.1 如何让自己的网站不被其他网站的 iframe 引用?

// 检测当前网站是否被第三方iframe引用
// 若相等证明没有被第三方引用,若不等证明被第三方引用。当发现被引用时强制跳转百度。
if(top.location != self.location){
    top.location.href = 'http://www.baidu.com'
}

3.2 如何禁用,被使用的 iframe 对当前网站某些操作?

sandbox是html5的新属性,主要是提高iframe安全系数。iframe因安全问题而臭名昭著,这主要是因为iframe常被用于嵌入到第三方中,然后执行某些恶意操作。
现在有一场景:我的网站需要 iframe 引用某网站,但是不想被该网站操作DOM、不想加载某些js(广告、弹框等)、当前窗口被强行跳转链接等,我们可以设置 sandbox 属性。如使用多项用空格分隔。

  • allow-same-origin:允许被视为同源,即可操作父级DOM或cookie等
  • allow-top-navigation:允许当前iframe的引用网页通过url跳转链接或加载
  • allow-forms:允许表单提交
  • allow-scripts:允许执行脚本文件
  • allow-popups:允许浏览器打开新窗口进行跳转
  • “”:设置为空时上面所有允许全部禁止

4. opener

4.1 原理

在项目中需要 打开新标签 进行跳转一般会有两种方式,通过这两种方式打开的页面可以使用 window.opener 来访问源页面的 window 对象

HTML ->

JS -> window.open(‘http://www.baidu.com’)

场景:A 页面通过 或 window.open 方式,打开 B 页面。但是 B 页面存在恶意代码如下:

  • window.opener.location.replace(‘https://www.baidu.com’) 【此代码仅针对打开新标签有效】,此时,用户正在浏览新标签页,但是原来网站的标签页已经被导航到了百度页面。

4.2 风险

  • 新打开的地址无限模仿用户要打开的网站,用户输入用户名密码或者交易等都在恶意网站上进行,风险极高,即使在跨域状态下 opener 仍可以调用 location.replace 方法。

4.3 避免方案

<a target="_blank" href="" rel="noopener noreferrer nofollow">a标签跳转url</a>

通过 rel 属性进行控制:
noopener:会将 window.opener 置空,从而源标签页不会进行跳转(存在浏览器兼容问题)
noreferrer:兼容老浏览器/火狐。禁用HTTP头部Referer属性(后端方式)。
nofollow:指示搜索引擎不要追踪(即抓取)网页上的任何出站链接

<button onclick='openurl("http://www.baidu.com")'>click跳转</button>

function openurl(url) {
    var newTab = window.open();
    newTab.opener = null;
    newTab.location = url;
}

5. ClickJacking(点击劫持)

5.1 原理

  1. 访问者被恶意页面吸引。怎样吸引的不重要。
  2. 页面上有一个看起来无害的链接(例如:“变得富有”或者“点我,超好玩!”)。
  3. 恶意页面在该链接上方放置了一个透明的 <iframe>,其 src 来自于 facebook.com,这使得“点赞”按钮恰好位于该链接上面。这通常是通过 z-index 实现的。
  4. 用户尝试点击该链接时,实际上点击的是“点赞”按钮。

5.2 风险

  • 在用户不知情的情况下就对某个网站进行了操作

5.3 避免方案

X-Frame-Options:X-Frame-Options可以说是为了解决ClickJacking而生的,它有三个可选的值:

DENY 拒绝当前页面加载任何frame页面
SAMEORIGIN frame页面的地址只能为同源域名下的页面
ALLOW-FROM origin 定义允许frame加载的页面地址

6.本地存储数据问题

很多开发者为了方便,把一些个人信息不经加密直接存到本地或者cookie,这样是非常不安全的,黑客们可以很容易就拿到用户的信息,所有在放到cookie中的信息或者localStorage里的信息要进行加密,加密可以自己定义一些加密方法或者网上寻找一些加密的插件,或者用base64进行多次加密然后再多次解码,这样就比较安全了。

7. 第三方依赖安全隐患

项目开发,很多都喜欢用别人写好的包,为了方便快捷,很快的就搭建起项目,自己写的代码不到20%,过多的用第三方依赖或者插件,一方面会影响性能问题,另一方面第三方的依赖或者插件存在很多安全性问题,也会存在这样那样的漏洞,所以使用起来得谨慎。

解决办法:手动去检查那些依赖的安全性问题基本是不可能的,最好是利用一些自动化的工具进行扫描过后再用,比如NSP(Node Security Platform),Snyk等等。

8.HTTPS加密传输数据

在浏览器对服务器访问或者请求的过程中,会经过很多的协议或者步骤,当其中的某一步被黑客拦截的时候,如果信息没有加密,就会很容易被盗取。所以接口请求以及网站部署等最好进行HTTPS加密,这样防止被人盗取数据。

观察者与发布订阅者模式

1. 观察者模式

官方给出的观察者模式的解释是这样的:

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

观察者模式实现的,其实就是当目标对象的某个属性发生了改变,所有依赖着目标对象的观察者都将接到通知,做出相应动作。 所以在目标对象的抽象类里,会保存一个观察者序列。当目标对象的属性发生改变生,会从观察者队列里取观察者调用各自的方法。

class Subject {
    constructor() {
        this.observers = [];
    }
 
    add(observer) {
        this.observers.push(observer);
    }
 
    notify(...args) {
        this.observers.forEach(observer => observer.update(...args));
    }
}
 
class Observer {
    update(...args) {
        console.log(...args);
    }
}
 
// 创建观察者ob1
let ob1 =new Observer();
// 创建观察者ob2
let ob2 =new Observer();
// 创建目标sub
let sub =new Subject();
// 目标sub添加观察者ob1 (目标和观察者建立了依赖关系)
sub.add(ob1);
// 目标sub添加观察者ob2
sub.add(ob2);
// 目标sub触发SMS事件(目标主动通知观察者)
sub.notify('I fired `SMS` event');

2. 发布/订阅模式

在发布订阅模式里,发布者,并不会直接通知订阅者,换句话说,发布者和订阅者,彼此互不相识。

发布/订阅模式相比于观察者模式多了一个中间媒介,因为这个中间媒介,发布者和订阅者的关联更为松耦合

发布-订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。

也就是说,发布/订阅模式和观察者最大的差别就在于消息是否通过一个中间类进行转发。

classPubSub {
    constructor() {
        this.subscribers = [];
    }
     
    subscribe(topic, callback) {
        letcallbacks =this.subscribers[topic];
        if(!callbacks) {
            this.subscribers[topic] = [callback];
        }else{
            callbacks.push(callback);
        }
    }
     
    publish(topic, ...args) {
        letcallbacks =this.subscribers[topic] || [];
        callbacks.forEach(callback => callback(...args));
    }
}
 
// 创建事件调度中心,为订阅者和发布者提供调度服务
letpubSub =newPubSub();
// A订阅了SMS事件(A只关注SMS本身,而不关心谁发布这个事件)
pubSub.subscribe('SMS', console.log);
// B订阅了SMS事件
pubSub.subscribe('SMS', console.log);
// C发布了SMS事件(C只关注SMS本身,不关心谁订阅了这个事件)
pubSub.publish('SMS','I published `SMS` event');

3. 两种模式的区别

由上,我们就可以得出这两者的区别了:

  • 观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。

  • 发布订阅模式中,组件是松散耦合的,正好和观察者模式相反。

  • 观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vyTRJybN-1666613145312)(https://user-gold-cdn.xitu.io/2019/11/3/16e30c9869b37af4?imageView2/0/w/1280/h/960/format/webp/ignore-error/1)]

4. 两种模式举例

**观察者:**事件处理(一旦触发事件,立即执行)

document.body.addEventListener('click',function(){
alert('我也是一个观察者,你一点击,我就知道了');
});

其中,body是发布者,即目标对象,当被点击的时候,向观察者反馈这一事件;JavaScript中函数也是一个对象,click这个事件的处理函数(alert(‘…’))就是观察者,当接收到目标对象反馈来的信息时进行一定处理。

**发布订阅者:**事件循环 (例如 发布者:ajax请求,发出去返回之后存在消息队列中,订阅者主线程并不会立即处理回调,而是等着事件循环机制在中间层将回调函数推送导致主线程中执行)

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

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

相关文章

数据导入与预处理-拓展-pandas可视化

数据导入与预处理-拓展-pandas可视化1. 折线图1.1 导入数据1.2 绘制单列折线图1.3 绘制多列折线图1.4 绘制折线图-双y轴2. 条形图2.1 单行垂直/水平条形图2.2 多行条形图3. 直方图3.1 生成数据3.2 透明度/刻度/堆叠直方图3.3 拆分子图4. 散点图4.1生成数据4.2 绘制大小不一的散…

自动化测试的使用场景有哪些?如何正确使用?

目录 前言 什么是自动化测试&#xff1f; 自动化测试的使用场景有哪些&#xff1f; 自动化测试有什么好处&#xff1f; 总结 前言 本文将通过介绍 自动化测试是什么 &#xff0c; 哪些场景适用于自动化测试 &#xff0c; 自动化测试的好处 &#xff0c; 以及通过 具体的自…

vue如何二次封装一个高频可复用的组件

在我们的业务里&#xff0c;我们通常会二次封装一些高频业务组件&#xff0c;比如弹框&#xff0c;抽屉&#xff0c;表单等这些业务组件&#xff0c;为什么要二次封装&#xff1f;我们所有人心里的答案肯定是&#xff0c;同样类似的代码太多了&#xff0c;我想复用组件&#xf…

2004-2020中小企业板上市公司财务报表股票交易董事高管等面板数据

1200变量&#xff01;中小企业板上市公司面板数据大全 2004-2020年 1、时间&#xff1a;2004-2020年 2、数据范围&#xff1a;共计973家上市公司 3、数据指标&#xff1a;包括财务报表、股票交易、董事高管等1200变量 4、用途&#xff1a;进行上市公司高管股权激励与公司绩…

C语言刷题系列——1.将三个整数按从大到小输出

将三个整数按从大到小输出1.输入三个整数2.最大的值放在a中&#xff0c;最小值放在c中&#xff0c;剩余的一个放在bstep1&#xff1a;a和b比较step2&#xff1a;a和c比较step3&#xff1a;b和c比较3.最终的代码1.输入三个整数 先写好main函数、头文件 #include <stdio.h&g…

用高并发技巧解决redis热key问题

​ 这篇文章我将介绍工作中处理热key问题的常用手段&#xff0c;可能介绍的不是很全&#xff0c;毕竟不同的业务场景可能有不同的解决方案&#xff0c;但是相信通过这部分的介绍能提供一个热key问题的思路。 热key问题&#xff0c;简单来说就是对某一资源的访问量过高问题&…

Unity学习shader笔记[一百零八]简单萤火效果

之前用粒子系统基于原有萤火虫的粒子改了一波慢萤火效果就被惊艳到了&#xff0c;开始大家讨论&#xff0c;就都觉得这样大数量的粒子消耗挺大的&#xff0c;后面测试过才发现单纯的粒子系统在总粒子数量3000&#xff0c;每秒300的生成数量&#xff0c;屏幕呈现有1000多个粒子的…

【黄啊码】MySQL入门—17、在没有备份的情况下,如何恢复数据库数据?

大家好&#xff01;我是黄啊码&#xff0c;MySQL的入门篇已经讲到第16个课程了&#xff0c;今天我们继续讲讲大白篇系列——科技与狠活之恢复数据库 在没做数据库备份&#xff0c;没有开启使用 Binlog 的情况下&#xff0c;尽可能地找回数据。 今天的内容主要包括以下几个部分…

2022NISCTF--web

easyssrf 打开题目&#xff0c;显示的是 尝试输入&#xff0c; 发现输入flag有东西 读取文件 访问下一个网站 读取文件 不能以file开头 直接伪协议&#xff0c;base64解码 checkIn 奇怪的unicode编码 当选中左边的时候右边也会被选中 我们在vscode看看 这样的额 展示的是UTF-1…

Linux系统中利用open函数多次打开同一个文件操作方法

大家好。 今天的话主要和大家聊一聊&#xff0c;在Linux系统中如果一个文件被打开多次会出现什么情况。 目录 第一&#xff1a;多次打开同一个文件 ​第二&#xff1a;一个文件被打开多次&#xff0c;在内存中不会存在多份动态文件 ​第三&#xff1a;多次open打开同一…

第一章 - Windows安装VMware Workstation Pro

文章目录前言一、VMware Workstation Pro安装的前提条件二、VMware Workstation Pro下载三、VMware Workstation Pro安装前言 Linux是一个开源、免费的操作系统&#xff0c;其稳定性、安全性、处理多并发已经得到业界认可&#xff0c;目前很多企业级的项目都会部署到Linux系统…

结构体内存对齐

在知道了结构体类型的基本使用之后&#xff0c;我们需要深入探讨一个问题&#xff0c;即计算结构体的大小&#xff0c;这也是一个热门的考点&#xff1a;结构体内存对齐。 目录 一、结构体的对齐规则 二、例题 2.1 例题一 2.2 例题二 2.3 例题三 ​编辑 三、为什么存在内存…

【C++】vector,list迭代器失效

1.vector迭代器失效 vector容器的物理基础是线性表&#xff0c;底层是指针变量实现的。 在这里导致vector迭代器失效的原因会有两种-----插入失效&#xff0c;删除失效。 1.2插入数值导致迭代器失效 1.21扩容导致迭代器失效 我们在一块vector空间插入pos&#xff08;20&…

第三章 单向链表的讲解与实现

初阶数据结构 第一章 时间复杂度和空间复杂度 第二章 动态顺序表的实现 第三章 单向链表的讲解与实现 文章目录初阶数据结构前言一、什么是链表&#xff1f;二、节点的定义&#xff1a;三、单向链表接口函数1、打印&#xff1a;2、尾插&#xff1a;3、头插&#xff1a;4、尾删…

改进YOLOv7系列: 最新结合用于小目标的新CNN卷积构建块

&#x1f4a1;统一使用 YOLOv7 代码框架&#xff0c;结合不同模块来构建不同的YOLO目标检测模型。&#x1f31f;本项目包含大量的改进方式,降低改进难度,改进点包含【Backbone特征主干】、【Neck特征融合】、【Head检测头】、【注意力机制】、【IoU损失函数】、【NMS】、【Loss…

Linux-进程控制

进程控制进程创建fork函数写时拷贝fork常规用法fork调用失败的原因进程终止进程等待进程程序替换程序替换的原理如何程序替换进程创建 fork函数 fork之前父进程独立运行&#xff0c;fork之后&#xff0c;父子两个执行流分别执行。 进程具有独立性&#xff0c;代码和数据必须独立…

机器学习HMM模型

目录1 马尔科夫链1.1 简介1.2 经典举例1.3 小结2 HMM简介2.1 简单案例2.2 案例进阶2.2.1 问题阐述2.2.2 问题解决3 HMM模型基础3.1 什么样的问题需要HMM模型3.2 HMM模型的定义3.3 一个HMM模型实例3.4 HMM观测序列的生成3.5 HMM模型的三个基本问题4 前向后向算法评估观察序列概率…

计算机毕业设计-SSM高校社团招新系统-JavaWeb大学生社团管理系统-源码+文档+讲解

注意&#xff1a;该项目只展示部分功能&#xff0c;如需了解&#xff0c;评论区咨询即可。 本文目录1.开发环境2.系统的设计背景3 前后台功能设计3.1 前台功能3.2 后台功能4 系统页面展示4.1 学生功能模块展示4.2 干部功能模块展示4.3 管理员功能模块展示5 更多推荐6 部分功能代…

如何用IDEA提高你的开发效率

前言 ​ 作为一名java开发工程师&#xff0c;IDEA无疑是我日常接触最多的工具。因此&#xff0c;能否高效使用IDEA软件&#xff0c;一定程度上决定了我们的开发效率。本文将主要介绍IDEA中的四个便于提高开发效率的功能&#xff0c;常用快捷键、实时模版、后缀补全、文件和代码…

《本地计算机DNS缓存文件》

C:\Windows\System32\drivers\etc 36.152.44.95 www.baidu.com 正常访问www.baidu.com可以DNS抓包&#xff0c;将百度的IP及域名加入文件位置的hosts文件中即该IP和域名将不再请求网络上的DNS服务器&#xff0c;即加快域名解析&#xff1b; 具体作用&#xff1a; 1.加快域名解…