探索设计模式的魅力:代理模式揭秘-软件世界的“幕后黑手”


设计模式专栏:http://t.csdnimg.cn/U54zu


目录

引言

一、魔法世界

1.1 定义与核心思想

1.2 静态代理

1.3 动态代理

1.4 虚拟代理

1.5 代理模式结构图

1.6 实例展示如何工作(场景案例)

 不使用模式实现

 有何问题

 使用模式重构示例

二、应用与实践

2.1 如何使用代理模式

2.2 工作中的实际案例

2.3 优点

2.4 缺点

三、避免陷阱与常见误区

3.1 缺点与可能的误用

3.2 性能和复杂度考虑

四、代理趋势 - 未来几年代理模式的展望


引言

    为何选择代理模式。

    在软件开发的世界里,随着项目规模的扩大和复杂性的增加,我们时常面临着这样的挑战:如何在不修改原始对象代码的情况下,为其增加新的操作或功能?这样的需求看似简单,实则在实际项目中经常遇到,而且解决起来并不容易。此时,一种强大的设计模式——代理模式(Proxy Pattern)应运而生,为我们提供了一种优雅而高效的解决方案。
    代理模式是一种结构型设计模式,它提供了一种方式来控制对另一个对象的访问。代理模式的核心思想是在原始对象之前引入一个代理对象,这个代理对象扮演着“中间人”的角色,负责处理客户端的请求,并根据需要决定是否将请求转发给原始对象。通过这种方式,我们可以在不修改原始对象代码的前提下,实现对原始对象行为的扩展或控制。
    代理模式在软件开发中的重要性不容忽视。它允许我们在不改变现有代码结构的情况下,为对象增加额外的职责或行为,从而提高了代码的灵活性和可扩展性。此外,代理模式还可以用于实现远程方法调用、权限控制、性能优化等场景,为软件开发提供了强大的支持。

    在本文中,我们将深入探讨代理模式的原理、实现方式以及应用场景。通过具体的示例和代码分析,我们将帮助读者更好地理解代理模式,并学会如何在实际项目中运用这一强大的设计模式。让我们一起踏上代理模式的探索之旅吧!

        

一、魔法世界

    在软件设计的世界里,代理模式以其独特的方式打开了一扇通往魔法世界的大门。在这个世界里,代理类扮演了魔法使者的角色,替真实对象处理请求,并在必要时将请求传递给真实对象。这种魔法般的操作,不仅让代码更加灵活,还为我们带来了许多意想不到的好处。

1.1 定义与核心思想

 定义

    代理模式是一种设计模式,它提供了一种代理对象来代表和控制另一个对象(真实对象)的访问。代理模式在不改变真实对象接口的前提下,为真实对象添加额外的操作或逻辑,如访问控制、延迟加载、性能优化等。

 核心思想

    代理模式的核心思想:在真实对象之前引入一个代理对象,这个代理对象负责接收客户端的请求,并根据需要决定是否将请求转发给真实对象。

 本质

  代理模式的本质:控制对象访问。

1.2 静态代理

    静态代理是最简单的一种代理模式实现方式。在静态代理中,代理类和真实对象类都实现了相同的接口,并且代理类持有一个真实对象类的实例。代理类在接收到请求后,会根据需要将请求转发给真实对象,或者在转发请求前后添加额外的逻辑。

    特定用途:静态代理通常用于在编译时就已经确定代理类和真实对象类关系的情况。例如,当我们需要为某个对象添加日志记录、权限验证等额外功能时,可以使用静态代理。由于静态代理需要在编译时确定代理类和真实对象类的关系,因此它通常用于功能相对固定、不会频繁变动的场景。

1.3 动态代理

    动态代理是一种更加灵活的代理模式实现方式。在动态代理中,代理类是在运行时动态生成的,而不需要提前编写好代理类的代码。动态代理利用了Java的反射机制和动态生成类的技术,可以在运行时动态地为目标对象创建代理对象。

    特定用途:动态代理通常用于需要在运行时动态地为目标对象添加额外功能的情况。例如,在AOP(面向切面编程)中,我们可以使用动态代理来实现横切关注点(如日志记录、事务管理等)的织入。由于动态代理是在运行时动态生成代理对象,因此它更加灵活,可以适应功能频繁变动的场景。

