精华内容
下载资源
问答
  • 可能在贯穿到整个验证系统思想里面,我们都会不断重复验证人员该具备素质。...接下来让我分别解释这五个维度:     完备性:该维度要求验证充分。无论你从项目经理、系统人员、设计人员还是验...

    本文转自:http://www.eetop.cn/blog/html/28/1561828-433754.html

    可能在贯穿到整个验证系统思想里面,我们都会不断重复验证人员该具备的素质。为了可以将抽象的词汇具象出来,我们列出了验证人员在验证流程中需要具备的五个技术维度。接下来让我分别解释这五个维度:

     

     

    • 完备性:该维度要求验证的充分。无论你从项目经理、系统人员、设计人员还是验证人员,大家谈验证首先提到的就是要“充分”。然而充分一词对于验证而言边界时模糊的,很难量化到什么时候才可以达到验证的完成标准。所以,作为一名验证经理,需要引入各种数据来综合量化出验证的进度,这其中包括了验证功能点的覆盖率,代码覆盖率,是否经过了低功耗验证流程(power aware verification),是否经过了跨时钟域检查等等。 通过数据量化,来对验证人员和验证经理增强足够信心来宣布某一个项目节点中,验证已经得到了“充分”的验证。当然,对于功能覆盖率部分,如何将功能描述文档充分理解,进而充分列出要测试的功能点并尽可能地细分出来,这需要系统人员、设计人员和验证人员的共同努力。同时,如何将抽象的验证计划转换到功能覆盖语言(SystemVerilog function coverage)需要验证人员具备该能力。

    • 复用性:从项目的实际运用角度来看,复用性和完备性是同等重要的。没有人愿意会在下一个项目中将以前的验证环境做较大的更新,因为这意味着额外的资源消耗,包括时间、人力和项目进度的考虑。在硬件设计角度而言,通过标准总线协议,可以最大限度的讲模块之间实现相对独立和快速集成,所以对于目前项目进度不断缩紧的现状来看,一方面是市场的瞬息万变导致的,一方面也是由于SoC自身逐渐趋向于软件的快速周期迭代方式而成的。对于一个系列芯片而言,后续芯片的性能提高、功耗优化都是建立在前一代的基础上的,而这些不断地提高和优化具体到每一个硬件子系统而言,可能就是他们的存储大小、时钟快慢、动态电源开关、总线宽度、缓存深度来综合决定的,然而下一代硬件设计自身一般不会有第一代芯片的艰难历程(否则它也就称不上是系列芯片了)。 那么从硬件设计的角度来看,这些更新如果不会在逻辑上面有大的变动,那么带来的工作量是可以估计的。而从验证角度来看,我们也很自然地希望验证的工作量也不需要太大——可是事实并不一定是这样的。首先从芯片项目的集成性而言,设计人员相比较验证人员,在同一功能模块的稳定性是更高的,那么当一个验证人员在尝试阅读和修改上一个项目的验证代码时,就要看看他的运气。一般来讲,他的运气会跟上一个验证人员的代码风格有直接的关系……同时,验证人员在处理一些总线协议的时候要有意识引入参数来为日后的复用做好准备。而不断融合的验证方法学,走到今天,UVM(Universal Verification Methodology)之所以划分出不同的功能单元,实现小的颗粒度,提供快速插拔式的环境集成,也是为了复用性考虑的。

    • 高效性:指的是用尽可能少的工作量来完成验证工作。在保证验证完备性的情况考虑下,实际上复用性和高效性会有存在冲突的可能。例如,验证人员会考虑如何“短平快”地在一个紧张周期内完成验证工作,但可能他不会采用UVM等方法学框架,也有可能他不会考虑将参数引入到验证环境中,因为这些“额外”的因素虽然是对复用性有帮助的,但是也会跟高效性有冲突。所以,验证人员需要针对不同的情况来在上述的五种维度之间做好平衡,至少需要保持一种意识,那就是工程学的执行阶段本身就是一种平衡,对于验证人员来讲,他需要作出的判断就是在每一个项目每一项验证任务中做好取舍,来给出一个合适的验证考量维度。甚至对于同一项验证任务而言,采取不同的验证策略也会有不同的完成效果。例如,一开始考虑采用随机约束的验证方法,那么单单就约束而言,它的约束一开始是比较窄合适,还是一开始比较宽宽合适?
      这里我们再给出一张示意图来说明高效性实际上在不同的验证方法和同一个验证任务在不同状态时都需要有相应的变化。因为在开始阶段,考虑到设计不够完备而且尚未经历过验证,我们一开始的阶段称作基本功能验证阶段,这个阶段,我们会将随机约束域降低到基本范围,尽可能少的触碰到边界情况,而把重点放到如何先将各项基本功能都验证到。第二个阶段是在我们已经完成基本功能验证以后开始的完备功能验证,这时我们就可以逐渐放开随机约束域,而开发的速度跟合适能够设定最终的开放域范围需要验证人员充分考虑到各种合理的情形再做约束域的限定。而当了功能覆盖率一般上升到80%附近的时候,这就处于了最后的爬坡阶段,这个时候,如果再沿用之前广泛的约束域,那么会产生很多无效的随机种子,这些“无效”的随机种子基本对于剩下的验证覆盖率完善没有什么帮助,那么这个时候验证人员就需要通过理解设计本身和随机产生的约束两方面来考虑具体贡献覆盖率的测试序列,再进一步缩窄随机约束域,来定向(biasing)产生一些激励,对于最后的这一阶段,一种极端的情况就是将随机约束域缩到尽可能窄的情况,甚至和直接测试(directed test)没有什么区别。

       

    • 高产出:指的是在一定的时间,可以调试、报告、帮助修正出多少个设计缺陷,以及可以建立多么完整的验证环境。多年来数字硬件设计(RTL级别)的基础并没有发生太多变化,同时EDA厂商提供的自动化工具又进一步提供了便利,提高的设计本身的可靠性。但是这一情况却并不适用于数字验证,因为EDA工具目前仍然只能作为辅助手段,例如提供更多方便的调试功能和接口,却不能也随之自动化帮助建立复杂的验证环境。这也就不难解释了2014年Wilson在功能验证领域的调查数据显示,今天在设计和验证领域面临着最大的挑战之一就是为快速的芯片产品和员工数量增长之间找到一个平衡点, 实现单位产出的提高。

    • 代码性能:关于这一点要讲详细一点,需要专门开个话题。代码性能似乎也跟高效高产出有冲突的地方,因为对于验证代码的整洁性、复用性甚至一点点地美感都对于数字意义上的验证完备性没有直接联系,这也包括你的验证经理可能有好长时间都不会注意到你写的验证代码,除非有一天你验证的那个设计出了一个缺陷,而且是一个显而易见的缺陷却没有被发现,这可能才会引起验证经理的注意专门来访问可能是一团糟的代码结构。 但是每一位验证人员也需要记住一句台词“出来混迟早是要还的”,无论是你在看着别人写的验证代码没有注释、没有缩进、超长if-else判断语句等等这些让你已经无力吐槽是时刻,还是你因为项目紧张快速搭建验证环境和编写测试用例的时候没有考虑到“后来阅读者”和“你后来阅读”而偷的各种懒,相信我,时间会让你为此买单的。所以,作为一名验证人员,请在你写每一行代码的时候把它当做你日后行业名声的荣誉墙,尽管你还在迫于项目的压力快速建立环境疲于完成验证,但等到你有闲的时候会去再改善那些代码吗?不要再相信这些鬼话了,现在就去做吧!

     


    从上面的五个维度来看,做一名合格的验证人员实属不易,更不要说考虑到每一个项目每一项验证任务来分别针对制定出合适的五个维度指数。虽然项目执行没有尽善尽美,但是针对验证人员自身,如果可以意识到这五个维度的存在,并且能够在实际工作中都照顾到它们,运用到验证任务的考量当中,那你就是有意识地在培养自己成为一名验证师了

    展开全文
  • 就是按天维度的统计,要求3s统计一次结果。 首先这需求,我的想法是:开一24H的窗口,然后自定义触发器,3s触发一次窗口计算,然后把计算结果sink到redis中去。话不多说,直接上代码。 基本代码 这里为了方便...

    前言:一看时间,都快1年不写flink的系列文章了,今天写一个很实用的一个场景内容,也是我们生产中的用法。就是按天维度的统计,要求3s统计一次结果。

    首先这个需求,我的想法是:开一个24H的窗口,然后自定义触发器,3s触发一次窗口计算,然后把计算结果sink到redis中去。话不多说,直接上代码。

    基本代码

    这里为了方便直接用socket去模拟数据源,数据格式大概是:sensor_1,1547718228000,38.1
    有个实体类:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class SensorReading {
        // ID。时间戳、温度
        private String sensorId;
        private Long timestamp;
        private Double temperature;
    }
    

    然后是基本流程不需要多解释了,有个自己写的工具类ExecutionEnvUtil

    private static final Logger log = LoggerFactory.getLogger(FlinkWindowTest.class);
    
        public static void main(String[] args) throws Exception {
            ParameterTool parameterTool = ExecutionEnvUtil.createParameterTool();
            StreamExecutionEnvironment env = ExecutionEnvUtil.getStreamExecutionEnv(parameterTool);
    
            DataStream<SensorReading> dataStream = env.socketTextStream("hadoop01", 7777)
                    .map(x -> new SensorReading(
                            x.split(",")[0],
                            Long.valueOf(x.split(",")[1]),
                            Double.valueOf(x.split(",")[2])));
            dataStream.print("source");
    
            // time window
            DataStream<Tuple2<String, Double>> resStream = dataStream
                    .assignTimestampsAndWatermarks(WatermarkStrategy.<SensorReading>forBoundedOutOfOrderness(Duration.ofSeconds(2))
                            .withTimestampAssigner(((element, l) -> element.getTimestamp())))
                    .keyBy(SensorReading::getSensorId)
                    .window(TumblingEventTimeWindows.of(Time.seconds(100)))  // 1.12默认都是EventTime
                    //.aggregate(new MyAggregateFunction());
                    .trigger(new MyTrigger(5000L))
                    .process(new MyProcessWindowFunction());
            resStream.print("res");
    
            // count window
    
    
            env.execute("window test");
        }
    

    注意:这里有几个自定义的类,后面一个个的细说

    • 首先是设置提取事件时间并且设置水印,1.12默认就是事件时间了,然后设置水印的写法和之前1.9的有些区别,之前的写法现在已经标记为过时方法了,大家如果用的新版本,可以按照这个写法来设置水印。

    • 然后就是分组,就是按照 sensorId 分组。

    • 然后是开窗,这里按照事件时间,开了100s的窗口(你们按实际需求来,天维度的直接24H即可)。

    • 然后就是自定义的触发器类 MyTrigger ,这里传了一个时间,就是每隔多长时间触发一次。 里面的注释写的还是比较详细的,都是自己实测出来的结果。
      这里说下大体的思路逻辑:就是数据来了看该key分组下的有没有触发器,如果没有就给他注册一个,时间的话是取事件时间加上触发间隔和窗口结束时间 这两者的最小值,这样保证触发时间是永远小于窗口结束时间的。然后返回的是TriggerResult.CONTINUE,就是啥都不做。然后当水位线达到了触发器的时间点,则会进入onEventTime方法,此时需要把触发器清除或者把触发器中的触发时间归零,然后返回TriggerResult.FIRE_AND_PURGE,即触发计算然后清除窗口元素。这样的话,下一次再有数据进来又会重新注册一个事件时间的触发器,然后触发下次的计算,如此循环往复,直到窗口关闭调用clear方法,把触发器删除即可。

      static class MyTrigger extends Trigger<SensorReading, TimeWindow> {
      
              /**
               * TriggerResult的各个含义
               * CONTINUE:啥都不做
               * FIRE:触发计算,保留元素
               * PURGE:不触发计算,清元素除窗口
               * FIRE_AND_PURGE:触发计算,然后清除窗口中的元素
               */
      
              // 存储窗口计算时间的状态
              private ValueStateDescriptor<Long> triggerTimeStateDesc = new ValueStateDescriptor<>("triggerTimeState", Long.class);
      
              // 触发的间隔时间
              private Long interval;
      
              public MyTrigger(Long interval) {
                  this.interval = interval;
              }
      
              /**
               * 每来一个数据都会调用该方法
               *
               * @param element   数据
               * @param timestamp 如果是事件时间,该时间为每条数据的事件时间
               * @param window    窗口对象
               * @param ctx       上下文对象
               * @return
               * @throws Exception
               */
              @Override
              public TriggerResult onElement(SensorReading element, long timestamp, TimeWindow window, TriggerContext ctx) throws Exception {
                  log.info("数据来了,timestamp:{}", timestamp);
                  log.info("窗口开始时间:{},窗口结束时间:{}", window.getStart(), window.getEnd());
                  Long triggerTime = ctx.getPartitionedState(triggerTimeStateDesc).value();
                  log.info("triggerTime:{}", triggerTime);
                  if (triggerTime == null || triggerTime == 0L) {
                      log.info("该key:{}下的数据中暂无定时器,下面给予设置事件时间定时器", element.getSensorId());
                      triggerTime = Math.min(timestamp + interval, window.getEnd());
                      ctx.getPartitionedState(triggerTimeStateDesc).update(triggerTime);
                      ctx.registerEventTimeTimer(triggerTime);
                  }
                  return TriggerResult.CONTINUE;
              }
      
      
              /**
               * 注册的 "处理时间定时器" 触发时调用该方法
               *
               * @param time   定时器触发时的时间
               * @param window 窗口对象
               * @param ctx    上下文对象
               * @return
               * @throws Exception
               */
              @Override
              public TriggerResult onProcessingTime(long time, TimeWindow window, TriggerContext ctx) throws Exception {
                  return TriggerResult.CONTINUE;
              }
      
      
              /**
               * 注册的 "事件时间定时器" 触发时调用该方法,
               * 注意是水位线到达的时候才会触发,水位线就是事件时间减去延迟时间
               *
               * @param time   定时器触发时的时间,即注册的事件时间触发器的时间
               * @param window 窗口对象
               * @param ctx    上下文对象
               * @return
               * @throws Exception
               */
              @Override
              public TriggerResult onEventTime(long time, TimeWindow window, TriggerContext ctx) throws Exception {
                  log.info("onEventTime中的time:{}", time);
                  // 触发器触发后,应该清除当前设置的触发器或者把触发事件设置为0,重新定义下一个触发器
                  ctx.getPartitionedState(triggerTimeStateDesc).update(0L);
                  // 此时应该触发窗口计算(即执行下面的窗口函数)并且清除窗口元素
                  return TriggerResult.FIRE_AND_PURGE;
              }
      
              /**
               * 窗口关闭的时候清除整个窗口的方法
               * @param window
               * @param ctx
               * @throws Exception
               */
              @Override
              public void clear(TimeWindow window, TriggerContext ctx) throws Exception {
                  Long value = ctx.getPartitionedState(triggerTimeStateDesc).value();
                  log.info("clear方法中 triggerTimeState 的值为:{}", value);
                  if (value != null) {
                      ctx.deleteEventTimeTimer(value);
                      ctx.getPartitionedState(triggerTimeStateDesc).clear();
                  }
              }
          }
      
    • 然后就是自定义的窗口函数 MyProcessWindowFunction,这里用的是全量聚合函数,大家可以根据实际需求自定选择增量聚合函数还是全量聚合函数。这里用了一个简单的逻辑:就是求温度的平均值,具体这里的逻辑是什么,按大家实际需求来即可。

      // 全量聚合求平均
      static class MyProcessWindowFunction extends ProcessWindowFunction<SensorReading, Tuple2<String, Double>, String, TimeWindow> {
      
          /**
           * 窗口触发计算的时候调用的方法
           *
           * @param s
           * @param ctx
           * @param input
           * @param out
           * @throws Exception
           */
          @Override
          public void process(String s, Context ctx, Iterable<SensorReading> input, Collector<Tuple2<String, Double>> out) throws Exception {
              log.info("进入process方法,窗口开始时间:{},窗口结束时间:{}", ctx.window().getStart(), ctx.window().getEnd());
              List<SensorReading> list = Lists.newArrayList(input);
              int count = list.size();
              double sum = list.stream().mapToDouble(SensorReading::getTemperature).sum();
              out.collect(Tuple2.of(s, sum / count));
          }
      
          /**
           * 清除窗口所有状态
           *
           * @param context
           * @throws Exception
           */
          @Override
          public void clear(Context context) throws Exception {
              log.info("进去clear方法了");
              super.clear(context);
          }
      
      }
      

    这样的话,我们就实现了一个自定义的触发器。如果要做基于天维度的统计,而且需要实时展示结果的,就可以这样做,可以把触发时间改短即可。至于后续sink到redis的操作很简单,这里就不贴代码了,直接做了print打印到控制台。

    最后把演示截图发出来:

    • 首先输入三条数据:
      sensor_1,1547718209000,32.9
      sensor_1,1547718209500,33.1
      sensor_1,1547718216000,38.1
      运行结果如下:第一条数据来了注册一个触发器,时间是在34s,最后一条数据事件时间是36s,此时不会触发计算,因为水印线在34s(前面代码中设置了两秒的延迟),相同的况下是不会触发的,只有大于才会。
      在这里插入图片描述
    • 然后继续输入一条数据:sensor_1,1547718217000,38.1
      此时水印线上涨到 35s,触发器触发,截图如下:
      得到计算结果,正好4条数据得到的温度平均值是35.55.在这里插入图片描述
    • 继续输入一组数据:
      sensor_1,1547718220000,38.1
      sensor_1,1547718222000,38.1
      sensor_1,1547718225000,38.1
      sensor_1,1547718227000,38.1
      截图如下:也不会触发计算,但是之前触发器的触发时间已经归零并且重新设置了下一个触发时间。这样的话就可以循环往复直到窗口结束。
      在这里插入图片描述
    展开全文
  • 维度建模思想事数据仓库领域另一位大师 Ralph Kimball 所倡导,按照书中主要思想,维度建模并不要求维度建模满足三范式,数据库中强调3NF 主要是为了消除冗余。规范化 3NF 将数据划分为多不同实体,每实体...

    一、概述

    1、概念
    维度建模思想事数据仓库领域的另一位大师 Ralph Kimball 所倡导,按照书中主要思想,维度建模并不要求维度建模满足三范式,数据库中强调3NF 主要是为了消除冗余。规范化的 3NF 将数据划分为多个不同的实体,每个实体构成一个关系表。比如说订单数据库,开始可能是每个订单中的一行表示一条记录,到后来为了满足3NF会变成类似蜘蛛网状图。也许会包含上百个规范化表。而且对于BI查询来讲,规范化模型太复杂,用户会难以理解这些记录和模型的使用。而且维度建模解决了模型过于复杂的问题。

    维度是维度建模的基础和灵魂。在维度建模中,将度量称为“事实”将环境描述为“维度”,而维度所包含的表示维度的列,我们称之为维度属性。维度属性事查询约束条件、分组和报表标签生成的基本来源,是数据易用性的关键。(。例如,在查询请求中,获取某类目的商品、正常状态的商品等,是通过约束商
    品类目属性和商品状态属性来实现的;统计淘宝不同商品类目的每日成交金额,是通过商品维度的类目属性进行分组的)

    2、维度和维度属性的获取
    **维度使用主键标志其唯一性,**再维度建模过程中主键有两种:代理键和自然键,它们都是用于标识某维度的具体值。但代理键是不具有业务含义的键, 般用于处理缓慢变化维;自然键是具有业务含义的键。比如商品,(在在 ETL程中,对于商品维表的每一行,可以生成一个唯一的代理键与之对应;商品本身的自然键可能是商品 ID 等。其实对于前台应用系统来说,商品ID 是代理键:而对于数据仓库系统来说,商品 ID 则属于自然键)
    而维度和维度属性的获取一般我们可以通过报表中,也可以通过业务分析中按照by 分组的语句中获得到。

    3、维度基本设计方法
    维度的设计过程就是确定维度属性的过程,如何生成维度属性,以及所生成的维度属性的优劣,决定了维度使用的方便性,成为数据仓库易用性的关键。
    第一步:**选择维度或新建维度,作为维度建模的核心,在企业级数据仓库中必须保证维度的唯一性。以电商商品维度为例,有且只允许有一个维度定义。
    第二步 确定主维表。此处的主维表一般是 ODS 表,直接与业务系统同步。以电商商品维度为例, 一般会同步前台商品中心系统同步的商品表,此表即是主维表。
    第三步
    :确定相关维表。**数据仓库是业务源系统的数据整合,不同业务系统或者同 业务系统中的表之间存在关联性。商品维度为例,根据对业务逻辑的梳理,可以得到商品与类目、 SPU 卖家、店铺等维度存在关联关系。
    第四步 **:确定维度属性。**本步骤主要包括两个阶段,第一个步骤是从主维表中选择维度属性或生成新的维度属性;第二个阶段是从相关维表中选择维度属性或产生新的维度属性。同样以商品维度为例子。从
    主维表 和类目、 SPU 、卖家、店铺等相关维表中选择维度属性或生成新的维度属性。

    注意:确定维度属性的几点提示:
    (1)、尽可能生成丰富的维度属性。
    比如淘宝商品维度有近百个维度属性,为下游的数据统计、分析、探查提供了良好的基础。
    (2)、尽可能多地给出包括一些富有意义的文字性描述
    属性不应该是编码,而应该是真正的文字。如在一般维度建模中,要求是编码和文字同时存在,比如商品维度中的商品 ID 和商品标题、类目 ID 类目名称等。 ID 般用于不同表之间的关联,而名称一般用于报表标签。
    (3)、区分数值型属性和事实
    数值型宇段是作为事实还是维度属性,可以参考字段的一般用途。如果通常用于查询约束条件或分组统计,则是作为维度属性;如果通常用于参与度量的计算, 则是作为事实。比如商品价格,可以用于查询约束条件或统计价格区间 的商品数量,此时是作为维度属性使用的;也可以用于统计某类目 下商品的平均价格,此时是作为事实使用的。
    (4)、尽量沉淀出通用的维度属性
    有些维度属性获取需要进行比较复杂的逻辑处理,需要将尽可能多的通用的维度属性进行沉淀。一方面,可以提高下游使用的方便性,减少复杂度;另 一方面,可以避免下游使用解析时由于各自逻辑不同而导致口径不一致。(有些需要通过多表关联得到,或者通过单表的不同宇段混合处理得到,或者通过对单表的某个字段进行解析得到。)例如淘宝的例子,中商品是否在线就需要我们对数据进行加工处理。(商品状态为0和1且商品上架时间小于或等于当前时间,则为在线商品;否则是非在商品。所以需要封装商品是否在线的逻辑作为 个单独的属性字段。)

    4、维度设计之维度的层次
    维度中的一些描述属性以层次的方式或一对多的方式相关关联,可以被理解未包含连续的主从关系的属性层次。层次的最底层电表维度中描述的最低级别的详细信息,最高层代表最高级别的概要信息。维度常常有多个这样的嵌入式的层次结构。(例如:淘宝商品维度,有卖家、类目、品牌等。商品属于类目,类目属于行业,其中类目的最低级别是叶子类目,叶子类目属于二级类目,二级类目属于一级类目。)

    在属性的层次结构中进行钻取是数据钻取的方法之一。(例如:已有一个淘宝交易订单,创建事实表现在统计下单GMV,得到一行记录;沿着层次向下钻取,添加行业,等到行业实例个数的记录数;继续沿着层次向下钻取,添加行业。等到行业实例个数的记录数;继续向下钻取,添加一级类目。等到一级类目实例个数的记录数。可以看到,通过向报表中添加连续的维度细节级别,实现层次结构中进行钻取)

    5、规范化和反规范化
    与范化处理相对应的是反规范化。其反规范化的意思是经维度属性的多个层次合并到单个维度中。而我们一般在范化处理(一般采用雪花模型)中,用户在统计分析过程中需要大量的关联操作,使用复杂度较高,查询麻烦且性能很差;而我们采用反规范化的处理则方便、易用且性能好。对于例子中,如果采用反规范化处理,将表现为
    在这里插入图片描述

    综上:从用户角度来看简化了模型,并且使数据库查询优化器的连接路径比完全规范化的模型简化许多。反规范化的维度仍包含与规范化模型同样的信息和关系,从分析角度来看,没有丢失任何信息,但
    复杂性降低了。

    6、一致性维度和交叉探查**(统一维度的方式)**
    数据仓库总线架构的重要基石之一是一致性维度。在针对不同数据域进行迭代构建或并行构建时。存在很多需求是对于不同数据域的业务过程或同一个数据域的业务工程合并在一起观察的。比如对于日志域中,统计了商品维度的最近一天的PV和UV;对于交易数据域,统计了商品尾端的最近一天的PV和UV;对于纪要数据域,统计了商品维度最近一天的下单GMV。现在将不同数据域的上坪事实合并在疫情精选数据探查,如计算转化率,称职位交叉探查。

    如果不同数据域的计算过程使用的维度不 致,就会导致交叉探查存在 问题 当存在 复的维度,但维度属性或维度属性 值不 致时,会导 叉探查无法进行或 叉探查结果错误。接上个例子,假设对于日志数据域,统计使用的是商品维度 ;对于交易数据域,统计使用的是商品维度 商品维度 包含维度属性 类型 而商品维度2无此属性,则无法在 BC 类型上进行交叉探查;商品维度 的商品上架时间这一维度属性时间格式是 yyyy-MM-dd HH:mm:ss ,商品维度 的商品上架时间这一维度属性时间格式是 UNIX timestamp ,进行交叉探查时如果需要根据商品上架时间做限制,则复杂性较高;商品维度 不包阿里旅行的商品,商品维度 包含全部的淘系商品,交叉探查也无法进行。还有很多种形式的不一致,这里不再一一列举,但基本可以划分为维度格式和内容不一致两种类型。

    上面对维度不一致性进行了详细分析,下面总结维度一致性的几种表现形式。
    1)、共享维表。 比如在的数据仓库中,商品、卖家、买家、类目等维度有且只有一个。所以基于这些公共维度进行的交叉探查不会存在任何问题。
    2)、一致性上卷,其中一个维度的维度属性是另 一个维度的维度属性的子集,且两个维度的公共维度属性结构和内容相同,比如在商品体系中,有商品维度和类目维度,其中类目维度的维度属性是商品维度的维度属性的子集,且有相同的维度属性和维度属性值。这样基于类目维度进行不同业务过程的交叉探查也不会存在任何问题。
    3)、交叉属性 :,两个维度具有部分相同的维度属性。比如在商品维度中具有类目属性,在卖家维度中具有主营类目属性,两个维度具有相同的类目属性,则可以在相同的类目属性上进行不同业务过程的交叉探查。

    展开全文
  • 不知不觉就毕业这么多年了,年前...下面给大家我将从做事、学习、架构师三个维度给大家分享一下自己心得。 一、做事 1.1 心态 首先先来说说工作中,如何做事比较好。在职场中有形形色色人,他们对工作.

    不知不觉就毕业这么多年了,年前的时候就想总结一下自己的工作心得,复盘一下自己的工作学习之旅,但是最近因为忙于工作,抽不出时间来写这篇文章。

    通过这么多年的工作,java生态圈或多或少都有用过或者接触过。小程序、前端、运维也都会涉及到一些。毕竟不同的公司对员工要求也会不一样,大公司可能专精一项就可以了,小公司可能就要做全栈开发。下面给大家我将从做事、学习、架构师三个维度给大家分享一下自己的心得。

    图片

    一、做事

    1.1 心态

    首先先来说说工作中,如何做事比较好。在职场中有形形色色的人,他们对工作的看法截然不同,有些人认为工作只是一份工作,我只是在这里打工的,上班摸摸鱼到点下班就可以了,然后就这样日复一日。有些人认为工作是积累自己能力和人脉的关键场所,会想方设法的做到最好,尽最大可能提升自己。

    因为选择的不同,最后结果也必然不近相同,我面试过的人中就有一些就是这样的,5年工作经验以上,但还是停留在业务的增删改查上面,对技术没有深入的掌握,技术的广度也没有得到提升,然后又想拿高工资。人家企业也不是冤大头,结果肯定是被pass掉的。

    1.2 方法

    工作态度转变之后,我们还需要讲究工作的方法,我见过很多人,工作做事都非常认真,天天加班,也非常负责,但是做事的结果却不尽人意。你说他也不是,不说他也不是,人家确实很努力的工作了,但是结果总是不尽人意。

    这类人我认为一定要深度的剖析自己内部原因,追寻最本质的原因。是因为自己能力不够胜任这个岗位,还是做事的方法上面欠缺思考呢?千万不要抱着自己都这么努力的工作了,大家为啥还这么苛责我的想法。公司作为一个盈利机构,都是以目标为导向的,虽然你加班到深夜,但是你的结果是不好的。那公司宁愿要不加班,可以按时处理好事情的人。所以一定要摆正好心态,积极的去寻找原因。

    1.3 细则

    做事要讲究有始有终,每一件任务都会有周期,做事的原则其实就是在规定的周期内把事情做好就可以了。当然这里面的水很深,我这边就总结几点:

    • 一件任务安排下来,你一定要清楚自己做什么,不清楚就找能问清楚的人确定清楚。

    • 任务确定好之后,要分解任务,作为开发人员,我认为任务可以被分解为接口级别,如果能分解到这一级别,我相信你对需求已经理解的差不多了,最后还需要将流程和上级捋清楚,千万不要什么都没确定就开始写代码,到时候发现自己写的代码都是错的,那就凉凉了。

    • 任务开发过程如果有问题,也不要啥问题都问别人,这样会让人觉得你很弱智,问问题都没经过大脑。最好的问问题的过程是带着自己的看法问问题的,而且至少要自己尝试过解决问题才可以,这样人家才愿意跟你深入的沟通。

    • 任务开发完成要发布上线之前,一定要进行反馈,特别是新员工,不了解当前公司的运作模式,就沿用之前公司的习惯,脑子一热就上线了,那后果有时候可能跟核弹一样。

    • 任务全部完成之后,一定要记得复盘,复盘自己整个过程中遇到的问题和当前模式可能存在的隐患,后面要如何进行优化,这些都要文档化。相信我,几个月过去之后,你可能自己也看不懂自己的代码。

    1.4 责任

    作为开发,不可避免会遇到线上紧急情况,最难受的是,这个紧急情况出现在凌晨,也就是你在呼呼大睡的时候,这个时候如果你收到报警,一定要起床修复。千万不要睡时一时爽,上班被开除。这个其实是责任心问题,任何一家公司都不会要没有责任心的人,越是身居高位,越是会看重这个,这也是别人通常说的这人靠谱不靠谱。

    1.5 小结

    做事就分享到这边,这边就不展开了,每个人都有自己的做事的风格,但优秀的人一般都具备上面几点,毕竟如果连事情都做不好,再优秀也没人敢用你。还有最重要的一点,做事情一定要给自己留一条后路,每次上线之前一定要想一下最严重的后果是啥,是否可以快速回滚之前的版本,这样才能稳如泰山。

    二、学习

    关于学习部分,作为程序猿,大家都会收到来自各大公众号传播的焦虑,例如人到中年被离职、Java未来还有前景嘛,我是如何做年入30+之类的软文,点进去一看发现都是培训广告。

    其实每一行都会有这样的压力的,因为随着年龄的增大,身上的责任也会越来越重,对收入要求也会有更高的追求,但是高薪岗位就那么多,老板们也不是傻子,他们只能把钱给具有对应价值的人。所以唯有时刻学习,让自己持续成成长,未来才不会被淘汰。

    2.1 提升认知:

    这就涉及到如何学习的问题,刚工作的时候,可能是认知不够完善,一直都在学习各个框架技术如何使用,也就是所谓搭框架的级别,认为把springcloud所涉及到的启动起来就很牛逼了,后面才发现这只能浮于表面,简单的来说,这种大家看个视频边学边做,谁都可以弄出来,没啥竞争优势。

    后面意识到自身的不足的时候,就渐渐的开始学习spring、mybatis、jdk等这些优秀框架的源码,当然说是学习,其实就是简单了解一下他们的实现原理,还远远没有到掌握的地步。通过学习这些源码之后,程序在运行过程中,如果出现bug,可以有效的提高查找bug的效率。毕竟你连框架的根都知道了,剩下的就是业务性问题了。

    2.2 持续学习

    关于如何学习这些框架,我建议大家可以先看书,第一遍可以不求甚解,先知道这个框架模块分为哪些,然后再深入研究自己感兴趣的部分,不然很快可能就散失继续学习的兴趣了。

    随着项目不断升级迭代,我愈发觉得java生态圈本身的技术已经不足以支持处理问题的能力,首先项目是运行在linux程序上面的,你要了解linux操作系统相关原理,其次服务肯定要进行网络交互,这就会涉及到计算机网络的内容,甚至还需要知道编译原理的内容。

    软件说白了就是一堆程序+数据运行起来的结果,所以都绕不开数据库这个层面,数据库的优化那又是一门大学问了。所以如果说程序猿是吃年轻饭的,那肯定最简单的应用发开,如果一个人想精通Java、操作系统、计算机网络、编译原理、算法、数据库、框架等相关内容,没有个十来年基本不可能。

    2.3 小结

    大家要牢记一点,经验并不是凭空产生的,一定要找一份可以给你不断成长的工作,虽然你可以自学技术,但是如果这些技术没有落地实施,过几天就忘记了,我的建议是:可以和工作相结合那是最好的,跟着项目一起成长,不断迭代,这样的技术才是最踏实的。

    三、架构师

    如果大家想往架构师层面发展的话,那就不能仅仅只知道java层面的内容,而且还不能仅仅只知道后端,我认为一个优秀的架构师应该懂得后端、前端、运维、产品等相关知识。这边为什么要加上产品呢,因为产品的功能直接影响底层设计,就比如秒杀系统,对一名架构师的挑战那可是相当大。但是这边不对产品进行扩展,毕竟博主本人对这方面也不是很精通,就不班门弄斧了。

    3.1 所需技能

    如果想成为架构师,对后端的技术就不能仅限于了解,至少要熟悉掌握相关技能。这边说的后端不仅仅是java本身,包含编程语言、框架、大数据技术、数据库、分布式、微服务等、操作系统、计算机网络、jvm虚拟机、算法、数学、计算机组成原理、软件工程、设计模式等。

    3.2 能力要求

    各个公司对架构师的要求也不近相同,但是有几点是共通的,架构师一定是解决问题能力最强的那个人,可以根据当前用户和未来用户对系统的负载进行估算,进而对系统进行调整,保证系统持续性稳定和高可用。

    简单的来说,比如线上的服务需要部署多少的实例、每台服务器的带宽要设置多少、要设置哪些维度的报警、系统出现问题的时候如何第一时间发现、系统出现严重问题如何快速恢复,这些都需要关注。所以架构师对技术的要求会相对更高,而且是站在整个系统的角度来要求的。

    3.3 沟通

    很多时候架构师面对的都是方方面面的问题和人,沟通也是一项重要的技能,如果只会闷头研究技术不懂得产品或者需求中隐晦的技术要求,也做不好架构师。当然并不是说你要像销售一样,能吹牛逼,至少你要能理解对方的问题,懂得将问题归纳总结为你需求点,然后进行分析设计。

    四、总结

    通过从做事、学习、成为架构师三个方面,复盘了自己这几年来的工作,发现了很多问题,一路走了很多的坑。现在回想刚工作那一两年,感觉浪费了很多时间,自己的认知、技术、学习、做事都没能走上正轨。希望通过我复盘,能对大家有所启发。

    当然每个人经历不一样,自身的认知也不一样,如果大家觉得有道理,能吸取一点经验就点个赞,如果觉得接受不了,也没事,毕竟我没有你的人生阅历,只希望大家以后可以越来优秀,加油!

    -----------------------

    公众号:林老师带你学编程

    网站:www.wolzq.com

    代码无非增删改查,关注老师给你Coding

    图片

    林老师带你学编程http://www.wolzq.com 

    展开全文
  • 我们通过证明上述在测地体积图上的总和是具有正确边界条件的共形Casimir算子的适当本征函数来证明我们的要求。 该结果基于从Bruhat-Tits树上建立的问题的简单得多的p-adic版本获得的关键灵感。
  • 汽车行业物料管理重点在于准确及时地将物料配送到指定工位,通过加快周转速度,降低资金占用,达到整个...我在文章(ERP系统工厂物流管理)中描述过物料流动个维度:质量、位置 、成本。那么我就从这三个...
  • 首先要求的个维度是城市+关键字 -&gt; 根据城市和关键字分组求出数量 2.要找到前输出,想到ROW_NUMBER() 开窗函数实现如下:select city,keyss,ROW_NUMBER() OVER(partition by city order by count(*) ...
  • 王颖—《从五感到无感》 高端服务礼仪五部曲 【课程背景】 在服务场合中,如何打造亲和、精致、精准高端服务,如何按照全球主流高端服务趋势及要求彰显企业服务品牌,有效将企业文化...触觉五个维度全方位出发,制
  • 1.关联容器  关联容器中元素时按照关键字来保存和访问,与之相对,...三个维度上: 或是一个 map 或是一个 set 或者要求不重复关键字,或者允许重复关键字 按顺序保存元素,或无序保存 ...
  • 共形异常边界项

    2020-03-28 11:20:02
    我们分析了在具有边界流形上整合共形异常中边界项结构。 我们建议,Weyl张量中多项式B型异常与Gibbons-Hawking类型边界项相伴。 它们形式是由要求它们产生一个变化量... 这些术语分为三个维度和五个维度
  • NumPy 广播(Broadcast) 广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。...这要求维数相同,且各维度的长度相同。 import numpy as np ...
  • 转载请注明出处  在卷积神经网络中,卷积层之间往往会加上一池化层。池化层可以非常有效地缩小参数矩阵尺寸,从而减少最后全连层中参数...池化在每一纵深维度上独自完成,因此图像纵深保持不变。池...
  • 标准库提供8个关联容器,体现在三个维度: 1,或者是一个set,或者是一个map,map、set有序关键字不可重复 2,或者要求不重复关键字,或者允许重复关键字,multimap、multiset有序关键字可重复 3,按顺序保存或无序...
  • 1. (一)、确定主题 2. 即确定数据分析或前端展现的主题。例如:我们希望分析某年某...我们将通过维度的组合,来考察量度。那么,“某年某月某一地区的啤酒销售情况”这样一主题,就要求我们通过时间和
  • PART 5 多维数据透视分析...星型模式:由一事实表和一组维度表组成,维度表只和事实表关联,维度表之间没有关联,以事实表为核心,维度表围绕核心呈星形分布。 订单表、产品表与客户表:一事实表连接两维...
  • 系列是一个一维数组,只有一个维度(或称作轴)是行(row),在访问系列时,只需要设置一个索引。pandas自动为系列创建了一个从0开始到N-1序号,称作行下标,行位置。可以显式设置index参数,为每行设置标签,...
  • 个人经常调侃SQL思考问题比大部分流行开发语言多一个维度,因为SQL主要是二维思考(集合)、区别于一维(数据结构)思维方式。对于ORACLE,通过以SQL(相对宏观)为主体、PLSQL(微观)为辅助,注入算法(灵魂)...
  • 对于带电GB-AdS黑洞,表明在五个维度上只有一个临界点(对于具有球形或双曲线拓扑黑洞),这也要求电荷限制在某个合适范围内。 而在d> 5维中,相同电荷最多可以有两个不同临界点,并且相变仅在不位于两个...
  • 高保真原型特点

    2017-06-07 09:53:00
    一、维度:高保真原型可以在以下五个维度进行考虑和评估  1、完整性:主要指业务和功能方面;  2、准确性:数据量,文案描述  3、操作:原型跳转和亮点  4、易用性:看起来清晰,操作链条简单  5、...
  • 本文来自于weixin,文章主要从数据分布地图、数据分类、数据管控、数据平台四个维度来看待如何满足智能工厂级建设要求的数据在哪、如何分类、如何管控、用什么管控平台?等知识。 能源化工集团企业信息化建设要...
  • 但是GPS坐标在后续(地理位置维度分析)分析中不好使用!直接去匹配两哪怕距离很近gps坐标,很可能都匹配不上!gps坐标匹配,不应该做这种精确匹配,应该做范围匹配;公司通过某渠道,收集到一批地理位置...
  • 五个维度来谈谈视觉设计师如何阐述设计风格。 设计风格是一种很虚东西,对于大部分 UI 设计师来说,都是如此。 相信很多人都是在一家小型互联网公司做设计,估计还是公司唯一...
  • 一、引言: 作为一名大三学生,找实习对于我们而言是迫在眉睫。...我从实习僧网站爬取了5000条全国互联网行业职位信息(时间节点06/17),下面开始从职位、薪资、地点、时长、工作要求五个维度进行分析。 ...
  • 五个维度来谈谈视觉设计师如何阐述设计风格。设计风格是一种很虚东西,对于大部分 UI 设计师来说,都是如此。相信很多人都是在一家小型互联网公司做设计,估计还是公司唯一设计师,同时对设计风格又拿捏...
  • 协同和分布式的网络攻击对传统的网络安全防护提出了巨大的挑战,同时也对分布式入侵检测技术提出了更高的要求,而有效融合多种入侵检测系统报警信息能够提高告警的准确性。首先给出了五维度报警信息关联的定义;然后...
  • COVID Android应用观察器 与COVID相关Android应用网页抓取工具和分析器 什么事啊 为了简化对COVID-19跟踪并告知人们与该... 您可以想象,我们为每个维度收集了多个数据点,因此,对我们提供信息有个最好
  • 一、前言二、数据仓库的定义三、数据仓库的特点四、数据仓库的作用、数据仓库的架构六、数据仓库的要求七 、数据仓库分层八、数据仓库四层次的划分8.1 ODS层8.2 PDW层8.3 APP层 九、数据流向十、数据仓库模型...

空空如也

空空如也

1 2 3 4 5
收藏数 90
精华内容 36
关键字:

五个维度的要求