<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>eolink官网</title><link>https://www.eolink.com/news/</link><description>Eolink - API全生命周期管理平台</description><item><title>多平台统一管理软件接口，如何实现多平台统一管理软件接口</title><link>https://www.eolink.com/news/post/89103.html</link><description>&lt;h2&gt;什么是多平台统一管理软件接口？&lt;/h2&gt;&lt;p&gt;多平台统一管理软件接口是一种技术方法，用于将不同平台（例如操作系统、应用程序、云服务等）的软件接口统一管理起来，从而提供更便捷的开发和管理体验。&lt;/p&gt;&lt;br&gt;&lt;h2&gt;为什么需要多平台统一管理软件接口？&lt;/h2&gt;&lt;p&gt;在现代软件开发领域中，常常需要在不同平台上进行开发和部署。然而，不同平台上的软件接口千差万别，开发人员需要逐个适配和调整接口，增加了开发和维护的成本。多平台统一管理软件接口可以解决这个问题，提供一套统一的接口标准，使开发人员能够在不同平台上更高效地开发和管理软件。&lt;/p&gt;&lt;br&gt;&lt;h2&gt;如何实现多平台统一管理软件接口？&lt;/h2&gt;&lt;p&gt;实现多平台统一管理软件接口需要考虑以下几个方面：&lt;/p&gt;&lt;h3&gt;1. 标准化接口定义&lt;/h3&gt;&lt;p&gt;定义一套统一的接口标准，明确接口名称、参数和返回值等规范，以便在不同平台上使用。&lt;/p&gt;&lt;h3&gt;2. 统一管理接口库&lt;/h3&gt;&lt;p&gt;建立一个统一的接口库，将各个平台的接口实现集中管理，方便开发人员查找和使用。&lt;/p&gt;&lt;h3&gt;3. 适配器模式&lt;/h3&gt;&lt;p&gt;使用适配器模式，将不同平台上的具体接口适配为统一接口，使得开发人员可以统一调用。&lt;/p&gt;&lt;h3&gt;4. 版本管理&lt;/h3&gt;&lt;p&gt;对接口进行版本管理，确保不同平台上的接口使用的是同一版本，避免不兼容和冲突问题。&lt;/p&gt;&lt;h3&gt;5. 文档和示例&lt;/h3&gt;&lt;p&gt;提供清晰的文档和示例代码，帮助开发人员理解和使用统一管理软件接口。&lt;/p&gt;&lt;br&gt;&lt;h2&gt;多平台统一管理软件接口的优势&lt;/h2&gt;&lt;p&gt;使用多平台统一管理软件接口可以带来以下几点优势：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;提高开发效率：无需逐个适配不同平台的接口，节省开发时间。&lt;/li&gt;  &lt;li&gt;降低开发成本：减少不同平台接口适配的工作量，降低开发和维护成本。&lt;/li&gt;  &lt;li&gt;简化管理：通过统一管理接口，简化接口的查找和维护过程。&lt;/li&gt;  &lt;li&gt;提升软件质量：使用统一的接口标准，减少接口使用错误和不一致性导致的问题。&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;h2&gt;多平台统一管理软件接口的应用场景&lt;/h2&gt;&lt;p&gt;多平台统一管理软件接口适用于以下场景：&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;跨平台开发：在不同操作系统或应用程序中，统一管理软件接口，方便跨平台开发。&lt;/li&gt;  &lt;li&gt;云服务集成：将云服务的接口进行统一管理，方便在不同云平台上使用和管理。&lt;/li&gt;  &lt;li&gt;移动应用开发：统一管理移动应用的接口，方便在不同移动平台上开发和维护应用程序。&lt;/li&gt;&lt;/ul&gt;&lt;br&gt;&lt;h2&gt;结论&lt;/h2&gt;&lt;p&gt;多平台统一管理软件接口是一种实现不同平台上软件接口统一管理的方法。它可以提高开发效率，降低成本，简化管理，提升软件质量。在跨平台开发、云服务集成和移动应用开发等场景中有着广泛的应用前景。&lt;/p&gt;&lt;br&gt;&lt;h2&gt;常见问题解答&lt;/h2&gt;&lt;h3&gt;问题1：多平台统一管理软件接口会增加系统的复杂性吗？&lt;/h3&gt;&lt;p&gt;答：多平台统一管理软件接口可以降低系统的复杂性，因为它提供了一套统一的接口标准，减少了不同平台接口细节的处理。&lt;/p&gt;&lt;h3&gt;问题2：如何保证多平台统一管理软件接口的兼容性？&lt;/h3&gt;&lt;p&gt;答：通过版本管理和接口规范的制定，可以确保不同平台上的接口使用的是同一版本，避免兼容性问题。&lt;/p&gt;&lt;h3&gt;问题3：多平台统一管理软件接口是否适用于所有类型的软件开发？&lt;/h3&gt;&lt;p&gt;答：多平台统一管理软件接口适用于需要在不同平台上进行开发和部署的软件项目，特别是跨平台开发的情况下。&lt;/p&gt;&lt;h3&gt;问题4：是否有开源的多平台统一管理软件接口库可供使用？&lt;/h3&gt;&lt;p&gt;答：是的，有一些开源的多平台统一管理软件接口库可供使用，开发人员可以根据需要选择合适的接口库。&lt;/p&gt;&lt;h3&gt;问题5：多平台统一管理软件接口是否会对性能造成影响？&lt;/h3&gt;&lt;p&gt;答：多平台统一管理软件接口的设计和实现可以通过合理的优化和缓存机制来减少性能影响，以平衡统一性和性能需求。&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 13:03:03 +0800</pubDate></item><item><title>Flask接口签名sign原理与实例代码浅析</title><link>https://www.eolink.com/news/post/89102.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Flask接口签名sign原理与实例代码浅析&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;觉得废话多的话，可以直接看代码&lt;/p&gt;


        &lt;h2 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;作用&lt;/h2&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;防止有人不停的刷接口，对接口作限制&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;比如说，登录接口，按道理说，应该只有app会请求这个接口&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;但是，如果有人抓取app的请求，就会得到登录接口的地址和请求参数&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;如果他写了个脚本，不断的访问登录接口，去测登录名密码，那么有些有些用户的密码策略过于简单，是很容易被试出来的&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;所以，接口签名就是专门用来限制这个的，只有app(自己人)才能通过校验&lt;/p&gt;


        &lt;h2 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;原理&lt;/h2&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1.服务器和app，各自存储一个相同的秘钥&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2.app请求时，把传的参数用秘钥进行加密，生成一个sign签名，一同传递过去&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3.服务器接到请求后，也会对传递的参数进行加密，也生成一个sign签名，拿服务器生成的sign和接口请求的sing比对一下，如果相同，那么就可以证明，是自己人请求的，就予以放行&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;因为这个秘钥，只有自己人才会有，同样的秘钥生成的sign签名，肯定是一模一样的&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;这个秘钥，一般是开发的时候，线下给到app开发，集成编译到app里面的&lt;/p&gt;


        &lt;h2 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;问题&lt;/h2&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;举例，app和服务器，各自保存了一个秘钥，进行签名验证&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1.app请求登录接口，账号名为abcd，密码为123456，&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2.app对账户名和密码用秘钥加密生成签名，去请求登录接口&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3.服务器收到请求，对账号名和密码也用秘钥加密生成签名，对比发现签名一致，然后予以通过&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4.请求成功&lt;/p&gt;
        &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;问题1&lt;/h3&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;但是，如果下次app还去请求登录的时候，生成的签名，是不是还是一模一样？&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;因为都是对账号和密码加密生成签名，那么只要账号和密码不变，那么生成的签名肯定是一模一样的&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;那如果坏人直接抓包拿到签名、账号和密码，是不是他也可以仿造登录请求，要知道，服务器只接受请求，他是分辨不出来的&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;所以，即使是相同的账号和密码，也要保证，每次的签名都不一致&lt;/p&gt;
        解决办法
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;在对账号和密码进行加密的时候，生成当前时间的时间戳，一起加密，这样就保证了每次生成的签名都一样了&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;传递参数的时候，也需要把加密用的时间戳一同传递过去，因为请求时候延迟的，服务器并不知道你是哪个时间进行加密的&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;那么现在生成签名和请求的步骤就是：&lt;/p&gt;

        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2.app请求登录接口，传参：账号、密码、时间戳、签名&lt;/p&gt;
        &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;问题2&lt;/h3&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;那么问题又来了，跟刚才的问题一样，如果有人抓包，得到账号、密码、时间戳、签名，然后去伪造请求，是不是服务器还会通过？&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;只要账号、密码、时间戳不变化，那么生成的签名，还是一模一样的。&lt;/p&gt;
        解决办法
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;服务器对时间戳进行校验，与当前时间不能相差10秒&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;这样就保证了，这个签名的有效期只有10秒，过了10秒后，就失效了&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;如果想要新的签名，那么就需要用新的时间戳了&lt;/p&gt;
        代码
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;如果需要传递很多参数的时候，还需要对参数进行排序后再加密，要不然app和服务器用了不一样的字符串加密，校验还是会失败的&lt;/p&gt;import hashlib
        import time
        salt = nx24Tej@R4gWVCopJkjHWjBo@n58LdQ5 # 盐, 加密生成签名的秘钥
        def validate_sign(sign, ts, **kwargs):
        &quot;&quot;&quot;时间戳有效期10秒，排序顺序为：盐+时间戳+按照字母排序的参数的值&quot;&quot;&quot;
        # 首先判断ts时间戳，有没有超过10秒有效期
        now_ts = int(time.time())
        if now_ts - int(ts) &amp;gt; 10:
        return False
        # 对字典中的键进行排序
        sort_dict = sorted(kwargs.items(), key=lambda x: x[0])
        # 按照排序拿出值，拼接成字符串，然后加密生成签名
        s = salt + str(ts)
        for key, value in sort_dict:
        s += str(value)
        # 使用sha256加密，与app也要约定好加密方式
        new_sign = hashlib.sha256(s.encode(utf-8)).hexdigest()
        # 比对签名是否一致
        if sign == new_sign:
        return True
        return False
        validate_sign(1, int(time.time()), phone=&quot;15555555555&quot;, password=&quot;123456&quot;)
        # 排序后的字符串：nx24Tej@R4gWVCopJkjHWjBo@n58LdQ5167541269212345615555555555
        # 生成的签名: d87f2833c1f6a1d0d3c67bafdeb0965b0503385dce615662229b27333c9963f7&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;关于Flask接口签名sign原理与实例代码浅析的文章就介绍至此，&lt;/p&gt;

        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Python编程技术&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;DBScan 算法解释说明DBScan 是密度基于空间聚类，它是一种基于密度的聚类算法，其与其他聚类算法（如K-Means）不同的是，它不需要事先知道簇的数量。DBScan 算法通过 ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 13:02:10 +0800</pubDate></item><item><title>java中的接口是类吗</title><link>https://www.eolink.com/news/post/89100.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;java中的接口是类吗&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;java中的接口是类吗&quot;，用于解决相关问题。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;java接口不是类，因为类是使用class关键字定义的，接口是使用interface定义的。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;而且类是一个模板，它描述一类对象的行为和状态；接口是一系列方法的声明，是一些方法特征的集合。&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Java接口是一系列方法的声明，是一些方法特征的集合，一个接口只有方法的特征没有方法的实现，因此这些方法可以在不同的地方被不同的类实现，而这些实现可以具有不同的行为（功能）。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;两种含义：&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;一，Java接口，Java语言中存在的结构，有特定的语法和结构；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;二，一个类所具有的方法的特征集合，是一种逻辑上的抽象。前者叫做“Java接口”，后者叫做“接口”。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Java接口本身没有任何实现，因为Java接口不涉及表象，而只描述public行为，所以Java接口比Java抽象类更抽象化。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;但是接口不是类，不能使用new 运算符实例化一个接口。&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;如 x=new comparable（......）;//这个是错误来的。但是可以声明接口变量Comparable x; //这是允许的。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Java接口的方法只能是抽象的和公开的，Java接口不能有构造器，Java接口可以有public、static和final属性。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;即接口中的属性可以定义为 public static final int value=5;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;接口把方法的特征和方法的实现分割开来。这种分割体现在接口常常代表一个角色，它包装与该角色相关的操作和属性，而实现这个接口的类便是扮演这个角色的演员。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;一个角色由不同的演员来演，而不同的演员之间除了扮演一个共同的角色之外，并不要求其它的共同之处。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;Java接口(以及抽象类)一般用来作为一个类型的等级结构的起点。&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;如果一个类已经有了一个主要的超类型，那么通过实现一个接口，这个类可以拥有另一个次要的超类型，这种次要的超类型叫做混合类型。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;关于 &quot;java中的接口是类吗&lt;/p&gt;

        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Java编程技术&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;java和jvm是什么关系&quot;，用于解决相关问题。JAVA本身就是一门编程语言，它编译生成的文件运行在JVM上（java虚拟机）。JVM是由c语言和汇编语言开发的。基于此之上就是java了，虚拟机是起到解 ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:51:15 +0800</pubDate></item><item><title>vue项目接口域名动态的获取方法</title><link>https://www.eolink.com/news/post/89099.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;vue项目接口域名动态的获取方法&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文主要介绍&quot;vue项目接口域名动态的获取方法&quot;，希望能够解决您遇到有关问题，下面我们一起来看这篇 &quot;vue项目接口域名动态的获取方法&quot; 文章。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;需求：&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;接口域名是从外部 .json 文件里获取的。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;思路：&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;在开始加载项目前 进行接口域名获取，然后重置 接口域名的配置项。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;实现：&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1、config/index.js 文件 进行基础配置&lt;/p&gt;import axios from axios

        const config = {
        requestUrl: http://qiniu.eightyin.cn/path.json, //动态域名所在地址
        baseUrl: {
        dev: /api/,
        pro: http://xxx.com/ // 接口域名，会被动态覆盖
        },

        requestRemoteIp: () =&amp;gt; { // 动态获取
        return new Promise((resolve, reject) =&amp;gt; {
        axios.get(config.requestUrl).then(response =&amp;gt;
        {

        config.baseUrl.pro = response.data.data.path;
        config.img.domain = config.baseUrl.pro;
        resolve()
        }, err =&amp;gt; {
        reject()
        });
        });
        }
        }

        export default config&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2、项目下main.js 文件 进行动态获取&lt;/p&gt;import config from @/config/index.js

        // 读取接口域名
        config.requestRemoteIp().finally(res =&amp;gt; {
        /* eslint-disable no-new */
        new Vue({
        el: #app,

        router,
        components: { App },
        template: &amp;lt;App/&amp;gt;
        })
        });&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3、请求数据&lt;/p&gt;const instance = axios.create({
        baseURL: process.env.NODE_ENV === development &amp;amp;#63; config.baseUrl.dev : config.baseUrl.pro
        })&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;补充知识：&lt;/strong&gt;&lt;strong style=&quot;color: blue;&quot;&gt;webpack + vue 打包生成公共配置文件（域名） 方便动态修改&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;需求原因&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;原来的项目中域名是打包到项目里面的，打包后不能动态配置，只能通过不同的指令打包来切换域名，每天都在测试域名和正式域名来回摩擦，后台大佬说你们可以生成一个配置文件这样就不用频繁打包了直接修改配置文件就好，于是就有了这篇文章。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;第一步 安装插件 &lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;npm install --save-dev generate-asset-webpack-plugin&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;第二步 新建配置文件&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;在项目的根目录下新建 serverConfig.json 以后会根据这个文件去生成打包的配置文件&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;{&quot;ProdUrl&quot;:&quot;http://text.com&quot;}&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;第三步 引入generate-asset-webpack-plugin&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;在build/webpack.prod.conf.js中添加&lt;/p&gt;const GenerateAssetPlugin = require(generate-asset-webpack-plugin);
        const serverConfig = require(../serverConfig.json)；//引入根目录下的配置文件

        const createJson = function() {
        return JSON.stringify(serverConfig);
        };

        //plugins 中使用
        plugins: [
        //打包时生成一个配置文件
        new GenerateAssetPlugin({
        filename: serverConfig.json,
        fn: (compilation, cb) =&amp;gt; {
        cb(null, createJson());
        },
        }),
        ]&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;第四步 使用配置文件中的内容&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;这里根据不同项目不同需求代码自行变换，我分享一下我的项目里的使用。在main.js 中vue实例初始化之前将baseURL存到本地&lt;/p&gt;axios.get(serverConfig.json).then( e =&amp;gt; {
        let baseURL = e.data.ProdUrl
        localStorage.setItem(&quot;baseURL&quot;, baseURL);
        new Vue({
        el: #app,
        router,
        store,
        i18n,
        render: h =&amp;gt; h(App)
        })
        })&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;由于是使用axios获取，是异步方法，根据情况进行处理。、&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;好了接下来就再也不用为了域名每天build了&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;打包后的目录&lt;/p&gt;


        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Vue 编程技术&lt;/h3&gt;
        &lt;/div&gt;

    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:46:07 +0800</pubDate></item><item><title>zookeeper python接口实例详解</title><link>https://www.eolink.com/news/post/89097.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;zookeeper python接口实例详解&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;zookeeper python接口实例详解&quot;，用于解决相关问题。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文主要讲python支持zookeeper的接口库安装和使用。zk的python接口库有zkpython，还有kazoo，下面是zkpython，是基于zk的C库的python接口。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;zkpython安装&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;前提是zookeeper安装包已经在/usr/local/zookeeper下&lt;/p&gt;cd /usr/local/zookeeper/src/c
        ./configure
        make
        make install

        wget --no-check-certificate http://pypi.python.org/packages/source/z/zkpython/zkpython-0.4.tar.gz
        tar -zxvf zkpython-0.4.tar.gz
        cd zkpython-0.4
        sudo python setup.py install&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;zkpython应用&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;下面是网上一个zkpython的类，用的时候只要import进去就行&lt;/p&gt;
        vim zkclient.py#!/usr/bin/env python2.7
        # -*- coding: UTF-8 -*-

        import zookeeper, time, threading
        from collections import namedtuple

        DEFAULT_TIMEOUT = 30000
        VERBOSE = True

        ZOO_OPEN_ACL_UNSAFE = {&quot;perms&quot;:0x1f, &quot;scheme&quot;:&quot;world&quot;, &quot;id&quot; :&quot;anyone&quot;}

        # Mapping of connection state values to human strings.
        STATE_NAME_MAPPING = {zookeeper.ASSOCIATING_STATE: &quot;associating&quot;,zookeeper.AUTH_FAILED_STATE: &quot;auth-failed&quot;,zookeeper.CONNECTED_STATE: &quot;connected&quot;,zookeeper.CONNECTING_STATE: &quot;connecting&quot;,zookeeper.EXPIRED_SESSION_STATE: &quot;expired&quot;,
        }

        # Mapping of event type to human string.
        TYPE_NAME_MAPPING = {zookeeper.NOTWATCHING_EVENT: &quot;not-watching&quot;,zookeeper.SESSION_EVENT: &quot;session&quot;,zookeeper.CREATED_EVENT: &quot;created&quot;,zookeeper.DELETED_EVENT: &quot;deleted&quot;,zookeeper.CHANGED_EVENT: &quot;changed&quot;,zookeeper.CHILD_EVENT: &quot;child&quot;,
        }

        class ZKClientError(Exception):def __init__(self, value): self.value = valuedef __str__(self): return repr(self.value)

        class ClientEvent(namedtuple(&quot;ClientEvent&quot;, type, connection_state, path)):&quot;&quot;&quot;A client event is returned when a watch deferred fires. It denotessome event on the zookeeper client that the watch was requested on.&quot;&quot;&quot;
        @propertydef type_name(self): return TYPE_NAME_MAPPING[self.type]
        @propertydef state_name(self): return STATE_NAME_MAPPING[self.connection_state]
        def __repr__(self): return &quot;&amp;lt;ClientEvent %s at %r state: %s&amp;gt;&quot; % ( self.type_name, self.path, self.state_name)


        def watchmethod(func):def decorated(handle, atype, state, path): event = ClientEvent(atype, state, path) return func(event)return decorated

        class ZKClient(object):def __init__(self, servers, timeout=DEFAULT_TIMEOUT): self.timeout = timeout self.connected = False self.conn_cv = threading.Condition( ) self.handle = -1 self.conn_cv.acquire() if VERBOSE: print(&quot;Connecting to %s&quot; % (servers)) start = time.time() self.handle = zookeeper.init(servers, self.connection_watcher, timeout) self.conn_cv.wait(timeout/1000) self.conn_cv.release() if not self.connected: raise ZKClientError(&quot;Unable to connect to %s&quot; % (servers)) if VERBOSE: print(&quot;Connected in %d ms, handle is %d&quot; % (int((time.time() - start) * 1000), self.handle))
        def connection_watcher(self, h, type, state, path): self.handle = h self.conn_cv.acquire() self.connected = True self.conn_cv.notifyAll() self.conn_cv.release()
        def close(self): return zookeeper.close(self.handle)
        def create(self, path, data=&quot;&quot;, flags=0, acl=[ZOO_OPEN_ACL_UNSAFE]): start = time.time() result = zookeeper.create(self.handle, path, data, acl, flags) if VERBOSE: print(&quot;Node %s created in %d ms&quot; % (path, int((time.time() - start) * 1000))) return result
        def delete(self, path, version=-1): start = time.time() result = zookeeper.delete(self.handle, path, version) if VERBOSE: print(&quot;Node %s deleted in %d ms&quot; % (path, int((time.time() - start) * 1000))) return result
        def get(self, path, watcher=None): return zookeeper.get(self.handle, path, watcher)
        def exists(self, path, watcher=None): return zookeeper.exists(self.handle, path, watcher)
        def set(self, path, data=&quot;&quot;, version=-1): return zookeeper.set(self.handle, path, data, version)
        def set2(self, path, data=&quot;&quot;, version=-1): return zookeeper.set2(self.handle, path, data, version)

        def get_children(self, path, watcher=None): return zookeeper.get_children(self.handle, path, watcher)
        def async(self, path = &quot;/&quot;): return zookeeper.async(self.handle, path)
        def acreate(self, path, callback, data=&quot;&quot;, flags=0, acl=[ZOO_OPEN_ACL_UNSAFE]): result = zookeeper.acreate(self.handle, path, data, acl, flags, callback) return result
        def adelete(self, path, callback, version=-1): return zookeeper.adelete(self.handle, path, version, callback)
        def aget(self, path, callback, watcher=None): return zookeeper.aget(self.handle, path, watcher, callback)
        def aexists(self, path, callback, watcher=None): return zookeeper.aexists(self.handle, path, watcher, callback)
        def aset(self, path, callback, data=&quot;&quot;, version=-1): return zookeeper.aset(self.handle, path, data, version, callback)

        watch_count = 0

        &quot;&quot;&quot;Callable watcher that counts the number of notifications&quot;&quot;&quot;
        class CountingWatcher(object):def __init__(self): self.count = 0 global watch_count self.id = watch_count watch_count += 1
        def waitForExpected(self, count, maxwait): &quot;&quot;&quot;Wait up to maxwait for the specified count, return the count whether or not maxwait reached. Arguments: - `count`: expected count - `maxwait`: max milliseconds to wait &quot;&quot;&quot; waited = 0 while (waited &amp;lt; maxwait): if self.count &amp;gt;= count: return self.count time.sleep(1.0); waited += 1000 return self.count
        def __call__(self, handle, typ, state, path): self.count += 1 if VERBOSE: print(&quot;handle %d got watch for %s in watcher %d, count %d&quot; % (handle, path, self.id, self.count))

        &quot;&quot;&quot;Callable watcher that counts the number of notifications
        and verifies that the paths are sequential&quot;&quot;&quot;
        class SequentialCountingWatcher(CountingWatcher):def __init__(self, child_path): CountingWatcher.__init__(self) self.child_path = child_path
        def __call__(self, handle, typ, state, path): if not self.child_path(self.count) == path: raise ZKClientError(&quot;handle %d invalid path order %s&quot; % (handle, path)) CountingWatcher.__call__(self, handle, typ, state, path)

        class Callback(object):def __init__(self): self.cv = threading.Condition() self.callback_flag = False self.rc = -1
        def callback(self, handle, rc, handler): self.cv.acquire() self.callback_flag = True self.handle = handle self.rc = rc handler() self.cv.notify() self.cv.release()
        def waitForSuccess(self): while not self.callback_flag: self.cv.wait() self.cv.release() if not self.callback_flag == True: raise ZKClientError(&quot;asynchronous operation timed out on handle %d&quot; % (self.handle)) if not self.rc == zookeeper.OK: raise ZKClientError( &quot;asynchronous operation failed on handle %d with rc %d&quot; % (self.handle, self.rc))


        class GetCallback(Callback):def __init__(self): Callback.__init__(self)
        def __call__(self, handle, rc, value, stat): def handler(): self.value = value self.stat = stat self.callback(handle, rc, handler)

        class SetCallback(Callback):def __init__(self): Callback.__init__(self)
        def __call__(self, handle, rc, stat): def handler(): self.stat = stat self.callback(handle, rc, handler)

        class ExistsCallback(SetCallback):pass

        class CreateCallback(Callback):def __init__(self): Callback.__init__(self)
        def __call__(self, handle, rc, path): def handler(): self.path = path self.callback(handle, rc, handler)

        class DeleteCallback(Callback):def __init__(self): Callback.__init__(self)
        def __call__(self, handle, rc): def handler(): pass self.callback(handle, rc, handler)&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;总结&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;以上就是本文关于zookeeper python接口实例详解的全部内容，希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题，如有不足之处，欢迎留言指出。感谢朋友们对本站的支持！&lt;/p&gt;


        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Python编程技术&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;python使用logging模块发送邮件代码示例&quot;，用于解决相关问题。logging模块不只是能记录log，还能发送邮件，使用起来非常简单方便#coding=utf-8 ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:35:05 +0800</pubDate></item><item><title>Iterator与LIstIterator接口在java中的区别有哪些</title><link>https://www.eolink.com/news/post/89096.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Iterator与LIstIterator接口在java中的区别有哪些&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;Iterator与LIstIterator接口在java中的区别有哪些&quot;，希望能够解决相关问题。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;java&amp;nbsp; Iterator接口和LIstIterator接口分析&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;目录&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1.Iterator接口&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2.ListIterator&lt;/p&gt;3.Iterator和ListIterator的区别&amp;nbsp;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;正文&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;在继续看ArrayList源码之前，先了解Iterator接口和ListIterator接口，下篇文章详细讲解ArrayList是如何实现它们的。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;我们知道，接口只是一种规范，当继承接口并实现其中的方法时，要遵循接口对方法的说明。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;1.Iterator接口&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Iterator接口取代了Java集合框架中的Enumeratrion。Iterators不同于enumerations的地方主要有两点：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Iterators允许调用者在迭代过程中从集合里移除元素；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　方法名得到了改善。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;Iterator源码如下：&lt;/strong&gt;&lt;/p&gt;/**
        * An iterator over a collection. {@code Iterator} takes the place of
        * {@link Enumeration} in the Java Collections Framework. Iterators
        * differ from enumerations in two ways:
        * Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
        * Method names have been improved.
        * This interface is a member of the Java Collections Framework.
        * @param &amp;lt;E&amp;gt; the type of elements returned by this iterator*/
        public interface Iterator&amp;lt;E&amp;gt; {
        /**
        * Returns {@code true} if the iteration has more elements.
        * (In other words, returns {@code true} if {@link #next} would
        * return an element rather than throwing an exception.)
        * @return {@code true} if the iteration has more elements
        */
        boolean hasNext();

        /**
        * Returns the next element in the iteration.
        * @return the next element in the iteration
        * @throws NoSuchElementException if the iteration has no more elements
        */
        E next();

        /**
        * Removes from the underlying collection the last element returned
        * by this iterator (optional operation). This method can be called
        * only once per call to {@link #next}. The behavior of an iterator
        * is unspecified if the underlying collection is modified while the
        * iteration is in progress in any way other than by calling this
        * method.
        *
        * @implSpec
        * The default implementation throws an instance of
        * {@link UnsupportedOperationException} and performs no other action.
        *
        * @throws UnsupportedOperationException if the {@code remove}
        * operation is not supported by this iterator
        *
        * @throws IllegalStateException if the {@code next} method has not
        * yet been called, or the {@code remove} method has already
        * been called after the last call to the {@code next}
        * method
        */
        default void remove() {
        throw new UnsupportedOperationException(&quot;remove&quot;);
        }

        /**
        * Performs the given action for each remaining element until all elements
        * have been processed or the action throws an exception. Actions are
        * performed in the order of iteration, if that order is specified.
        * Exceptions thrown by the action are relayed to the caller.
        *
        * @implSpec
        * &amp;lt;p&amp;gt;The default implementation behaves as if:
        * &amp;lt;pre&amp;gt;{@code
        * while (hasNext())
        * action.accept(next());
        * }&amp;lt;/pre&amp;gt;
        *
        * @param action The action to be performed for each element
        * @throws NullPointerException if the specified action is null
        * @since 1.8
        */
        default void forEachRemaining(Consumer&amp;lt;&amp;amp;#63; super E&amp;gt; action) {
        Objects.requireNonNull(action);
        while (hasNext())
        action.accept(next());
        }
        }&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Iterator接口定义了四个方法以及各个方法的功能，如果有类实现了这个接口，且实现了这些方法，这方法需要实现定义的功能，遵循这些规则：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　1).hasNext() 判断容器是否有下一个元素，有则返回true；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　2).next() 返回容器中的下一个元素；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3).remove() 移除当前迭代器返回的最后一个元素。这个方法在每次调用next()方法之后只能调用一次；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　4).Java 8 增加forEachRemaining方法，它可以实现对余下的所有元素执行指定的操作。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;更详细的说明请阅读源码中的注释。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;2.ListIterator&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;ListIterator在Iterator基础上提供了add、set、previous等对列表的操作。但是ListIterator跟Iterator一样，仍是在原列表上进行操作。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;ListIterator源码如下：&lt;/strong&gt;&lt;/p&gt;/**
        * An iterator for lists that allows the programmer
        * to traverse the list in either direction, modify
        * the list during iteration, and obtain the iterators
        * current position in the list. A {@code ListIterator}
        * has no current element; its &amp;lt;I&amp;gt;cursor position&amp;lt;/I&amp;gt; always
        * lies between the element that would be returned by a call
        * to {@code previous()} and the element that would be
        * returned by a call to {@code next()}.
        * An iterator for a list of length {@code n} has {@code n+1} possible
        * cursor positions, as illustrated by the carets ({@code ^}) below:
        * &amp;lt;PRE&amp;gt;
        * Element(0) Element(1) Element(2) ... Element(n-1)
        * cursor positions: ^ ^ ^ ^ ^
        * &amp;lt;/PRE&amp;gt;
        * Note that the {@link #remove} and {@link #set(Object)} methods are
        * &amp;lt;i&amp;gt;not&amp;lt;/i&amp;gt; defined in terms of the cursor position; they are defined to
        * operate on the last element returned by a call to {@link #next} or
        * {@link #previous()}.
        *
        * This interface is a member of the Java Collections Framework.*/
        public interface ListIterator&amp;lt;E&amp;gt; extends Iterator&amp;lt;E&amp;gt; {
        // Query Operations

        /**
        * Returns {@code true} if this list iterator has more elements when
        * traversing the list in the forward direction. (In other words,
        * returns {@code true} if {@link #next} would return an element rather
        * than throwing an exception.)
        *
        * @return {@code true} if the list iterator has more elements when
        * traversing the list in the forward direction
        */
        boolean hasNext();

        /**
        * Returns the next element in the list and advances the cursor position.
        * This method may be called repeatedly to iterate through the list,
        * or intermixed with calls to {@link #previous} to go back and forth.
        * (Note that alternating calls to {@code next} and {@code previous}
        * will return the same element repeatedly.)
        *
        * @return the next element in the list
        * @throws NoSuchElementException if the iteration has no next element
        */
        E next();

        /**
        * Returns {@code true} if this list iterator has more elements when
        * traversing the list in the reverse direction. (In other words,
        * returns {@code true} if {@link #previous} would return an element
        * rather than throwing an exception.)
        *
        * @return {@code true} if the list iterator has more elements when
        * traversing the list in the reverse direction
        */
        boolean hasPrevious();

        /**
        * Returns the previous element in the list and moves the cursor
        * position backwards. This method may be called repeatedly to
        * iterate through the list backwards, or intermixed with calls to
        * {@link #next} to go back and forth. (Note that alternating calls
        * to {@code next} and {@code previous} will return the same
        * element repeatedly.)
        *
        * @return the previous element in the list
        * @throws NoSuchElementException if the iteration has no previous
        * element
        */
        E previous();

        /**
        * Returns the index of the element that would be returned by a
        * subsequent call to {@link #next}. (Returns list size if the list
        * iterator is at the end of the list.)
        *
        * @return the index of the element that would be returned by a
        * subsequent call to {@code next}, or list size if the list
        * iterator is at the end of the list
        */
        int nextIndex();

        /**
        * Returns the index of the element that would be returned by a
        * subsequent call to {@link #previous}. (Returns -1 if the list
        * iterator is at the beginning of the list.)
        *
        * @return the index of the element that would be returned by a
        * subsequent call to {@code previous}, or -1 if the list
        * iterator is at the beginning of the list
        */
        int previousIndex();


        // Modification Operations

        /**
        * Removes from the list the last element that was returned by {@link
        * #next} or {@link #previous} (optional operation). This call can
        * only be made once per call to {@code next} or {@code previous}.
        * It can be made only if {@link #add} has not been
        * called after the last call to {@code next} or {@code previous}.
        *
        * @throws UnsupportedOperationException if the {@code remove}
        * operation is not supported by this list iterator
        * @throws IllegalStateException if neither {@code next} nor
        * {@code previous} have been called, or {@code remove} or
        * {@code add} have been called after the last call to
        * {@code next} or {@code previous}
        */
        void remove();

        /**
        * Replaces the last element returned by {@link #next} or
        * {@link #previous} with the specified element (optional operation).
        * This call can be made only if neither {@link #remove} nor {@link
        * #add} have been called after the last call to {@code next} or
        * {@code previous}.
        *
        * @param e the element with which to replace the last element returned by
        * {@code next} or {@code previous}
        * @throws UnsupportedOperationException if the {@code set} operation
        * is not supported by this list iterator
        * @throws ClassCastException if the class of the specified element
        * prevents it from being added to this list
        * @throws IllegalArgumentException if some aspect of the specified
        * element prevents it from being added to this list
        * @throws IllegalStateException if neither {@code next} nor
        * {@code previous} have been called, or {@code remove} or
        * {@code add} have been called after the last call to
        * {@code next} or {@code previous}
        */
        void set(E e);

        /**
        * Inserts the specified element into the list (optional operation).
        * The element is inserted immediately before the element that
        * would be returned by {@link #next}, if any, and after the element
        * that would be returned by {@link #previous}, if any. (If the
        * list contains no elements, the new element becomes the sole element
        * on the list.) The new element is inserted before the implicit
        * cursor: a subsequent call to {@code next} would be unaffected, and a
        * subsequent call to {@code previous} would return the new element.
        * (This call increases by one the value that would be returned by a
        * call to {@code nextIndex} or {@code previousIndex}.)
        *
        * @param e the element to insert
        * @throws UnsupportedOperationException if the {@code add} method is
        * not supported by this list iterator
        * @throws ClassCastException if the class of the specified element
        * prevents it from being added to this list
        * @throws IllegalArgumentException if some aspect of this element
        * prevents it from being added to this list
        */
        void add(E e);
        }&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;ListIterator的功能更加强大，定义的方法有：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1).hasNext() 向前遍历时，如果有下一个元素返回真；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　2).next() 返回下一个元素的值，并将指针加1；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　3).hasPrevious() 向相反方向遍历时，如果还有元素返回真；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　4).previous() 返回上一个元素的值，并将指针前移1；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;6).previousIndex() 返回此时调用previous()方法时返回的元素的索引；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　7).remove() 移除最近一次调用next()或previous()方法返回的元素（可选）；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;8).set(E e) 用元素e将如果此时调用next()或previous()方法返回的元素替换掉；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;9).add(E e) 添加元素到此时调用next()返回的元素之前，或此时调用previous()返回的元素之后。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;更详细的说明请阅读源码中的注释。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;3.Iterator和ListIterator的区别&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&amp;nbsp; Iterator和ListIterator的方法对比如下表：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Iterator&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;ListIterator&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;hasNext()&lt;/p&gt;hasNext()覆盖&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;next()&lt;/p&gt;next()覆盖&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;remove()&lt;/p&gt;remove()覆盖&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;forEachRemaining(Consumer&amp;lt;&amp;amp;#63; super E&amp;gt;&amp;nbsp;action)&lt;/p&gt;forEachRemaining(Consumer&amp;lt;&amp;amp;#63; super E&amp;gt;&amp;nbsp;action)继承hasPrevious()previous()nextIndex()previousIndex()set(E e)add(E e)&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;二者的不同之处主要有：&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　1).Iterator只能单向移动，ListIterator可以双向移动；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;　　2).ListIterator可以删除、替换或添加元素，而Iterator只能删除元素；&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3).ListIterator可以返回当前（调用next()或previous()返回的）元素的索引，而Iterator不能。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;关于 &quot;Iterator与LIstIterator接口在java中的区别有哪&lt;/p&gt;

        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Java编程技术&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;java 中RandomAccess接口源码分析&quot;，希望能够解决相关问题。java 中RandomAccess接口源码分析RandomAccess是一个接口，位于java.util ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:29:36 +0800</pubDate></item><item><title>c#自定义Attribute获取接口实现示例代码</title><link>https://www.eolink.com/news/post/89095.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;c#自定义Attribute获取接口实现示例代码&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;c#自定义Attribute获取接口实现示例代码&quot;，用于解决相关问题。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;一般的接口实现多态&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;定义接口&lt;/p&gt;interface Ipeople{void say();}&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;定义实现的类&lt;/p&gt;public class man : Ipeople{public void say(){ MessageBox.Show(&quot;man&quot;);}}
        public class woman : Ipeople{public void say(){ MessageBox.Show(&quot;woman&quot;);}}&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;一般实现的方法&lt;/p&gt;

        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;升级版&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;添加自定义（这个网上好多）&lt;/p&gt;

        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;实现类&lt;/p&gt;

        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;调用方法&lt;/p&gt;private static void NewMethod(string tpye){ Ipeople ib = null; var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a =&amp;gt; a.GetTypes().Where(t =&amp;gt; t.GetInterfaces().Contains(typeof(Ipeople)))) .ToArray(); foreach (var v in types) { var attribute = v.GetCustomAttributes(typeof(NameAttribute), false).FirstOrDefault(); if (attribute != null &amp;amp;&amp;amp; ((NameAttribute)attribute).Name == tpye) { ib = (Ipeople)v.Assembly.CreateInstance(v.FullName); break; } } if (ib != null) ib.say();}&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;这个可以避免需要维护swich语句&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;总结&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;以上就是这篇文章的全部内容了，希望本文的内容对大家的学习或者工作具有一定的参考学习价值，谢谢大家对亿速云的支持。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;关于 &quot;c#自定义Attribute获取接口实现示例代码&quot; 就介绍到此。希望多多支持&lt;/p&gt;

        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;编程技术 和 程序设计&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;C# 实现PPT 每一页转成图片过程解析&quot;，用于解决相关问题。要实现PPT转图片，首先需要引用两个DLL。我这里用的这个这个版本Microsoft.Office.Interop.Power ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:24:18 +0800</pubDate></item><item><title>hdml指的是什么接口</title><link>https://www.eolink.com/news/post/89093.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;hdml指的是什么接口&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文主要介绍&quot;hdml指的是什么接口&quot;，希望能够解决您遇到有关问题，下面我们一起来看这篇 &quot;hdml指的是什么接口&quot; 文章。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;hdml全称High Definition Multimedia Interface，中文意思为高清多媒体接口，是一种全数字化视频和声音发送接口，可以发送未压缩的音频及视频信号。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;高清多媒体接口（High Definition Multimedia Interface，HDMI ）是一种全数字化视频和声音发送接口，可以发送未压缩的音频及视频信号。HDMI可用于机顶盒、DVD播放机、个人计算机、电视、游戏主机、综合扩大机、数字音响与电视机等设备。HDMI可以同时发送音频和视频信号，由于音频和视频信号采用同一条线材，大大简化系统线路的安装难度。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;HDMI是被设计来取代较旧的模拟信号影音发送接口如SCART或RCA等端子的。它支持各类电视与计算机视频格式，包括SDTV、HDTV视频画面，再加上多声道数字音频。HDMI与去掉音频传输功能的UDI都继承DVI的核心技术“传输最小化差分信号”TMDS，从本质上来说仍然是DVI的扩展。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;HDMI也支持非压缩的8声道数字音频发送（采样率192kHz，数据长度24bits/sample），以及任何压缩音频流如Dolby Digital或DTS，亦支持SACD所使用的8声道的1bit DSD信号。在HDMI 1.3规格中，又追加超高数据量的非压缩音频流如Dolby TrueHD与DTS-HD的支持。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;HDMI组织的发起者包括各大消费电子产品制造商，如日立制作所、松下电器、Quasar、飞利浦、索尼、汤姆生RCA、东芝、Silicon Image。数字内容保护公司（Digital Content Protection, LLC）提供HDMI接口相关的防拷保护技术。此外，HDMI也受到各主要电影制作公司如20世纪福斯、华纳兄弟、迪士尼，包括三星电子在内的各大消费电子产品制造商，以及多家有线电视系统业者的支持。&lt;/p&gt;


        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;编程技术 和 程序设计&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文主要介绍&quot;potato指的是什么软件&quot;，希望能够解决您遇到有关问题，下面我们一起来看这篇 &quot;potato指的是什么软件&quot; 文章。Potato是一款即时通讯软件，用户可通过安卓、iOS、linux、macos、 ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:13:12 +0800</pubDate></item><item><title>分析EBS常用接口表</title><link>https://www.eolink.com/news/post/89092.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;分析EBS常用接口表&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;分析EBS常用接口表&quot;，希望能够解决您遇到的有关问题，下面我们来看这篇 &quot;分析EBS常用接口表&quot; 文章。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;AP接口表：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;AP_INVOICES_INTERFACE&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;AP_INVOICE_LINES_INTERFACE&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及的请求：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;应付款管理系统开放接口导入&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及案例： 运费导AP、费用导AP&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;PO接口表：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;申请：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;PO_REQUISITIONS_INTERFACE_ALL&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及请求：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;导入申请&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;采购：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;po_headers_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;po_lines_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;po_distributions_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及的请求：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;Import Standard Purchase Orders&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;接收：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;rcv_headers_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;rcv_transactions_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;mtl_transaction_lots_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及请求：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;接收事务处理处理器&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及案例：运费导采购、MRP导申请、POP导申请&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;GL接口表：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及案例：ADI导日记账、返利导日记账&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;FA接口表：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;fa_mass_additions&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;FA API：&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;增加fa_addition_pub.do_addition&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;修改：fa_adjustment_pub.do_adjustment&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&amp;nbsp;&amp;nbsp; fa_asset_desc_pub.update_desc&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;涉及案例：电子资产清理&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;库存事务接口：mtl_transactions_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）一般用来做各类杂收发、Cost Update，对于和业务有关的事务一般不建议使用，比如SO发货，如果自己发会导致Workflow没有往下走&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）成功导入之后运行Cost Manager生成会计分录&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）
            平均成本更新也通过此接口；如果该Item没有交易，则成本数据不会进入cst_item_costs&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;固定资产接口：fa_mass_additions&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）fa_mass_additions这个表有几个Trigger需要注意；会自动去插其他表，删除的时候也是&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）折旧方法接口表无法给，而是自动从Category继承下来，所以导入之后需要Update表&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）不是通过AP引过来的FA，是没有Source Lines信息的；如果需要，可以通过插表来实现&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）数据进接口之后从Navigator:Mass Additions/Post Mass Additions提交请求集，这样会有个报表显示导入结果。不过我的测试程序可以直接提交请求集。&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;总账分录接口：gl_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）最简单的接口，不说了&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;应付发票接口：ap_invoices_interface/ap_invoice_lines_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）Profile AP: Use Invoice Batch Controls定义是否使用批控制&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）仅支持CREDIT/STANDARD；注意金额正负，小于零用CREDIT，大于零用STANDARD&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）PREPAYMENT/DEBIT/EXPENSE REPORT/MIXED不支持，先用CREDIT或者STANDARD，进去之后再Update正式表ap_invoices_all&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）导入之后可再调用请求Invoice Validation自动Validate发票&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;应收发票接口：ra_interface_lines_all/ra_interface_salescredits_all&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）几个接口表之间的关系和其他接口不同，不是通过ID关联，而是通过描述性
            弹性域Line Transaction Flexfield定义&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）接口给ID还是Name，要根据Transaction Source上的定义，不能随便给&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）ra_interface_distributions_all这个表可以不插，让系统自动生成分配行&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）如果没有销售员，可以提供一条ID=-3的No Sales Person记录给接口。这个要看AR System Option Miscellaneous上的设置是否要求销售员&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;应收收据接口：ar_interim_cash_receipts_all&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）AR Receipt标准接口是Lockbox，需要预先定义Format；Oracle根据Format定义把接口数据写到ar_interim_cash_receipts_all；我们可以跳过第一步，直接把数据插入到ar_interim_cash_receipts_all，不过Batch需要我们直接插表&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）在Batch界面查看：数据在ar_interim_cash_receipts_all的Batch Type为 Mannual Quick&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）Batch的Currency取本位币即可，收据用需要的货币&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;客户导入接口：ra_customers_interface_all/ra_customer_profiles_int_all/ra_contact_phones_int_all&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）要导Customer，ra_customer_profiles_int_all需要有记录&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）orig_system_party_ref相同的话，Customer_Number不同，可以在一个Party下建多个Customer&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）ship to的bill_to_orig_address_ref可用bill to的orig_system_address_ref，这样可以自动关联&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）需要打Patch 3606744和3558213，否则Statement和Dunning类型的Site Use导不进去&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;5）不是所以字段都可以从Interface进去；以HZ_Cust_Site_Uses_all为例，导入之后需要直接Update如下比较重要的字段：payment_term_id、order_type_id、warehouse_id、territory_id、primary_salesrep_id&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;6）更新HZ_Cust_Site_Uses_all的Primary_flag的时候注意同时更新hz_cust_acct_sites_all的bill_to_flag和ship_to_flag为P（Primary）或者Y&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;销售订单接口：oe_headers_iface_all/oe_lines_iface_all/oe_actions_iface_all&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）整张Close的订单可以通过接口表；Close的订单，Oracle几乎是直接插表；其他的要做很多验证&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）部分行Close的订单，可以给行Assign一个仅负责Close（Enter/Fulfill/Close/End）的工作流，这样Workflow Back Ground Process起来之后就会Close&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）非Close的订单行号不能重复，所以接口表我们给空；如果有需要待导入后Update Line表即可&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）数量正负要与Line Type的类型一致，正的对Order，负的对Return，否则接口报Inventory Item错误&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;5）订单号更新需要更新几个表：oe_order_headers_all/wsh_delivery_details/mtl_sales_orders&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;6）订单行在收货或者发货不足的情况下会拆行，拆行的时候系统几乎是拷贝所有的字段，如果碰到Unique的字段会失败。我碰到的问题是把源系统的line_id记录在弹性域上，并给这个弹性域建了Unique索引，导致Dropship的订单采购部分收货老是报错&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;采购订单接口：po_headers_interface/po_lines_interface/po_distributions_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）PO接口有问题可察看错误信息表po_interface_errors，可以解决大部分问题&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）本位币导入之后，头上的Rate Date为空，需要Update表&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）quantity_billed也可以事后更新，这样AP不会再Match过来&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）审批记录可以直接插入表po_action_history&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;5）注意采购的Valdiate ORG&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;6）如果Item没有Assign给Ship_to_org，会报No data found错误&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;采购接收接口：rcv_shipment_headers/rcv_transactions_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）收据头直接写表；收据行和收货事务通过接口&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）注意parent_transaction_id，Receive需要放空&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）PO接口有问题可察看错误信息表po_interface_errors，可以解决大部分问题&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）如果要再现原来的Receiving Transaction，可按如下顺序分批进入接口RECEIVE、TRANSFER、ACCEPT、REJECT、DELIVER、RETURN TO RECEIVING、RETURN TO VENDOR、CORRECT&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;库存项目接口：mtl_system_items_interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;1）在Master Org新增Item比较简单，给足需要的字段即可&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;2）在其他组织增加Item（相当于从Master Assign后再Update），需要注意Master Org Conctrol的字段需要保持主组织的值（比较多，看mtl_item_attributes的Conctrol_level = 1）&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;3）在其他组织增加Item还需要注意一些字段需要保持主组织的值，否则接口会报错，它们是create_supply_flag、dual_uom_control、buyer_id、allowed_units_lookup_code、purchasing_item_flag、internal_order_flag、inventory_item_flag&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;4）如果要给Item Assign Category，可以通过mtl_item_categories_interface，对应的请求是Item Category Assignment Open Interface&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;EBS中的几个接口表&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;select * from RCV_TRANSACTIONS_INTERFACE--待定接收事务处理&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;select * from MTL_TRANSACTIONS_INTERFACE--待定物料事务处理&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;select * from WIP_MOVE_TXN_INTERFACE--待定移动事务处理&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;select * from MTL_MATERIAL_TRANSACTIONS_TEMP--未处理的物料事务处理&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;select * from MTL_MATERIAL_TRANSACTIONS--未计算成本的物料事务处理&lt;/p&gt;select * from WIP_COST_TXN_INTERFACE--待定WIP成本计算事务处理


        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;编程技术 和 程序设计&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;本文讲解&quot;EBS AR模块常用表分析&quot;，希望能够解决您遇到的有关问题，下面我们来看这篇 &quot;EBS AR模块常用表分析&quot; 文章。AR 模块常用表应收事务处理相关表SELECT * FROM&amp;nbsp;ar.ar_batche ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:07:40 +0800</pubDate></item><item><title>java 单机接口限流处理方案</title><link>https://www.eolink.com/news/post/89091.html</link><description>&lt;p&gt;
    &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
        &lt;h1 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;java 单机接口限流处理方案&lt;/h1&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;&lt;strong style=&quot;color: blue;&quot;&gt;对单机服务做接口限流的处理方案&lt;/strong&gt;&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;设定某个接口一定时间只接受固定次数的请求，比如 /add 接口1秒最多接收100次请求，多的直接拒绝，直接上代码：&lt;/p&gt;/**
        * 单机限流
        */
        @Slf4j
        public class FlowLimit {

        //接口限流上限值和限流时间缓存
        private static Cache&amp;lt;String, AtomicLong&amp;gt; localCache = CacheBuilder.newBuilder().maximumSize(100)
        .expireAfterWrite(1000, TimeUnit.MILLISECONDS).build();

        //每个接口的上限缓存
        private static Map&amp;lt;String, Long&amp;gt; maxFlowLimitMap = new ConcurrentHashMap&amp;lt;&amp;gt;();

        private static final FlowLimit instance = new FlowLimit();

        //这块的目的是初始化每个接口的上限，下面的变量：apiFlowLimitConfigure
        //实际使用的时候应该是从db或者其他地方获取设置的每个接口的限流上限值，
        //这样可以动态的调整接口上限，比如直接修改db，不用发布，就可以调整接口限流值
        static {
        new ScheduledThreadPoolExecutor(1, runnable -&amp;gt; {
        Thread thread = new Thread(runnable, &quot;api-flowLimit-configure&quot;);
        // thread.setDaemon(true);
        return thread;
        }).scheduleAtFixedRate(() -&amp;gt; {
        try {
        String apiFlowLimitConfigure = &quot;{\&quot;doAdd\&quot;:100}&quot;; //表示/doAdd接口1秒接受100次请求
        Map mapObj = JSONObject.parseObject(apiFlowLimitConfigure, Map.class);
        if(mapObj != null){
        mapObj.forEach((key, value) -&amp;gt; {
        if(value != null){
        instance.setMaxFlowLimit(key.toString(), new Long(value.toString()));
        }else{
        log.warn(key + &quot; - 设置接口限流发现限流值为空，设置默认值&quot;);
        instance.setMaxFlowLimit(key.toString(), 100L);
        }
        });
        }
        } catch (Exception e) {
        log.error(&quot;设置接口限流出现异常{}&quot;, e);
        }
        }, 0, 3, TimeUnit.SECONDS);
        }

        public static FlowLimit getInstance() {
        return instance;
        }

        private FlowLimit setMaxFlowLimit(String key, Long maxFlowLimit) {
        maxFlowLimitMap.put(key, maxFlowLimit);
        return this;
        }

        public Boolean isAvailable(String key) {
        return checkAvailable(key, 1L);
        }

        public Boolean isAvailable(String key, Long incrNum) {
        return checkAvailable(key, incrNum);
        }

        private Boolean checkAvailable(String key, Long incrNum){
        Long maxFlowLimit = maxFlowLimitMap.get(key);
        if (null == maxFlowLimit || maxFlowLimit == 0) {
        return true;
        }
        if (incrAndGet(key, incrNum) &amp;lt;= maxFlowLimit.longValue()) {
        return true;
        } else {
        return false;
        }
        }

        private long incrAndGet(String key, final long n) {
        try {
        return localCache.get(key, new Callable&amp;lt;AtomicLong&amp;gt;() {
        @Override
        public AtomicLong call() throws Exception {
        return new AtomicLong(0);
        }
        }).addAndGet(n);
        } catch (Exception e) {
        log.error(e.getMessage(), e);
        }
        return 0;
        }

        public long get(String key) {
        return incrAndGet(key, 0);
        }

        }&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;上面这个就是单机限流逻辑，代码不难，感觉没必要使用ConcurrentHashMap，不过感觉无所谓了&lt;/p&gt;这段代码只需要加在需要限流的接口前面：@GetMapping(&quot;doAdd&quot;)
        public Boolean doAdd(){
        FlowLimit instance = FlowLimit.getInstance(); //单例获取
        //查看当前的/doAdd接口是否触发了限流
        Boolean flowLimitFlag = instance.isAvailable(&quot;doAdd&quot;);
        if(!flowLimitFlag){
        log.warn(&quot;触发限流，拒绝请求&quot;);
        return false;
        }
        //doAdd()
        return true;
        }&lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;调用实例如上&lt;/p&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;上面这个限流其实是有一定问题的：比如你限定10秒钟1000次，在第9.9秒的时候，突然进来1000个请求，然后第10.1秒的时候，攻击者，又进来1000次请求，这样，0.2秒之内，进来2000次请求。。。&lt;/p&gt;所以这个时候就需要令牌桶或者其他算法了，其他算法后面再写
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;没怎么仔细测试，有问题欢迎提出，共同学习&lt;/p&gt;


        &lt;div style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;
            &lt;h3 style=&quot;text-align: left; margin-bottom: 10px;&quot;&gt;Java编程技术&lt;/h3&gt;
        &lt;/div&gt;
        &lt;p style=&quot;font-size: 18px; line-height: 40px; text-align: left; margin-bottom: 30px;&quot;&gt;最近写了一个秒杀的功能模块，为了保证高并发情况下不会宕机，要从多方面去考虑，当前的限流操作只是其中的一个方面，具体操作如下。导入所需依赖&amp;lt;properties&amp;gt; &amp;lt;project. ...&lt;/p&gt;
    &lt;/div&gt;




&lt;/p&gt;</description><pubDate>Sun, 04 Feb 2024 12:02:09 +0800</pubDate></item></channel></rss>