1.4 虚拟代理

    虚拟代理是一种特殊的代理模式实现方式。在虚拟代理中,代理类并不直接持有真实对象的实例,而是在需要时才创建真实对象。虚拟代理通常用于表示一个资源消耗较大或初始化时间较长的对象,通过延迟对象的创建来降低系统的资源消耗。

    特定用途:虚拟代理通常用于资源消耗较大或初始化时间较长的场景。例如,在加载大型图片或视频时,我们可以使用虚拟代理来延迟加载过程,直到用户真正需要查看图片或视频时才创建真实对象。虚拟代理通过延迟对象的创建,可以有效地降低系统的资源消耗和响应时间。

1.5 代理模式结构图

  1. 代理类(Proxy)代理类是代理模式的核心部分,它实现了与真实对象相同的接口。代理类负责接收客户端的请求,并根据需要决定是否将请求转发给真实对象。代理类还可以在执行请求前后添加额外的逻辑,如权限验证、日志记录等。
  2. 接口(Interface)接口定义了代理类和真实对象需要实现的方法。客户端通过接口与代理类和真实对象进行交互,从而实现了解耦。
  3. 真实对象(Real Object)真实对象是代理类所代表的实际对象,它实现了接口中定义的方法。真实对象负责处理代理类转发过来的请求,并返回结果。

1.6 实例展示如何工作(场景案例)

    假设我们有一个图片加载器,它负责从网络上加载图片。由于网络加载是一个耗时的操作,我们希望在加载图片之前先显示一个占位符,并在图片加载完成后替换占位符。

 不使用模式实现

    不使用模式来实现图片加载器的功能,我们可能需要直接在客户端代码中处理图片加载的逻辑,包括显示占位符、执行网络请求以及替换占位符。以下是一种不使用代理模式的实现方式:

    首先,我们仍然需要定义ImageLoader接口和RealImageLoader类,这些类将负责实际的图片加载工作。

