精华内容
下载资源
问答
  • 多线程的实现和使用场景

    万次阅读 2021-06-09 22:06:20
    多线程的实现和使用场景一、多线程实现方式1.1 Thread实现1.2 Runnable实现二、多线程的使用场景1.多线程使用场景1.1 多线程应该最多的场景:1.2多线程的常见应用场景:2.多线程小案列2.1 多线程计算2.2 多线程实现...

    一、多线程实现方式

    1.1 Thread实现

    继承Thread类并重写它的run方法。之后创建这个子类的对象并调用start()方法。下面直接上代码:

    /**
    *描述
    * @author cy
    * @date 2021-06-09
    * @return
    **/
    public class TreadTest  extends  Thread{
        public static void main(String[] args) {
            //创建两个线程
            TreadTest thread1 = new TreadTest();
            TreadTest thread2 = new TreadTest();
            thread1.start();
            thread2.start();
        }
        @Override
        public void run() {
           for (int i = 0;i < 100;i++){
               //分别打印线程名称和i
               System.out.println("threadName:"
               +Thread.currentThread()+";i="+i);
           }
        }
    }
    

    输出结果可以看到两个线程交替打印。线程启动成功。
    在这里插入图片描述

    1.2 Runnable实现

    Runnable的实现方式是实现其接口,下面请看具体的实现代码

    
    /**
     * @author  cy
     * @date  2021-06-09
     *@deprecated  Runnable实现多线程
     */
    public class RunnableDemoTest {
    
        public static void main(String[] args) {
            //新建两个线程
            RunnableDemoTest1 r =  
            new RunnableDemoTest1();
            new Thread(r).start();
            new  Thread(r).start();
        }
    
        /**
         * 通过runnable 方式实现多线程
          */
    static class  RunnableDemoTest1  
                       implements  Runnable{
        @Override
        public void run() {
            for (int i = 0 ;i < 5 ;i++)
                System.out.println("threadName:"
                +Thread.currentThread()+";i="+i);
        }
    }
    }
    
    

    从输出结果中我们可以看到两个线程交替打印。线程启动成功。
    在这里插入图片描述

    二、多线程的使用场景

    1.多线程使用场景

    1.1 多线程应该最多的场景:

    web服务器本身; 各种专用服务器(如游戏服务器);

    1.2多线程的常见应用场景:

    1、后台任务,例如:定时向大量(100w以上)的用户发送邮件; 2、异步处理,例如:发微博、记录日志等; 3、分布式计算

    2.多线程小案列

    2.1 多线程计算

    计算一亿个数字之和,在没有学习多线程之前,也是可以实现的,我们可以通过循环一亿次进行累加,最后得出结果。
    代码如下:

    package trhead;
    
    import java.util.Random;
    
    /**
     * 计算一亿个数之和
     */
    public class SumThreadDemo {
    
        private static double [] nums = new double[1_0000_0000];
        private static Random r  =  new Random();
        private static  double  result = 0.0,result1 = 0.0,result2 = 0.0;
    
        static {
            for (int i =0;i < nums.length ; i++){
                nums[i] = r.nextDouble();
            }
        }
    
        public static void main(String[] args) throws InterruptedException {
            SumThreadDemo.m1();
            SumThreadDemo.m2();
        }
    
        /**
         * 使用单线程计算
         */
        private  static  void m1(){
            long startTime = System.currentTimeMillis();
            for (int i = 0;i < nums.length;i++){
                result += nums[i];
            }
            System.out.println(result);
            long endTime = System.currentTimeMillis();
            long countTime = endTime - startTime;
            System.out.println("m1耗时:"+countTime);
        }
    
        /**
         * 使用多线程计算
         */
        private  static  void m2() throws InterruptedException {
    
    
            Thread thread1 =   new Thread(()->{
                for (int i = 0;i < nums.length/2;i++){
                    result1 += nums[i];
                }
            });
    
            Thread thread2 =   new Thread(()->{
                for (int i = nums.length/2;i < nums.length;i++){
                    result2 += nums[i];
                }
            });
            long startTime = System.currentTimeMillis();
            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            System.out.println(result1+ result2);
            long endTime = System.currentTimeMillis();
            long countTime = endTime - startTime;
            System.out.println("m2耗时:"+countTime);
        }
    
    
    
    }
    
    

    从输出结果中可以观察出,两个线程计算结果比单个线程快了将近两倍。如果实际应用中有这种场景,大家可以使用多线程实现。
    在这里插入图片描述

    2.2 多线程实现卖票小程序

    某电影院正在上映某大片,共5张票,而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。

    多线程实现方式1:

    package trhead;
    
    /**
    *描述
     *  某电影院正在上映某大片,共5张票,
     * 而他又有3个售票窗口售票,请设计一个程序模拟该电影院售票。
    * @author cy
    * @date 2021-06-09
    * @return
    **/
    public class TicketTreadTest extends  Thread{
        //设置票数
        private  int ticket = 5;
        public static void main(String[] args) {
            //创建两个线程
            TicketTreadTest thread1 
                  = new TicketTreadTest();
            TicketTreadTest thread2 
                  = new TicketTreadTest();
            TicketTreadTest thread3 
                  = new TicketTreadTest();
            thread1.start();
            thread2.start();
            thread3.start();
        }
        @Override
        public void run() {
            while(true){
               //分别打印线程名称 和 ticket 数
               System.out.println("threadName:"
               +Thread.currentThread()+";
               ticket="+ticket--);
               if(ticket < 0){
                   break;
                }
           }
        }
    }
    

    结果分析:从下图输出结果中可以分析,使用继承Thread类实现卖票,导致每个窗口都卖了五张票,而这个电影院总共才五张票,多线程出现了超卖现象。原因是继承Thread方式,是多线程多实例,无法实现资源的共享
    在这里插入图片描述

    2.3多线程卖票小程序优化

    在2.2的小程序案列中,我们发现了在多线程的环境下, 由于公共资源可能会被多个线程共享, 也就是多个线程可能会操作同一资源. 当多个线程操作同一块资源时, 很容易导致数据错乱或发生数据安全问题,
    即: 数据有可能丢失, 有可能增加, 有可能错乱.

    我们如何避免这种现象呢?具体看代码:

    package trhead;
    
    /**
     * @author  cy
     * @date  2021-06-09
     *@deprecated  Runnable实现多线程卖票
     */
    public class TicketRunnableDemoTest {
        //设置票数
        private  static int ticket = 5;
    
        public static void main(String[] args) {
            //新建两个线程
            RunnableDemoTest1 r 
                   =  new RunnableDemoTest1();
            new Thread(r).start();
            new  Thread(r).start();
        }
    
        /**
         * 通过runnable 方式实现多线程
          */
    static class  RunnableDemoTest1  
                        implements  Runnable{
        @Override
        public void run() {
            while (ticket > 0){
                saleTicket();
            }
        }
    
            /**
             * 实现卖票方法
             */
        public  void  saleTicket(){
            if(ticket>0){
                System.out.println("threadName:"
                +Thread.currentThread()
                + "正在出票,余票剩余:"+ticket-- +"张");
            }
        }
    }
    }
    
    

    结果分析:从下图输出结果中可以分析,实现Runnable接口进行卖票,电影院总共才五张票,多线程卖票正常。原因是实现Runnable方式,是多线程单实例,可实现资源的共享

    在这里插入图片描述

    2.4多线程卖票小程序优化升级

    细心的小伙伴可能会发现,怎么在2.3输出打印的票数不是从大到小排序的,这跟现实中的卖票场景不一样呐。如果想解决这样的问题,就必须使用同步,所谓的同步就是指多个操作在同一个时间段内只有一个线程进行,其他线程要等待此线程完成之后才可以继续执行
    下面我们通过对2.3代码进行继续优化,实现真实卖票场景。

     /**
    * 通过synchronized实现线程同步
      * 实现卖票方法
      */ public synchronized   void   saleTicket1(){
          if(ticket>0){
              System.out.println("threadName:"
              +Thread.currentThread()
                      + "正在出票,余票剩余:"
                      + +ticket-- +"张");
          }
      }
    

    结果分析:从下图输出结果中可以分析,通过同步代码的方法进行代码的加锁操作,实现了卖票场景。
    在这里插入图片描述


    总结

    这节主要给大家介绍了多线程的实现以及相应的一些使用场景,并且引入了同步的知识点,下一节主要介绍synchronized关键字的使用。
    另外,码字不容易,如果发现小编描述有误,麻烦指摘。

    展开全文
  • ACL:是什么?目的?使用场景

    千次阅读 2020-01-30 11:26:57
    ACL的使用场景  ACL可以应用于诸多业务模块,其中最基本的ACL应用,就是在简化流策略/流策略中应用ACL,使设备能够基于全局、VLAN或接口下发ACL,实现对转发报文的过滤。 此外,ACL还可以应用在Telnet、FTP...

    ACL简介

    定义

    访问控制列表ACL(Access Control List)是由一条或多条规则组成的集合。所谓规则,是指描述报文匹配条件的判断语句,这些条件可以是报文的源地址、目的地址、端口号等。

    ACL本质上是一种报文过滤器,规则是过滤器的滤芯。设备基于这些规则进行报文匹配,可以过滤出特定的报文,并根据应用ACL的业务模块的处理策略来允许或阻止该报文通过。

    ACL结构图

    ACL匹配机制

    ACL在匹配报文时遵循“一旦命中即停止匹配”的原则。其实,这句话就是对ACL匹配机制的一个高度的概括。

    当然,ACL匹配过程中,还存在很多细节。比如,ACL不存在系统会怎么处理?ACL存在但规则不存在系统会怎么处理?为了对整个ACL匹配过程展开详细的介绍,小编画了一张ACL匹配流程图,相信对大家理解ACL匹配机制能有所帮助。

    ACL匹配机制

    从整个ACL匹配流程可以看出,报文与ACL规则匹配后,会产生两种匹配结果:匹配”和“不匹配”

    • 匹配(命中规则):指存在ACL,且在ACL中查找到了符合匹配条件的规则。不论匹配的动作是“permit”还是“deny”,都称为“匹配”,而不是只是匹配上permit规则才算“匹配”。
    • 不匹配(未命中规则):指不存在ACL,或ACL中无规则,再或者在ACL中遍历了所有规则都没有找到符合匹配条件的规则。切记以上三种情况,都叫做“不匹配”。

    无论报文匹配ACL的结果是“不匹配”、“允许”还是“拒绝”,该报文最终是被允许通过还是拒绝通过,实际是由应用ACL的各个业务模块来决定的。

    不同的业务模块,对命中和未命中规则报文的处理方式也各不相同。例如,在Telnet模块中应用ACL,只要报文命中了permit规则,就允许通过;而在流策略中应用ACL,如果报文命中了permit规则,但流行为动作配置的是deny,该报文会被拒绝通过。

    ACL目的

    随着网络的飞速发展,网络安全和网络服务质量QoS(Quality of Service)问题日益突出。

    • 企业重要服务器资源被随意访问,企业机密信息容易泄露,造成安全隐患。

    • Internet病毒肆意侵略企业内网,内网环境的安全性堪忧。

    • 网络带宽被各类业务随意挤占,服务质量要求最高的语音、视频业务的带宽得不到保障,造成用户体验差。

    以上种种问题,都对正常的网络通信造成了很大的影响。因此,提高网络安全性服务质量迫在眉睫。ACL就在这种情况下应运而生了。

    通过ACL可以实现对网络中报文流的精确识别和控制,达到控制网络访问行为、防止网络攻击和提高网络带宽利用率的目的,从而切实保障网络环境的安全性和网络服务质量的可靠性。

    ACL的使用场景 

    ACL可以应用于诸多业务模块,其中最基本的ACL应用,就是在简化流策略/流策略中应用ACL,使设备能够基于全局、VLAN或接口下发ACL,实现对转发报文的过滤。

    此外,ACL还可以应用在Telnet、FTP、路由等模块。

    ACL应用的业务模块非常多,但主要分为以下四类:

    业务分类

                                                                   应用场景

    涉及业务模块

    登录控制

    对登录权限进行控制,允许合法用户登录,拒绝非法用户登录,从而有效防止未经授权用户的非法接入,保证网络安全性。

    例如,一般情况下交换机只允许管理员登录,非管理员用户不允许随意登录。这时就可以在Telnet中应用ACL,并在ACL中定义哪些主机可以登录,哪些主机不能。

    Telnet、SNMP、FTP、TFTP、SFTP、HTTP

    对转发的报文进行过滤

    对转发的报文进行过滤,从而使交换机能够进一步对过滤出的报文进行丢弃、修改优先级、重定向、IPSEC保护等处理。

    例如,可以利用ACL,降低P2P下载、网络视频等消耗大量带宽的数据流的服务等级,在网络拥塞时优先丢弃这类流量,减少它们对其他重要流量的影响。

    QoS流策略、NAT、IPSEC

    对上送CPU处理的报文进行过滤

    对上送CPU的报文进行必要的限制,可以避免CPU处理过多的协议报文造成占用率过高、性能下降。

     

    例如,发现某用户向交换机发送大量的ARP攻击报文,造成交换机CPU繁忙,引发系统中断。这时就可以在本机防攻击策略的黑名单中应用ACL,将该用户加入黑名单,使CPU丢弃该用户发送的报文。

    黑名单、白名单、用户自定义流

    路由过滤

    ACL可以应用在各种动态路由协议中,对路由协议发布和接收的路由信息进行过滤。

    例如,可以将ACL和路由策略配合使用,禁止交换机将某网段路由发给邻居路由器。

    BGP、IS-IS、OSPF、OSPFv3、RIP、RIPng、组播协议

     ACL应用案例

    1使用基本ACL限制Telnet登录权限

    为了保障远程维护网络设备的安全性,现要求只有管理员(源地址是10.1.1.1/32)才能telnet登录交换机,其他人不允许登录。

    要实现这个需求,一定是在Telnet模块中应用ACL。那么该如何配置ACL规则呢?大家是不是认为应该先配置一条permit规则允许10.1.1.1/32登录,然后再配置多条deny规则拒绝其他地址登录呢?其实大可不必。

    查阅Telnet模块的报文处理机制参照表,当ACL中存在规则的情况下,如果报文匹配上permit规则,则该地址允许登录设备;如果未匹配上规则,该地址被拒绝登录设备。

    业务模块

    匹配上了permit规则

    匹配上了deny规则

    ACL中配置了规则,但未匹配上任何规则

    ACL中没有配置规则

    ACL未创建

    Telnet

    permit(允许登录)

    deny(拒绝登录)

    deny(拒绝登录)

    permit(允许登录)

    permit(允许登录)

    因此,我们仅需配置一条允许10.1.1.1/32地址通过的permit规则即可,10.1.1.1/32以外的地址的报文因匹配不上任何规则会被拒绝登录。

    2使用基本ACL限制FTP访问权限示例

    组网需求

    如图所示,Switch作为FTP服务器,对网络中的不同用户开放不同的访问权限:

    • 子网1(172.16.105.0/24)的所有用户在任意时间都可以访问FTP服务器。
    • 子网2(172.16.107.0/24)的所有用户只能在某一个时间范围内访问FTP服务器。
    • 其他用户不可以访问FTP服务器。

    已知Switch与各个子网之间路由可达,要求在Switch上进行配置,实现FTP服务器对客户端访问权限的设置。

    使用基本ACL限制FTP访问权限组网图 

     

    配置思路

    采用如下的思路在Switch上进行配置:

    1. 配置时间段和ACL,使设备可以基于时间的ACL,对网络中不同用户的报文进行过滤,从而控制不同用户的FTP访问权限。
    2. 配置FTP基本功能。
    3. 在FTP模块中应用ACL,使ACL生效。

     

    Consul Access Control(ACLS)

    Consul使用Access Control Lists (ACLs)来保护UI、API、CLI、服务间通信和agent间通信。ACL的核心是将规则分组到策略中,然后将一个或多个策略与一个Token关联起来。

    Consul ACL可以用来控制数据和接口的访问。

    应用:consul配置acl:允许注册和访问所有节点,并读取任何服务

    参考链接:

    https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#domain-acls

    https://learn.hashicorp.com/consul/security-networking/production-acls

    https://forum.huawei.com/enterprise/zh/thread-336589.html

    https://support.huawei.com/enterprise/zh/doc/EDOC1100038902/9aca1495

    https://juejin.im/post/5d3ffce56fb9a06af7121025

    https://support.huawei.com/enterprise/zh/doc/EDOC1100116596/bcfa479c

    https://muka.app/?p=336

    https://www.consul.io/api/acl/acl.html

    展开全文
  • Elasticsearch最佳实践之使用场景

    万次阅读 多人点赞 2018-10-08 20:31:30
    本文围绕Elasticsearch的核心特征:搜索与分析,探讨其常见的业务场景:ELK日志系统、数据聚合分析、业务内搜索,以及集群建设的选择。

      最开始使用Elasticsearch是两年多前,在一家创业公司负责数据系统的建设,当时也有写一些博文来分享使用方法。然而回过头去想,觉得当时的很多认知不够深入,或者说是当时的业务场景下没有遇到更多的问题。很多时候,一个技术或工具,只有在更复杂的业务场景和更大的数据量下经历实践,才能有更深的体会与认识。
      过去一段时间,有幸在项目中继续实践Elasticsearch,从设计、研发到调优,逐渐对Elasticsearch有了些新的认知与心得,因此计划撰写一个专栏来较系统的整理一下。也许,一段时间后,又会觉得这些认识不够深入,奈何这就是认知的过程。
      对于Elasticsearch的实践,主要分为两块:应用层面的研发和集群的运维,本专栏侧重于前者。计划撰写5篇左右:

    • 使用场景,探讨几种常见的业务场景,以及集群建设的选择
    • 核心概念与原理,以图文形式整理出核心的概念与原理
    • Index与Shard设计,分享如何结合业务来设计Index和合理分配Shard
    • 项目应用,分享Elasticsearch在笔者项目中的实践
    • 性能调优,分享数据写入与查询过程的性能调优方法

      需要首先指出的是,本专栏所使用的Elasticsearch版本是5.5

    正文

      作为专栏的第一篇,本文将尝试从两个角度来探讨一下当前Elasticsearch的使用场景。一个是常见的业务场景,目的在于让大家能够感性的认识到Elasticsearch可以做什么。在遇到类似业务场景时,可以想到Elasticsearch,用其形成解决方案或者作为评估对象之一。另一个是集群建设方面,探讨的问题是:自己搭建Elasticsearch集群还是使用云服务。

    常见的业务场景

      下图是官方的定位,Elasticsearch的核心特征是数据搜索分析。与这两个特征相关的需求都可以考虑使用Elasticsearch,其本身是单纯的,复杂的是具体业务。在不同的业务中,Elasticsearch扮演着不同的角色,也有着不同的实践和优化方法。归纳起来,目前主要有三类常见的业务场景,笔者将逐一分析。

    • ELK日志系统
    • 数据聚合分析
    • 业务内搜索

    ELK日志系统

      大概很多互联网的朋友接触Elasticsearch都是从ELK开始的,用来解决Log的集中式管理问题。这样的需求来自于互联网的快速发展,出现越来越多的集群部署与分布式系统,导致服务产生的Log信息分散在不同的机器上,无法有效的检索与统计。以下面的应用服务集群为例,为了做集中式Log管理,需要有一个Agent负责从每台机器收集信息,送到一个存储系统集中存储(该系统需要具备快速的文本搜索功能),然后通过一个可视化UI来查看和分析信息。

      ELK以全家桶的形式为这一问题提供了解决方案,Logstash负责收集、解析数据,Elasticsearch负责存储、检索数据,Kibana提供可视化功能。笔者曾在创业公司做数据分析(四)ELK日志系统一文介绍过相关的使用方法。

      当然,这并不意味着ELK必须捆绑使用。一方面,Logstash是基于JRuby编写,在部署和性能上的表现并不能满足所有需求,所以很多人会将其替换为自己编写的数据采集工具。同时Elastic官方也有提供Beats相关轻量级组件,可与Logstash组合使用。另一方面,也有很多人在Kibana的基础上做二次开发,来增强相应的查询功能,集成开源的告警功能等。但是Elasticsearch始终是核心组件,很少有人将其替换掉,源于其强大的搜索功能恰好满足Log的检索需求。有一点建议是,ELK本身已经很好使用,除非有强烈的业务需求,否则没有必要刻意去替换,先考虑用对、用好它。

    数据聚合分析

      数据的维度统计查询,是当前数据业务的一个主要需求。其配合相应的可视化UI可以帮助用户直观的获取信息、做出决策等。比如,针对网络流量数据,查看上班时间段,员工访问视频类网站的流量占比。
      这样的统计查询基本可以归纳为:按照某些条件过滤 --> 针对某个维度分组 --> 统计数据(Sum/Count)。在海量数据下,如何实现快速查询?(亿级以上数据量,秒级查询)

      首先,诸如MySQL这类关系型数据基本是无法胜任的,其无法突破单机的存储和处理能力限制,而引入分片又会带来应用层面的复杂度。其次,面对这样的海量数据,通常有两个思路:一个是根据需求,制定相应的预计算方案,通过ETL来提前算好相关的统计数据,但是不能很好的应对未知的维度数据。另一个就是不做预计算,Elasticsearch便是其中一个选择,其他方案还有Presto/Spark SQL这样基于内存的Map/Reduce计算框架等。
      Elasticsearch强大的搜索与分析聚合能力使其可以很好的适用于这一业务场景。以笔者当前的项目来看,百亿级数据可以做到秒级查询。另外,Elasticsearch的一些特性,诸如alias等可以很好的帮助我们完成一些业务逻辑。
      当然,任何事情都不是完美的,选择Elasticsearch得有两个前提:第一,受限于其工作机制,聚合结果可能存在较小的偏差的;第二,数据需要规划好,保持扁平结构,不能有JOIN的需求。

    业务内搜索

      现如今,搜索功能几乎是互联网产品的标配,用于帮助用户快速在产品中找到所需的信息。笔者将这样一类需求定义为业务内搜索,其特性是在业务范围内提供搜索功能。比如下图中的食谱类App,只需要支持对菜谱、食材这些业务内容进行搜索,而无需关注其他信息。

      基于Elasticsearch,可以快速构建这样的搜索功能。通常是采用DB与Elasticsearch配合的方案,DB负责数据存储,Elasticsearch负责关键词检索。Elasticsearch可以在多维度上检索与关键词相关的数据,并为每个匹配结果生成一个相关度分数。当服务收到搜索请求时,首先根据关键词到Elasticsearch中进行检索,然后根据检索结果去DB中查询信息,并在应用层进行数据整理和排序。
      搜索精度的调优是重点,也是最难的一部分。比如,如何建立业务内容的词库,如何进行合理分词建立索引,如何调整搜索权重等等。笔者曾经在做搜书系统(打造私人搜书系统之系统设计)时有过相关的简单实践,抽空会继续将其整理出来。

    集群建设的选择

      伴随着云服务的发展,Elasticsearch集群的建设出现了以下三种选择:

    • 在自有的服务器上构建Elasticsearch集群,自己运维
    • 在云厂商提供的EC2机器上构建Elasticsearch集群,自己运维
    • 使用云厂商提供的Elasticsearch云服务构建Elasticsearch集群

      第一种选择以大公司为主,多以平台的形式为整个公司提供服务;后面两种主要面向中小型企业,多以产品为导向,即每个产品维护自己的集群。对于第二种选择,通常是需要构建稳定运行的Elasticsearch集群,由专业的运维人员负责管理。而第三种选择,通常是企业需要构建稳定运行的Elasticsearch集群,并希望将更多的人力、物力放到业务层面而非集群运维上面。随着Elasticsearch云服务的成熟,越来越多处于第二种选择的企业开始考虑或正在迁移。
      Elasticsearch云服务可帮助企业更好的做集群扩展,解放运维,把关注点放到业务层面。以AWS Elasticsearch云服务为例,它可以帮助用户实现没有downtime的扩展、版本升级等。目前,提供相关服务的有AWS、阿里云、Elastic官方等等。当然,任何事情都有两面性,在方便的同时也会带来不方便,比如无法触及到机器导致一些调优方案无法实施。
      其实,究竟应该如何选择,更多是由一个企业所处的行业、企业战略以及历史背景来决定。


      不同的业务场景,加上不同的集群构建方法,就会导致在使用Elasticsearch时的侧重点不同,相关设计与优化的方法也会有所不同。笔者当前项目是采用AWS Elasticsearch云服务构建,针对大数据聚合分析的业务场景,所以,在后面的博文中,会侧重于这方面。




    (全文完,本文地址:https://blog.csdn.net/zwgdft/article/details/82917861
    版权声明:本人拒绝不规范转载,所有转载需征得本人同意,并且不得更改文字与图片内容。大家相互尊重,谢谢!)

    Bruce
    2018/10/08 晚


    展开全文
  • TreeMap使用场景 优势

    千次阅读 2020-03-21 10:05:47
    TreeMap使用场景 1- 简介 TreeMap的底层实现原理 基于红黑树实现的排序Map TreeMap增删改查的时间复杂度 TreeMap的增删改查和统计相关的操作的时间复杂度都为O(logn) TreeMap的key和value的要求 1 由于实现...

                                  TreeMap使用场景 优势

    优势

    先说说红黑树的五点

     

    1 红黑树是牺牲了严格的高度平衡的优越条件为代价,它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。

     

    2红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较便宜的解决方案。

    3结合TreeMap

    TreeMap 实现了 SortMap 接口,其能够根据键排序,默认是按键的升序排序,也可以指定排序的比较器,当用 Iterator 遍历 TreeMap 时得到的记录是排过序的,TreeMap 取出来的是排序后的键值

    4 红黑树占用的内存更小(仅需要为其存在的节点分配内存),而Hash事先应该分配足够的内存存储散列表,即使有些槽可能弃用

    使用场景

     

    答:TreeMap 实现了 SortMap 接口,其能够根据键排序,默认是按键的升序排序,也可以指定排序的比较器,当用 Iterator 遍历 TreeMap 时得到的记录是排过序的,所以在插入和删除操作上会有些性能损耗,TreeMap 的键不能为空,其为非并发安全 Map,此外 TreeMap 基于红黑树实现。

    HashMap 是最常用的 Map,其基于哈希散列表实现,主要根据键的 hashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,当用 Iterator 遍历 HashMap 时得到的记录顺序是随机的,HashMap 允许键和值均为空,其为非并发安全 Map。

    所以一般情况下我们选用 HashMap,因为 HashMap 的键值对在取出时是随机的,其依据键的 hashCode 值和键的 equals 方法存取数据,具有很快的访问速度,所以在 Map 中插入、删除及索引元素时其是效率最高的实现。而 TreeMap 取出来的是排序后的键值对,所以效率会低点。

     

    自己的话来说就是TreeMap是按键排序的也可以是按照自己自定义键排序,而HashMap其依据键的 hashCode 值和键的 equals 方法存取数据,具有很快的访问速度。

     

    而 TreeMap 取出来的是排序后的键值,HashMap 的键值对在取出时是随机的

     

     

     

     

     

     

     

     

     

    1- 简介

    TreeMap的底层实现原理

    基于红黑树实现的排序Map

    TreeMap增删改查的时间复杂度

    TreeMap的增删改查和统计相关的操作的时间复杂度都为 O(logn)

    TreeMap的key和value的要求

    1 由于实现了Map接口,则key的值不允许重复(重复则覆盖),也不允许为null,按照key的自然顺序排序或者Comparator接口指定的排序方法进行排序。

    2 value允许重复,也允许为null,当key重复时,会覆盖此value值。

     

    2- TreeMap的使用场景

    考虑如下场景:

    • 需要基于排序的统计功能:

    由于TreeMap是基于红黑树的实现的排序Map,对于增删改查以及统计的时间复杂度都控制在O(logn)的级别上,相对于HashMap和LikedHashMap的统计操作的(最大的key,最小的key,大于某一个key的所有Entry等等)时间复杂度O(n)具有较高时间效率。


          需要快速增删改查的存储功能:
     

    相对于HashMap和LikedHashMap 这些 hash表的时间复杂度O(1)(不考虑冲突情况),TreeMap的增删改查的时间复杂度为O(logn)就显得效率较低。

     

    需要快速增删改查而且需要保证遍历和插入顺序一致的存储功能

    相对于HashMap和LikedHashMap 这些 hash表的时间复杂度O(1)(不考虑冲突情况),TreeMap的增删改查的时间复杂度为O(logn)就显得效率较低。但是HashMap并不保证任何顺序性。LikedHashMap额外保证了Map的遍历顺序与put顺序一致的有序性。

    在这里插入图片描述

     

    展开全文
  • Redis-使用场景

    万次阅读 2018-06-06 18:23:40
    Redis是一个key-value存储系统,现在在各种系统中的使用越来越多,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景。 Redis特性 一个产品的使用场景肯定是需要根据产品的...
  • EventBus使用总结和使用场景

    千次阅读 2019-01-21 11:25:40
    一、EventBus介绍 EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。传统的事件传递方式包括:Handler、...二、使用场景 刚开始接触EventBus的使用...
  • Redis之常用的十几种使用场景

    千次阅读 多人点赞 2020-04-17 12:01:00
    四、使用场景 文章目录四、使用场景1、缓存2、数据共享分布式3、分布式锁4、全局ID5、计数器6、限流7、位统计8、购物车9、用户消息时间线timeline10、消息队列11、抽奖12、点赞、签到、打卡13、商品标签14、商品筛选...
  • 常见图表的使用场景

    千次阅读 2020-01-13 21:36:12
    ...在数据可视化领域我们经常使用各种图表来形象直观的展现数据,业务人员或者数据分析人员可以通过图表分析公司业务的经营状况,发现公司...二、图表类型和使用场景 三、Abela 图表使用傻瓜指南
  • redis使用场景及案例

    万次阅读 多人点赞 2019-08-19 14:49:30
    最近在写一个篮球社区项目,其中redis的使用场景还挺多的,于是结合项目总结一下redis的使用场景 一、缓存 项目场景:用户登录或注册时的验证码存储,用户名 set Code:1:code 1232 EX 100 NX OK get Code...
  • redis的bitmap使用场景

    千次阅读 2019-08-04 11:43:57
    使用场景一:用户周活跃 一周用户登录情况 127.0 .0 .1 : 6379 > setbit Monday 8987129 0 ( integer ) 0 127.0 .0 .1 : 6379 > setbit Monday 8298191 1 ( integer ) 0 127.0 .0 .1 : 6379...
  • 理解useMemo与useCallback的使用场景

    千次阅读 2020-12-19 23:40:28
    回顾 在介绍一下这两个hooks的作用之前,我们先来回顾一下react中的性能...基于上面的两点,我们通常的解决方案是:使用immutable进行比较,在不相等的时候调用setState;在shouldComponentUpdate中判断前后的props
  • 一文读懂 HBase 使用场景

    千次阅读 2019-05-17 13:39:29
    目前已经在金融、交通、医疗、车联网、IoT等众多领域有了最佳实践,涉及到订单/账单存储、用户画像、时空/时序数据、对象存储、Cube分析等各个使用场景。 往期推荐 1、HBase最佳实践 | 聊聊HBase核心配置参数 2、...
  • Java泛型的使用场景

    千次阅读 2019-08-06 11:00:37
    一、泛型概括 ... 在没有使用泛型的情况下,如果要实现参数“任意化”,通常会定义成Object类型来接受,然后强制类型转换使用;而强制类型转换有明显的缺点,就是必须要知道实际参数的具体类型的情...
  • VUE slot插槽的使用和使用场景

    千次阅读 2020-09-30 13:56:32
    我先简单的说一个场景吧,来理解一下插槽和它的使用场景,比如哈!有一个模块,除了一个小地方 显示的东西不同,其他的内容都是一样的!如下图,你此时此刻想怎么写这个需求呢? 1.有几个状态写几个组件??? 2....
  • MongoDB特点和使用场景

    万次阅读 2019-05-17 09:19:10
    Mongodb的优点与不足 (1)Mongodb的不足之处 在集群分片中的数据分布不均匀 单机可靠性比较差 大数据量持续插入,写入性能有较大波动 ...MongoDB 的应用场景和不适用场景 1.适用场景 对于MongoDB实际应用来讲...
  • 闭包的使用场景

    千次阅读 2020-10-24 19:23:47
    一、闭包 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,闭包就是能够读取其他函数内部变量的函数。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。 比如下面的代码: ...
  • MongoDB和Elasticsearch的各使用场景对比

    千次阅读 2020-09-20 12:30:17
    mongo使用c++, es使用Java开发 写入延迟 低 高 es的写入延迟默认1s, 可配置, 但是要牺牲一些东西 全文索引支持度 一般 非常好 es本来就是搜索引擎, 这个没啥可比性 有无Schem.
  • 2.Redis五种数据类型及使用场景

    万次阅读 2021-08-07 09:52:49
    通过使用场景,带大家快速掌握Redis五种数据类型。string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。
  • this.$nextTick()的使用场景

    万次阅读 多人点赞 2020-04-26 19:13:16
    一、用途 应用场景:需要在视图更新之后,基于新的视图进行操作。 this.$nextTick()方法主要是用在...created()中使用的方法时,dom还没有渲染,如果此时在该钩子函数中进行dom赋值数据(或者其它dom操作)时无异...
  • ELK使用场景解析

    千次阅读 2019-03-07 09:38:38
    也会介绍一些典型的使用场景,方便大家发散思维。另外会对未来的产品的演进方向做一个展望,总结过去、现在和未来,对我们产品感兴趣、想知道拿来都能干什么以及以后将会怎么样,都可以过来了解一下。 8、最后,...
  • 原型模式的使用场景

    千次阅读 2019-05-30 14:18:56
    文章目录原型模式的使用场景源码使用场景-Intent案例demo 原型模式的使用场景 (1)类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。 (2)通过new一个对象需要非常繁琐的数据...
  • Redis在项目中的地位及使用场景剖析

    千次阅读 2019-05-03 12:49:12
    Redis在项目中的地位及使用场景剖析 一、 redis 特点 所有数据存储在内存中,高速读写 提供丰富多样的数据类型:string、 hash、 set、 sorted set、bitmap、hyperloglog 提供了 AOF 和 RDB 两种...
  • spring BeanPostProcessor使用场景

    千次阅读 2020-04-12 12:34:59
    AnnotationConfigApplicationContext(创建容器) ->refresh ->finishBeanFactoryInitialization ->getBean ->doGetBean ->createBean ->doCreateBean -> this.p...
  • ThreadLocal 是什么?有哪些使用场景

    万次阅读 多人点赞 2019-05-23 11:09:03
    有哪些使用场景? ThreadLocal 是线程本地存储,在每个线程中都创建了一个 ThreadLocalMap 对象,每个线程可以访问自己内部 ThreadLocalMap 对象内的 value。 经典的使用场景是为每个线程分配一个 JDBC 连接 ...
  • kafka的使用场景

    万次阅读 多人点赞 2018-05-10 18:28:02
    目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ二、消息队列应用场景以下介绍消息队列在实际应用中常用的使用场景。异步处理,应用解耦,流量削锋和消息通讯四个场景。2.1异步...
  • Neo4j 使用场景

    千次阅读 2020-01-08 13:08:48
    通过人员关系图分析可以清楚地知道洗钱网络及相关嫌疑,例如对用户所使用的帐号、发生交易时的IP地址、MAC地址、手机IMEI号等进行关联分析。 2、推荐系统 比如你在淘宝上浏览了某一个商品,它在下面有“猜你喜欢”...
  • 闭包原理以及使用场景

    千次阅读 2020-11-23 18:54:26
    前端面试,必问闭包 闭包有多重要?如果你是初入前端的朋友,我没有办法直观的告诉你闭包在实际开发中的无处不在,但是我可以告诉你,前端面试,必问闭包。面试官们常常用对闭包的了解程度来判定面试者的基础水平,...
  • Jwt的使用场景

    千次阅读 2019-07-02 09:48:22
    什么是Jwt ...为什么要使用token? token是什么 Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需...
  • MQTT 使用场景

    千次阅读 2020-04-28 15:16:54
    MQTT 应用场景 物联网英文名称为The Internet of things,IoT便是物联网的英文缩写,物联网是基于互联网、广播电视网、传统电信网等信息承载体,让所有能够被独立寻址的普通物理对象实现互联互通的网络。它具有普通...
  • ES6 Symbol 使用场景

    千次阅读 2019-04-02 16:11:38
    ES6 新增了第 7 种原始数据类型 Symbol,简单介绍一下它的使用方法及使用场景。 Symbol 含义及使用方法 symbol 英文意思为 符号、象征、标记、记号,在 js 中更确切的翻译应该为 独一无二的值,理解了它的意思之后再...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,088,227
精华内容 835,290
关键字:

使用场景

友情链接: KS3Explorer-2.3.22.zip