public interface ImageLoader {  void loadImage();  
}  public class RealImageLoader implements ImageLoader {  @Override  public void loadImage() {  // 模拟网络加载图片的耗时操作  try {  Thread.sleep(2000);  } catch (InterruptedException e) {  e.printStackTrace();  }  System.out.println("图片加载完成!");  }  
}

    然后,在客户端代码中,我们需要负责处理显示占位符和替换占位符的逻辑。这可以通过在调用RealImageLoader的loadImage方法之前和之后手动添加这些逻辑来实现。

public class Client {  public static void main(String[] args) {  RealImageLoader realImageLoader = new RealImageLoader();  // 显示占位符  System.out.println("显示占位符...");  // 加载图片  new Thread(realImageLoader).start(); // 使用新线程来避免阻塞UI  // 等待图片加载完成(这里假设我们有一种机制来知道图片何时加载完成)  // 实际上,这通常涉及到一些复杂的同步机制,例如使用Future、CountDownLatch等  // 替换占位符为真实图片  System.out.println("替换占位符为真实图片...");  }  
}
    在这个实现中,我们创建了一个新的线程来执行RealImageLoaderloadImage方法,以避免阻塞主线程(通常是UI线程)。但是,这要求我们有一种机制来知道何时图片加载完成,以便我们可以安全地替换占位符。这可能涉及到一些复杂的同步机制,例如使用FutureCountDownLatch或其他并发工具。

 有何问题

    不使用代理模式的这种方法有几个缺点:

 1. 复杂性增加

  • 客户端代码需要处理更多的逻辑,包括同步和线程管理。

 2. 代码可读性和维护性下降

  • 由于加载逻辑和显示逻辑混合在一起,代码的可读性和可维护性可能会受到影响。

 3. 缺乏灵活性

  • 如果以后需要添加新的逻辑(如权限检查、日志记录等),客户端代码可能需要进行大量修改。

 4. 同步问题

  • 等待图片加载完成并替换占位符可能需要复杂的同步机制,这增加了出错的可能性。

 使用模式重构示例

    为了更好地理解代理模式的工作原理和解决以上的问题,我们使用代理模式来实现这个功能。

    首先,我们定义一个接口ImageLoader,它包含了加载图片的方法loadImage()

public interface ImageLoader {  void loadImage();  
}

    然后,我们创建一个真实对象RealImageLoader,它实现了ImageLoader接口,并实现了实际的图片加载逻辑:

public class RealImageLoader implements ImageLoader {  @Override  public void loadImage() {  // 模拟网络加载图片的耗时操作  try {  Thread.sleep(2000);  } catch (InterruptedException e) {  e.printStackTrace();  }  System.out.println("图片加载完成!");  }  
}

    接下来,我们创建一个代理类ProxyImageLoader,它也实现了ImageLoader接口,并在内部持有一个真实对象的引用。代理类负责接收加载图片的请求,并在必要时将请求转发给真实对象:

public class ProxyImageLoader implements ImageLoader {  private RealImageLoader realImageLoader;  public ProxyImageLoader(RealImageLoader realImageLoader) {  this.realImageLoader = realImageLoader;  }  @Override  public void loadImage() {  System.out.println("显示占位符...");  // 在真实对象加载图片之前,先显示占位符  realImageLoader.loadImage();  System.out.println("替换占位符为真实图片...");  }  
}

    最后,在客户端代码中,我们通过代理类来加载图片:

public class Client {  public static void main(String[] args) {  RealImageLoader realImageLoader = new RealImageLoader();  ProxyImageLoader proxyImageLoader = new ProxyImageLoader(realImageLoader);  proxyImageLoader.loadImage();  }  
}

    运行客户端代码后,我们可以看到以下输出:

显示占位符...  
图片加载完成!  
替换占位符为真实图片...

    通过代理模式,我们在不修改真实对象代码的情况下,实现了在加载图片之前先显示占位符的功能。这种魔法般的操作让我们可以更加灵活地控制对象的访问和扩展对象的行为。

        

二、应用与实践

    代理模式作为一种灵活且强大的设计模式,在软件开发中拥有广泛的应用场景。通过代理模式,我们可以提升系统性能、增强对对象的控制、实现延迟初始化和增强系统安全性。下面,我们将探讨如何使用代理模式,并通过实际案例来展示代理模式在工作中的价值。

2.1 如何使用代理模式

    使用代理模式通常需要以下几个步骤:

 1. 定义接口

  • 首先,我们需要定义一个接口,该接口将被真实对象和代理对象共同实现。这个接口定义了客户端与对象交互所需的方法。

 2. 创建真实对象

  • 实现接口,并实现接口中定义的具体业务逻辑。这是实际执行工作的对象。

 3. 创建代理对象

  • 同样实现接口,并在其内部持有真实对象的引用。代理对象负责处理客户端的请求,根据需要在调用真实对象的方法前后添加额外的逻辑。

 4. 客户端使用代理对象

  • 客户端通过代理对象与真实对象进行交互,而不需要直接与真实对象交互。代理对象根据需要决定是否将请求转发给真实对象。

2.2 工作中的实际案例

 1. 性能优化:缓存代理

  • 在Web应用中,我们经常需要处理大量的数据库查询操作。为了提高性能,我们可以使用缓存代理来缓存查询结果。当相同的查询再次发生时,代理可以直接从缓存中返回结果,而不需要再次访问数据库。这大大减少了数据库的负载,提高了系统的响应速度。

 2. 控制访问:权限代理

  • 在许多系统中,我们需要对用户的访问权限进行控制。通过权限代理,我们可以在用户请求访问资源之前进行权限验证。如果用户具有访问权限,代理将请求转发给实际资源;否则,代理将拒绝请求并返回错误消息。

 3. 延迟初始化:资源加载代理

  • 在处理大型资源(如大型图片、视频文件或远程数据)时,我们可以使用资源加载代理来延迟资源的加载。代理可以在用户实际需要查看资源时才加载资源,从而减少了系统启动时的资源消耗和加载时间。

 4. 安全性增强:安全代理

  • 在安全敏感的应用中,我们可以使用安全代理来增强系统的安全性。代理可以在请求被处理之前对请求进行安全检查,如验证用户身份、检查请求参数等。这有助于防止恶意请求对系统的攻击和破坏。

2.3 优点

 1. 提升性能

  • 通过缓存代理、延迟加载等方式,减少不必要的计算或资源消耗,提高系统性能。

 2. 增强控制

  • 通过权限代理、安全代理等,实现对对象访问的精细控制,保护系统的安全性和稳定性。

 3. 延迟初始化

  • 通过资源加载代理等方式,延迟对象的创建和资源的加载,降低系统启动时的负载。

 4. 安全性增强

  • 通过安全代理等方式,对请求进行安全检查,增强系统的安全性和鲁棒性。

2.4 缺点

 1. 额外复杂性

  • 代理模式的引入增加了系统的复杂性。你需要创建额外的代理类,并在其中实现与真实对象相同的接口。这可能会增加代码的维护成本,并需要额外的测试来确保代理类正确地实现了接口并正确地转发请求。

 2. 潜在的性能开销

  • 虽然代理模式可以提高性能,但在某些情况下,它也可能引入额外的性能开销。代理对象需要在客户端和真实对象之间进行额外的跳转,这可能会增加处理请求的时间。尤其是在代理对象需要进行大量逻辑处理时,这种性能开销可能更加明显。

 3. 可能的内存占用

  • 代理对象可能会占用额外的内存空间,特别是当代理对象持有大量数据或复杂逻辑时。如果系统中存在大量的代理对象,这可能会导致内存占用增加,从而影响系统的整体性能。

 4. 透明性问题

  • 代理模式的一个关键问题是它可能对客户端代码产生透明性问题。客户端代码需要知道它正在与代理对象交互,而不是直接与真实对象交互。这可能会导致客户端代码更加复杂,并需要额外的逻辑来处理代理对象。

 5. 灵活性限制

  • 在某些情况下,代理模式可能会限制系统的灵活性。由于代理对象需要在客户端和真实对象之间进行中转,这可能会限制真实对象的使用方式。例如,某些针对真实对象的优化或特殊用法可能无法在代理模式下直接实现。

三、避免陷阱与常见误区

    尽管代理模式为我们提供了许多便利和优势,但在实际应用中,如果不加以注意,我们可能会陷入一些陷阱和误区。在本章中,我们将探讨代理模式的缺点与可能的误用,并讨论如何避免这些问题,以及提供相关的解决方法和最佳实践。

3.1 缺点与可能的误用

 1. 过度使用

  • 代理模式可能会过度使用,导致系统中存在大量的代理对象。这不仅增加了代码的复杂性,还可能导致性能下降和内存占用增加。

 2. 不必要的代理

  • 有时,我们可能会在不必要的情况下使用代理模式,增加了系统的复杂性和维护成本。

 3. 不恰当的代理逻辑

  • 在代理对象中添加了过多的逻辑处理,可能会导致性能下降和逻辑混乱。

 4. 忽略透明性

  • 代理模式可能会影响系统的透明性,使客户端代码难以理解和维护。

3.2 性能和复杂度考虑

    使用代理模式时,我们需要权衡性能和代码复杂度之间的关系。过多的代理对象可能会导致性能下降,而复杂的代理逻辑可能会增加代码的维护成本。因此,在使用代理模式时,我们应该仔细考虑是否需要代理,以及代理中应该包含哪些逻辑。

 解决方法

 1. 适度使用

  • 避免过度使用代理模式,只在必要时使用代理对象。

 2. 简化代理逻辑

  • 尽量保持代理对象的逻辑简单,避免在代理中添加过多的业务逻辑。

 3. 保持透明性

  • 尽量保持代理对象的透明性,使客户端代码能够无缝地与代理对象进行交互。

 4. 合理设计接口

  • 设计合理的接口,使代理对象和真实对象能够方便地实现相同的接口,从而简化客户端代码。

 最佳实践

 1. 明确需求

  • 在使用代理模式之前,明确系统的需求,确定是否真正需要代理对象。

 2. 遵循单一职责原则

  • 代理对象应该只负责代理相关的逻辑,避免承担过多的职责。

 3. 测试覆盖

  • 对代理对象进行充分的测试,确保代理逻辑的正确性和性能。

 4. 文档化

  • 为代理对象和相关的逻辑提供清晰的文档说明,方便其他开发人员理解和维护代码。

四、代理趋势 - 未来几年代理模式的展望

    在本文的最后篇章,我们着眼未来,展望代理模式如何在最新技术的浪潮中不仅保持其重要性,而且变得更加关键。随着云计算、物联网(IoT)和边缘计算的兴起,代理模式预计将作为一种扩展性和安全性的重要工具而得到更广泛的采用。在分布式系统中,代理可以作为一个轻量级的中间件,协调不同服务之间复杂的交互,并在异构环境中提供缓冲和消息队列功能。
    我们预见,动态代理将变得更加灵活和强大,它可以实现在运行时向系统动态添加行为。这将配合微服务和自适应系统架构,允许软件更好地管理资源并快速响应变化。同时,随着人工智能和机器学习的集成,代理或许能够使用预测模型来自主优化其行为,提升系统表现和用户体验。
    在安全性领域,代理模式有望加强对网络流量的监控和过滤,特别是在面临更加复杂的网络攻击和隐私保护挑战的时代。智能代理可以实施更复杂的权限管理策略,并在必要时进行敏感操作的审计和验证
    结论是,随着技术的持续进步,代理模式将继续在现代软件架构中扮演重要角色。它不仅提供了设计灵活性和扩展性,而且在安全性、性能优化和服务管理方面提供了关键的支持。代理模式的未来看起来既光明又必要,它准备好在下一次技术革命中发挥其不可或缺的作用。

        

结语:通过本文的学习,相信你已经对代理模式有了深入的了解。掌握代理模式,让你在软件开发中更加游刃有余,轻松实现对象操作的灵活代理。期待你在未来的项目中,能够灵活运用代理模式,创造出更加出色的作品!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

车载电子电器架构 —— 电子电气系统车载功能子系统

车载电子电器架构 —— 电子电气系统车载功能子系统 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 本就是小人物,输了就是输了&#xff0c…

osg模型的平移、缩放、旋转

加载2个模型,其中一个向上移动28个单位; 加载2个模型,其中一个缩放0.5倍,向下移动22个单位; 加载2个模型,其中一个缩放0.5倍、旋转45度、向右向下移动几个单位; 都是用矩阵实现的; …

【笔记】Harmony学习:下载安装 DevEco Studio 开发工具IDE

IDE 安装 从官网下载DevEco Studio 安装包后进行安装, 安装完毕后,本地环境可能要配置相关工具,可以通过下面的诊断检测一下本地环境,通过蓝色“Set it up now” 可以快速安装。 1. Node.js (for ohpm) 2. ohpm 下载op的包管理&a…

Codeforces Round 923 (Div. 3) C. Choose the Different Ones(Java)

比赛链接:Round 923 (Div. 3) C题传送门:C. Choose the Different Ones! 题目: ** Example** ** input** 6 6 5 6 2 3 8 5 6 5 1 3 4 10 5 6 5 6 2 3 4 5 6 5 1 3 8 10 3 3 3 4 1 3 5 2 4 6 2 5 4 1 4 7 3 4 4 2 1 4 2 2 6 4 4 2 1 5 2 3 …

实现远程开机(电脑)的各种方法总结

一.为什么要远程开机 因为工作需要,总是需要打开某台不在身边的电脑,相信很多值友也遇到过相同的问题,出门在外,或者在公司,突然需要的一个文件存在家里的电脑上,如果家里有人可以打个电话回家&#xff0c…

1978-2023年全国国内生产总值、分产业分行业增加值相关指标数据

1978-2023年全国国内生产总值、分产业分行业增加值相关指标数据 1、时间:1978-2023年 2、指标:国内生产总值(亿元)、第一产业增加值(亿元)、第二产业增加值(亿元)、第三产业增加值(亿元)、人均国内生产总值(元)、国民总收入指数(上年100)、国内生产总值…

SQL 表信息 | 统计 | 脚本

介绍 统计多个 SQL Server 实例上多个数据库的表大小、最后修改时间和行数,可以使用以下的 SQL 查询来获取这些信息。 脚本 示例脚本: DECLARE Query NVARCHAR(MAX)-- 创建一个临时表用于存储结果 CREATE TABLE #TableSizes (DatabaseName NVARCHAR…

2024Node.js零基础教程(小白友好型),nodejs新手到高手,(六)NodeJS入门——http模块

047_http模块_获取请求行和请求头 hello,大家好,那第二节我们来介绍一下如何在这个服务当中来提取 HTT 请求报文的相关内容。首先先说一下关于报文的提取的方法,我在这个文档当中都已经记录好了,方便大家后续做一个快速的查阅。 …

Shell脚本编程

文章目录 一、简介二、变量变量命名使用变量只读变量删除变量变量种类 三、数组四、算数运算五、条件测试数值测试字符串测试文件测试组合测试 六、选择执行七、用户交互read命令 八、循环语句for循环while循环until循环 九、函数十、调试脚本十一、环境配置bash配置文件案例&a…

Matlab使用点云工具箱进行点云配准ICP\NDT\CPD

一、代码 主代码main.m,三种配准方法任选其一 % 读取点云文件 source_pc pcread(bun_zipper.ply); target_pc pcread(bun_zipper2.ply);% 下采样 ptCloudA point_downsample(source_pc); ptCloudB point_downsample(target_pc);% 配准参数设置 opt param_set…

基于YOLOv8的暗光低光环境下(ExDark数据集)检测,加入多种优化方式---自研CPMS注意力,效果优于CBAM ,助力自动驾驶(二)

💡💡💡本文主要内容:详细介绍了暗光低光数据集检测整个过程,从数据集到训练模型到结果可视化分析,以及如何优化提升检测性能。 💡💡💡加入 自研CPMS注意力 mAP0.5由原始的0.682提升…

大型语言模型(LLM)的优势、劣势和风险

最近关于大型语言模型的奇迹()已经说了很多LLMs。这些荣誉大多是当之无愧的。让 ChatGPT 描述广义相对论,你会得到一个非常好(且准确)的答案。然而,归根结底,ChatGPT 仍然是一个盲目执行其指令集…

使用UMAP降维可视化RAG嵌入

大型语言模型(LLMs)如 GPT-4 已经展示了出色的文本理解和生成能力。但它们在处理领域特定信息方面面临挑战,比如当查询超出训练数据范围时,它们会产生错误的答案。LLMs 的推理过程也缺乏透明度,使用户难以理解达成结论…

【Linux】make和Makefile

目录 make和Makefile make和Makefile 我们使用vim编辑器的时候,在一个文件里写完代码要进行编译,要自己输入编译的指令。有没有一种可以进行自动化编译的方法——makefile文件,它可以指定具体的编译操作,写好makefile文件&#x…

新零售的升维体验,摸索华为云GaussDB如何实现数据赋能

新零售商业模式 商业模式通常是由客户价值、企业资源和能力、盈利方式三个方面构成。其最主要的用途是为实现客户价值最大化。 商业模式通过把能使企业运行的内外各要素整合起来,从而形成一个完整的、高效率的、具有独特核心竞争力的运行系统,并通过最…

【el-tree 文字过长处理方案】

文字过长处理方案 一、示例代码二、关键代码三、效果图 一、示例代码 <divstyle"height: 600px;overflow: auto"class"text item"><el-treeref"tree":data"treeData":props"defaultProps"class"filter-tree&…

fast.ai 深度学习笔记(四)

深度学习 2&#xff1a;第 2 部分第 8 课 原文&#xff1a;medium.com/hiromi_suenaga/deep-learning-2-part-2-lesson-8-5ae195c49493 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 来自 fast.ai 课程的个人笔记。随着我继续复习课程以“真正”理解它&#xff0c;这…

6.0 Zookeeper session 基本原理详解教程

客户端与服务端之间的连接是基于 TCP 长连接&#xff0c;client 端连接 server 端默认的 2181 端口&#xff0c;也就 是 session 会话。 从第一次连接建立开始&#xff0c;客户端开始会话的生命周期&#xff0c;客户端向服务端的ping包请求&#xff0c;每个会话都可以设置一个…

数据分析基础之《pandas(6)—高级处理》

一、缺失值处理 1、如何处理nan 两种思路&#xff1a; &#xff08;1&#xff09;如果样本量很大&#xff0c;可以删除含有缺失值的样本 &#xff08;2&#xff09;如果要珍惜每一个样本&#xff0c;可以替换/插补&#xff08;计算平均值或中位数&#xff09; 2、判断数据是否…

爬虫练习——动态网页的爬取(股票和百度翻译)

动态网页也是字面意思&#xff1a;实时更新的那种 还有就是你在股票这个网站上&#xff0c;翻页。他的地址是不变的 是动态的加载&#xff0c;真正我不太清楚&#xff0c;只知道他是不变的。如果用静态网页的方法就不可行了。 静态网页的翻页&#xff0c;是网址是有规律的。 …