精华内容
下载资源
问答
  • 零件加工一致性评价技术,宋忠伟,陶桂宝,本文针对我国机床加工精度保持性差、可靠性不高等问题,提出了加工相对一致性和绝对一致性相关概念。首先从几何精度(包括尺寸
  • 5.失真-均匀性-一致性交互-瑕疵检测 6.SFR–查找最清晰文件–Batchview–MTF比较–OIS/图像比较–倾斜边缘算法–锐度/SQF 7.分辨率测试:SFR——星图——对数频率——对数F——对比度——随机(溢出硬币等)——...

    1.图像质量概念:清晰度(sharpness)、锐化(sharpening)、噪声-原始转换

    清晰度(sharpness)在边缘等特征上最为明显。它可以通过边缘(阶跃)响应来测量。

    成像系统的每个组件都会影响整个系统的响应(通常会降低清晰度)

    注:图像分析可以分为空间域与频域。通过在频域中描述成像系统的性能,可以更容易地描述和可视化成像系统的性能。复合信号(音频或图像)可以通过组合由正弦波组成的信号(以周期或频率为特征)来创建。高频对应于精细的细节。系统在高频(短周期)下的响应越好,系统可以传达的细节就越多。

    SFR (Spatial Frequency Response) 空间频率响应和MTF (Modulation Transfer Function) 调制传递函数是测量清晰度(sharpness)的关键。

    清晰度(sharpness)总结:

    •清晰度在边缘等特征上最为明显,它是重要的。但在细纹理(树叶,皮肤等)不太明显

    •清晰度可从以下几种图案中测量,对于线性系统,所有的结果都是相似的。


    •许多成像系统都是高度非线性的(处理随图像内容而变化;边缘的行为与纹理不同),因此通常需要多张图表来表征一个系统。
    •具有1/f频谱(*)的图表具有标度不变性,这使得测量非常方便:如果图表频谱和比例已知,则MTF计算非常简单。

    锐化(hsarpening)影响MTF测量–提高图像清晰度;大多数数码相机的图像看起来柔和而不锐化。所有的数字图像都能从锐化中受益,但过多的锐化会降低图像的质量;Raw格式图像没有锐化,但锐化应用于几乎所有的数字图像-在相机,Raw转换,或图像编辑器。锐化的操作就是从每个像素中减去一小部分相邻像素,使产生的信号更加清晰,提高高空间频率下的对比度(也提高MTF50),数量取决于锐化分数和半径。锐化传递函数:

    由于锐化对MTF有很强的影响,因此需要一个基于锐化的度量(过锐化、过冲等)来充分表征MTF响应。反锐化掩模(USM)是一种替代算法:从原始边缘的高斯模糊副本中减去一小部分。过度锐化会增加可见噪声,当MTF和信噪比(SNR)的频率被强烈增强时,会降低外观。

    噪声(noise):•信号电平的随机扰动。•薄膜严重退化。•以RMS(均方根)电压测量,与标准偏差σ相同。•噪声具有频谱。•噪声在平滑区域(如天空)最为明显,通常采用降噪(NR=低通滤波,即高频衰减;与锐化正好相反)。•低通滤波模糊边缘。•为了在保持边缘质量的同时降低噪声,经常采用非线性、非均匀的双边滤波器。图像处理在不同的位置是不同的!锐化(高频增强)是最强的边缘附近,而噪音降低(高频切割)是最强的远离边缘。

    2.图像质量因子

    • 锐度
    • 横向色差
    • 噪声
    • 颜色精度
    • 色调响应与对比
    • 动态范围
    • 曝光精度
    • 光衰减
    • 透镜畸变
    • 感光度
    展开全文
  • 提出一个用于信息系统综合评价的数学模型,该模型能够适应对各评价对象进行评价的专家数目不一致,或参与评价某对象各指标的专家数目不一致的情况;同时,模型中引入了...
  • 个人网站 www.HelloDBA.com研究背景实际上,我们所说的保证同一时间点一致性的概念,其背后是物理层面的 block 读,Oracle 会依据你发出 select 命令,记录下那一刻的 SCN 值,然后以这个 SCN 值去同所读的每个 ...
        

    640?wx_fmt=gif&wxfrom=5&wx_lazy=1


    作者简介

    640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1黄玮(Fuyuncat)

    资深 Oracle DBA,致力于数据库底层技术的研究,其作品获得广大同行的高度评价。

    个人网站 www.HelloDBA.com


    研究背景

    640?wx_fmt=png&wxfrom=5&wx_lazy=1

    640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1


    实际上,我们所说的保证同一时间点一致性读的概念,其背后是物理层面的 block 读,Oracle 会依据你发出 select 命令,记录下那一刻的 SCN 值,然后以这个 SCN 值去同所读的每个 block 上的 SCN 比较,如果读到的块上的 SCN 大于 select 发出时记录的 SCN,则需要利用 Undo 得到该 block 的前镜像,在内存中构造 CR 块(Consistent Read)。


    一致性读(Consistent Gets,CG)是反映 SQL 语句性能的一项重要数据。它通常作为我们语句调优的指标。一般情况下,通过该数据可以比较两条语句或者同一语句的不同执行计划之间的性能。然而,某些情况下,它并不会完全反映出语句的性能。


    分析探讨

    640?wx_fmt=png

    我们先看两份性能统计数据:


    SQL代码

    SQL 1:  

    Statistics  

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

              0  recursive calls  

              0  db block gets  

            460  consistent gets  

              0  physical reads  

              0  redo size  

        1203583  bytes sent via SQL*Net to client  

           3868  bytes received via SQL*Net from client  

            306  SQL*Net roundtrips to/from client  

              0  sorts (memory)  

              0  sorts (disk)  

           4563  rows processed  

    SQL 2:  

    Statistics  

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

              0  recursive calls  

              0  db block gets  

            167  consistent gets  

              0  physical reads  

              0  redo size  

         267325  bytes sent via SQL*Net to client  

           3868  bytes received via SQL*Net from client  

            306  SQL*Net roundtrips to/from client  

              1  sorts (memory)  

              0  sorts (disk)  

           4563  rows processed  


    可以看到,第一条语句的 CG 是第二条语句的近3倍,看起来应该是第二条语句的性能更好。是否真是如此?


    那再看看这两条语句是如何构造执行的:


    SQL代码

    HelloDBA.COM> create table t1 as select * from dba_tables;    

    Table created.    

    HelloDBA.COM> create table t2 as select * from dba_users;    

    Table created.   

    HelloDBA.COM> exec dbms_stats.gather_table_stats('DEMO''T1');    

    PL/SQL procedure successfully completed.   

    HelloDBA.COM> exec dbms_stats.gather_table_stats('DEMO''T2');    

    PL/SQL procedure successfully completed.   

    HelloDBA.COM> set timing on  

    HelloDBA.COM> set autot trace  

    HelloDBA.COM> select * from t1;    

    4563 rows selected.   

    Elapsed: 00:00:00.10    

    Execution Plan  

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

    Plan hash value: 3617692013    

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

    | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |  

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

    |   0 | SELECT STATEMENT  |      |  4563 |  1078K|    49   (0)| 00:00:01 |  

    |   1 |  TABLE ACCESS FULL| T1   |  4563 |  1078K|    49   (0)| 00:00:01 |  

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

    Statistics  

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

              0  recursive calls  

              0  db block gets  

            460  consistent gets  

              0  physical reads  

              0  redo size  

        1203583  bytes sent via SQL*Net to client  

           3868  bytes received via SQL*Net from client  

            306  SQL*Net roundtrips to/from client  

              0  sorts (memory)  

              0  sorts (disk)  

           4563  rows processed    

    HelloDBA.COM> select * from t1, t2 where t2.username='SYS';    

    4563 rows selected.   

    Elapsed: 00:00:00.23    

    Execution Plan  

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

    Plan hash value: 1323614827    

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

    | Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |  

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

    |   0 | SELECT STATEMENT     |      |  4563 |  1581K|    52   (0)| 00:00:01 |  

    |   1 |  MERGE JOIN CARTESIAN|      |  4563 |  1581K|    52   (0)| 00:00:01 |  

    |*  2 |   TABLE ACCESS FULL  | T2   |     1 |   113 |     3   (0)| 00:00:01 |  

    |   3 |   BUFFER SORT        |      |  4563 |  1078K|    49   (0)| 00:00:01 |  

    |   4 |    TABLE ACCESS FULL | T1   |  4563 |  1078K|    49   (0)| 00:00:01 |  

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

    Predicate Information (identified by operation id):  

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

       2 - filter("T2"."USERNAME"='SYS')    

    Statistics  

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

              0  recursive calls  

              0  db block gets  

            167  consistent gets  

              0  physical reads  

              0  redo size  

         267325  bytes sent via SQL*Net to client  

           3868  bytes received via SQL*Net from client  

            306  SQL*Net roundtrips to/from client  

              1  sorts (memory)  

              0  sorts (disk)  

           4563  rows processed  


    这两条语句并不复杂。如果我们忽略性能统计数据,我们很容易就从其语句逻辑结构或者执行计划判断出它们的性能谁优谁劣。


    但是为什么第二条语句的 CG 更少呢?


    我们对它们作 SQL 运行跟踪,再看格式化的跟踪结果:


    SQL代码

    Rows (1st) Rows (avgRows (max)  Row Source Operation  

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

          4563       4563       4563  MERGE JOIN CARTESIAN (cr=167 pr=0 pw=0 time=38433 us cost=52 size=1619865 card=4563)  

             1          1          1   TABLE ACCESS FULL T2 (cr=3 pr=0 pw=0 time=78 us cost=3 size=113 card=1)  

          4563       4563       4563   BUFFER SORT (cr=164 pr=0 pw=0 time=22958 us cost=49 size=1104246 card=4563)  

          4563       4563       4563    TABLE ACCESS FULL T1 (cr=164 pr=0 pw=0 time=11815 us cost=49 size=1104246 card=4563)   


    这是第二条语句的计划统计数据。显然,它包含两个部分:对 T1 和 T2 的全表扫描访问。


    在该执行计划当中,T1 的全表扫描的 CG 为 164,当时为什么在第一条语句中对其的全部扫描产生的 CG 为 466 呢?这是因为数据获取数组大小(fetch array size)设置的影响。


    如下,在 SQLPlus 当中,该设置默认值为15,如果我们将其设得足够大,CG 将变为165,没错。因为无论该数组大小设为多大,Oracle 总是在第一次读取时读取第一条记录。


    SQL代码

    HelloDBA.COM> set arraysize 5000  

    HelloDBA.COM> set autot trace stat  

    HelloDBA.COM> select * from t1;   

    Statistics  

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

              0  recursive calls  

              0  db block gets  

            165  consistent gets  

              0  physical reads  

              0  redo size  

        1147039  bytes sent via SQL*Net to client  

            524  bytes received via SQL*Net from client  

              2  SQL*Net roundtrips to/from client  

              0  sorts (memory)  

              0  sorts (disk)  

           4563  rows processed  


    关于全部扫描的 CG 可以参考该文章了解更多细节:http://www.hellodba.com/reader.php?ID=39&lang=EN


    F2 是一张小表,它的全表扫描访问产生的CG为3。


    写到这是否可以结束了呢?现在将第二条语句的过滤条件移除看看。


    SQL代码

    HelloDBA.COM> select * from t1, t2;    

    246402 rows selected.    

    Statistics  

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

              1  recursive calls  

              0  db block gets  

            219  consistent gets  

              0  physical reads  

              0  redo size  

       14113903  bytes sent via SQL*Net to client  

         181209  bytes received via SQL*Net from client  

          16428  SQL*Net roundtrips to/from client  

              1  sorts (memory)  

              0  sorts (disk)  

         246402  rows processed  


    仅仅 219 CG?这是一个笛卡尔乘积的关联(无关联条件),怎么会是如此少的 CG 呢?


    再次产生 SQL 跟踪文件:


    SQL代码

    Rows (1st) Rows (avgRows (max)  Row Source Operation  

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

        246402     246402     246402  MERGE JOIN CARTESIAN (cr=219 pr=0 pw=0 time=957833 us cost=2553 size=87472710 card=246402)  

            54         54         54   TABLE ACCESS FULL T2 (cr=55 pr=0 pw=0 time=728 us cost=3 size=6102 card=54)  

        246402     246402     246402   BUFFER SORT (cr=164 pr=0 pw=0 time=433549 us cost=2550 size=1104246 card=4563)  

          4563       4563       4563    TABLE ACCESS FULL T1 (cr=164 pr=0 pw=0 time=10674 us cost=47 size=1104246 card=4563)  


    T1 的全表扫描的 CG 并未变化,T2 的 CG 增加为 55。55 意味着什么?它是 T2 的数据记录数加一。


    SQL代码

    HelloDBA.COM> select count(*) from t2;    

      COUNT(*)  

    ----------  

            54  


    但是,笛卡尔乘积不是意味着 m×n 吗?为什么结果是 m+n?


    实际上,Oracle 确实对 T1 做了多次重复访问。不过,第一次访问后,读取到的数据被缓存到了私有工作区,接下来的访问就是从私有内存而非共享内存中读取数据。因此,这些访问就没有被记入 CG 当中。


    为了获取实际的访问次数,我们使用嵌套关联提示使其从共享内存中读取数据:


    SQL代码

    HelloDBA.COM> select /*+use_nl(t1) leading(t1)*/* from t1, t2;  

    246402 rows selected.   

    Elapsed: 00:00:07.43  

    Execution Plan  

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

    Plan hash value: 787647388  

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

    | Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |  

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

    |   0 | SELECT STATEMENT     |      |   246K|    83M|  5006   (1)| 00:01:01 |  

    |   1 |  MERGE JOIN CARTESIAN|      |   246K|    83M|  5006   (1)| 00:01:01 |  

    |   2 |   TABLE ACCESS FULL  | T1   |  4563 |  1078K|    49   (0)| 00:00:01 |  

    |   3 |   BUFFER SORT        |      |    54 |  6102 |  4956   (1)| 00:01:00 |  

    |   4 |    TABLE ACCESS FULL | T2   |    54 |  6102 |     1   (0)| 00:00:01 |  

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

    Statistics  

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

              0  recursive calls  

              0  db block gets  

           4568  consistent gets  

              0  physical reads  

              0  redo size  

       16632868  bytes sent via SQL*Net to client  

         181209  bytes received via SQL*Net from client  

          16428  SQL*Net roundtrips to/from client  

              1  sorts (memory)  

             0  sorts (disk)  

         246402  rows processed  


    尽管执行计划没有变化,但是 CG 的变化却相当明显。

    研究收获

    640?wx_fmt=png

    从这个例子中可以注意到两点:

    1. 数据获取数组大小会影响 CG;

    2. CG 仅包含从共享内存读取的次数;


    注:

    测试环境为: Oracle 11.2.0.3 on Oracle Linux 5 64bit


    资源下载

    关注公众号:数据和云(OraNews)回复关键字获取

    ‘2017DTC’,2017 DTC 大会 PPT

    ‘DBALIFE’,“DBA 的一天”海报

    ‘DBA04’,DBA 手记4 经典篇章电子书

    ‘RACV1’, RAC 系列课程视频及 PPT

    ‘122ARCH’,Oracle 12.2 体系结构图

    ‘2017OOW’,Oracle OpenWorld 资料

    ‘PRELECTION’,大讲堂讲师课程资料

    640?wx_fmt=png

    展开全文
  • 一致性哈希原理与应用

    千次阅读 2018-06-15 11:28:24
    概念百科释义一致性哈希算法简单来说就是一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用简 单哈希算法带来问题,使得分布式...

    概念

    百科释义

    一致性哈希算法简单来说就是一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。

    哈希算法评价标准

    在动态的缓存环境中,有下面这么几条标准,可以用来判断一个哈希算法的好坏。借用网上 一篇文章 对此的描述。

    • 平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
    • 单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
    • 分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
    • 负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同 的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。

    通用代码

    在正式解释一致性哈希算法之前,先贴一下待会要用到的通用的代码。

    constrants.py

    #coding: utf8
    servers = [
        "192.168.0.1:11211",
        "192.168.0.2:11211",
        "192.168.0.3:11211",
        "192.168.0.4:11211",
    ]
    
    entries = [
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
        "g",
        "h",
        "i",
        "j",
        "k",
        "l",
        "m",
        "n",
        "o",
        "p",
        "q",
        "r",
        "s",
        "t",
        "u",
        "v",
        "w",
        "x",
        "y",
        "z",
    ]

    func.py

    #coding: utf8
    
    from hashlib import md5
    
    def hashcode(key=""):
        if key == None or key == "":
            return 0
        return int(md5(str(key).encode('utf8')).hexdigest(), 16)
    
    
    def print_pretty_list(ls=[]):
        for item in ls:
            print(item)
    
    def print_pretty_dict(dc={}):
        for key, value in dc.items():
            print(f'{key}: {value}')
    
    def compute_cache_percentage(oldcache, newcache):
        result = {key: 0 for key in oldcache.keys()}
        for key, value in oldcache.items():
            if key in newcache.keys():
                result[key] = len(list(set(value).intersection(set(newcache[key]))))
        return result
    
    def get_map_list_key(maplist):
        result = []
        for map in maplist:
            result.extend(map.keys())
        return result
    
    def compute_cache_percentage_ring(oldcache, newcache):
        result = {key: 0 for key in oldcache.keys()}
        # 这里每一个value其实都是一个装了字典map的列表
        for node, maplist in oldcache.items():
            if node in newcache.keys():
                oldkeys = get_map_list_key(maplist)
                newkeys = get_map_list_key(newcache[node])
                result[node] = len(list(set(oldkeys).intersection(set(newkeys))))
        return result
    
    def compute_cache_percentage_virtual_ring(oldcache, newcache):
        result = {key.split("#")[0]: 0 for key in oldcache.keys()}
        # 这里每一个value其实都是一个装了字典map的列表
        for node, maplist in oldcache.items():
            if node in newcache.keys():
                oldkeys = get_map_list_key(maplist)
                newkeys = get_map_list_key(newcache[node])
                temp = str(node).split("#")[0]
                result[temp] += len(list(set(oldkeys).intersection(set(newkeys))))
        return result

    硬哈希

    硬哈希,一般又被称为普通哈希。其原理较为简单,当然实现方式也多种多样。比如取余数法等。单调性也能很好的满足。

    硬哈希在缓存服务的适用场景一般是缓存环境不怎么发生变化,对于缓存服务器群的稳定性要求较高。一旦服务器群出现故障,就有可能导致井喷现象,出现缓存服务瞬间崩溃。这么说可能不太容易理解,下面举个通俗点的例子。

    张大胖负责维护公司的缓存服务群,手里现在有10台机器,每台服务器的内存使用率都达到了95%, 而且老板还贼抠,就是不给配新机器。这天,实习生小李写了个日志分析的脚本,没有考虑到目前服务器内存已然吃紧的现状,就直接执行了。结果第三台服务器出现了严重的Out Of Memory问题,导致服务器直接死掉了。然后缓存数据直接全部丢失。这个时候原本的10台服务器,变成了9台。原本可以命中的缓存内容这下都失效了。导致了缓存服务被迫更新,瞬间服务器压力都上来了。不仅缓存服务器挂了,后台的MySQL服务器也撑不住这么大规模的请求啊,公司的整个业务线都陷入了瘫痪的状态。

    简易实现硬哈希 hard-hash.py

    # coding: utf8
    from hashlib import *
    from constraints import servers, entries
    from func import *
    length = len(servers)
    details1 = {key:[] for key in servers}
    for entry in entries:
        # keyhash = sum([ord(c) for c in entry])
        keyhash = hashcode(entry)
        server = servers[keyhash%length]
        details1[server].append(entry)
    print_pretty_dict(details1)
    
    print("---"*28)
    del servers[0]
    length = len(servers)
    details2 = {key:[] for key in servers}
    for entry in entries:
        # keyhash = sum([ord(c) for c in entry])
        keyhash = hashcode(entry)
        server = servers[keyhash%length]
        details2[server].append(entry)
    print_pretty_dict(details2)
    
    print("---"*28)
    servers.insert(0, "192.168.0.1:11211")
    servers.append("192.168.0.5:11211")
    length = len(servers)
    details3 = {key:[] for key in servers}
    for entry in entries:
        # keyhash = sum([ord(c) for c in entry])
        keyhash = hashcode(entry)
        server = servers[keyhash%length]
        details3[server].append(entry)
    print_pretty_dict(details3)
    
    # -------计算缓存度
    print("==="*7)
    print_pretty_dict(compute_cache_percentage(details1, details2))
    print("---"*20)
    print_pretty_dict(compute_cache_percentage(details1, details3))

    硬哈希缓存效果

    python hard-hash.py
    192.168.0.1:11211: ['o', 's', 'u', 'w']
    192.168.0.2:11211: ['a', 'd', 'g', 'h', 'i', 'j', 'n', 'q', 'r', 'y']
    192.168.0.3:11211: ['e', 'p', 't', 'v', 'x']
    192.168.0.4:11211: ['b', 'c', 'f', 'k', 'l', 'm', 'z']
    ------------------------------------------------------------------------------------
    192.168.0.2:11211: ['d', 'k', 'l', 'm', 's', 't', 'v', 'x']
    192.168.0.3:11211: ['a', 'b', 'c', 'e', 'h', 'i', 'n', 'o', 'p', 'r', 'u', 'w', 'y']
    192.168.0.4:11211: ['f', 'g', 'j', 'q', 'z']
    ------------------------------------------------------------------------------------
    192.168.0.1:11211: ['j', 'n', 't']
    192.168.0.2:11211: ['e', 'm', 'p', 'q', 'w']
    192.168.0.3:11211: ['a', 'i', 'l']
    192.168.0.4:11211: ['b', 'c', 'd', 'g', 'h', 'k', 'o', 's', 'v', 'x', 'z']
    192.168.0.5:11211: ['f', 'r', 'u', 'y']
    =====================
    192.168.0.1:11211: 0
    192.168.0.2:11211: 1
    192.168.0.3:11211: 2
    192.168.0.4:11211: 2
    ------------------------------------------------------------
    192.168.0.1:11211: 0
    192.168.0.2:11211: 1
    192.168.0.3:11211: 0
    192.168.0.4:11211: 4

    可以看出,动态缓存环境下,硬哈希的命中率并不高。

    一致哈希

    一致性哈希算法的基本实现原理是将机器节点和key值都按照一样的hash算法映射到一个0~2^32(也不一定非得是2^32, 理论上能让节点分布均匀的‘环’就够了)的圆环上。当有一个写入缓存的请求到来时,计算Key值k对应的哈希值Hash(k),如果该值正好对应之前某个机器节点的Hash值,则直接写入该机器节点,如果没有对应的机器节点,则顺时针查找下一个节点,进行写入,如果超过2^32还没找到对应节点,则从0开始查找(因为是环状结构)。比如下面盗的一张图。 
    简单一致性哈希原理图

    简易代码实现consisthash.py

    # coding: utf8
    # 简单一致性hash实现
    
    from constraints import servers, entries
    from func import print_pretty_dict, hashcode, compute_cache_percentage, compute_cache_percentage_ring
    
    
    class ConsistHash(object):
        """
        简单一致性哈希算法实现
        """
        def __init__(self, servers=[]):
            self.servers = servers
            # sorted list which contains server nodes.
            self.ring = []
            # node:[hashcode1, hashcode2, ...]
            self.hashnodemap = {}
            for server in self.servers:
                self.addNode(server)
    
        def addNode(self, node):
            code = hashcode(node)
            self.hashnodemap[code] = node
            self.ring.append(code)
            self.ring.sort()
    
    
        def removeNode(self, node):
            del self.hashnodemap[hashcode(node)]
            self.ring.remove(hashcode(node))
    
        def getNode(self, key):
            code = hashcode(key)
            for ringitem in self.ring[::-1]:
                if ringitem <= code:
                    return self.hashnodemap[ringitem]
            return self.hashnodemap[self.ring[0]]
    
    
    class Cacher(object):
        """
        普通一致性哈希算法的应用
        """
        def __init__(self, servers):
            self.c = ConsistHash(servers=servers)
            self.container = {key:[] for key in servers}
    
        def addServer(self, server):
            self.c.addNode(server)
            self.container[server] = []
    
        def removeServer(self, server):
            self.c.removeNode(server)
            del self.container[server]
    
        def cache(self, key, value):
            server = self.c.getNode(key)
            self.container[server].append({key: value})
    
    
        def get(self, key):
            server = self.c.getNode(key)
            return self.container[server].items()[key]
    
    
    if __name__ == "__main__":
        # c = ConsistHash(servers=servers)
        # print_pretty_list(c.ring)
        # print_pretty_dict(c.hashnodemap)
        cacher1 = Cacher(servers)
        for entry in entries:
            cacher1.cache(entry, entry)
        print_pretty_dict(cacher1.container)
        # 删除一个服务器
        cacher3 = Cacher(servers)
        cacher3.removeServer("192.168.0.1:11211")
        for entry in entries:
            cacher3.cache(entry, entry)
        print_pretty_dict(cacher3.container)
        # 添加一个服务器
        cacher2 = Cacher(servers)
        cacher2.addServer("192.168.0.5:11211")
        for entry in entries:
            cacher2.cache(entry, entry)
        print_pretty_dict(cacher2.container)
        # 计算缓存有效度
        print_pretty_dict(compute_cache_percentage_ring(cacher1.container, cacher2.container))
        print_pretty_dict(compute_cache_percentage_ring(cacher1.container, cacher3.container))

    缓存效果

    python consisthash.py
    192.168.0.1:11211: [{'a': 'a'}, {'c': 'c'}, {'h': 'h'}, {'j': 'j'}, {'l': 'l'}, {'r': 'r'}, {'s': 's'}, {'y': 'y'}]
    192.168.0.2:11211: [{'b': 'b'}, {'d': 'd'}, {'f': 'f'}, {'g': 'g'}, {'i': 'i'}, {'k': 'k'}, {'m': 'm'}, {'n': 'n'}, {'p': 'p'}, {'q': 'q'}, {'u': 'u'}, {'v': 'v'}, {'x': 'x'}]
    192.168.0.3:11211: []
    192.168.0.4:11211: [{'e': 'e'}, {'o': 'o'}, {'t': 't'}, {'w': 'w'}, {'z': 'z'}]
    192.168.0.2:11211: [{'a': 'a'}, {'b': 'b'}, {'c': 'c'}, {'d': 'd'}, {'f': 'f'}, {'g': 'g'}, {'h': 'h'}, {'i': 'i'}, {'j': 'j'}, {'k': 'k'}, {'l': 'l'}, {'m': 'm'}, {'n': 'n'}, {'p': 'p'}, {'q': 'q'}, {'r': 'r'}, {'s': 's'}, {'u': 'u'}, {'v': 'v'}, {'x': 'x'}, {'y': 'y'}]
    192.168.0.3:11211: []
    192.168.0.4:11211: [{'e': 'e'}, {'o': 'o'}, {'t': 't'}, {'w': 'w'}, {'z': 'z'}]
    192.168.0.1:11211: []
    192.168.0.2:11211: [{'b': 'b'}, {'d': 'd'}, {'f': 'f'}, {'g': 'g'}, {'i': 'i'}, {'k': 'k'}, {'m': 'm'}, {'n': 'n'}, {'p': 'p'}, {'q': 'q'}, {'u': 'u'}, {'v': 'v'}, {'x': 'x'}]
    192.168.0.3:11211: []
    192.168.0.4:11211: [{'e': 'e'}, {'o': 'o'}, {'t': 't'}, {'w': 'w'}, {'z': 'z'}]
    192.168.0.5:11211: [{'a': 'a'}, {'c': 'c'}, {'h': 'h'}, {'j': 'j'}, {'l': 'l'}, {'r': 'r'}, {'s': 's'}, {'y': 'y'}]
    192.168.0.1:11211: 0
    192.168.0.2:11211: 13
    192.168.0.3:11211: 0
    192.168.0.4:11211: 5
    192.168.0.1:11211: 0
    192.168.0.2:11211: 13
    192.168.0.3:11211: 0
    192.168.0.4:11211: 5

    结果表明: 与硬哈希缓存命中率相比,一致哈希的缓存命中率确实提高了不少。

    “虚拟”一致哈希

    虽然缓存命中率得到了提高,但是仅仅这样还不能够真正的应用到实际生产环境中,因为目前的一致哈希还缺少了平衡性。

    在此基础上,算法大佬们又引入了虚拟节点的概念。

    “虚拟节点”( virtual node )是实际节点(机器)在 hash 空间的复制品( replica ),一实际个节点(机器)对应了若干个“虚拟节点”,这个对应个数也成为“复制个数”,“虚拟节点”在 hash 空间中以hash值排列

    虚拟节点的一致哈希原理图

    带有虚拟节点的一致哈希virtualconstisthash.py

    # coding: utf8
    # 带有虚拟节点的一致性哈希算法实现
    
    from constraints import servers, entries
    from func import print_pretty_dict, hashcode, print_pretty_list
    from func import compute_cache_percentage
    from func import compute_cache_percentage_ring
    from func import compute_cache_percentage_virtual_ring
    
    class VirtualConsistHash(object):
        """
        带有虚拟节点的一致性哈希算法实现
        """
        def __init__(self, servers=[], replicas=3):
            self.servers = servers
            # sorted list which contains server nodes.
            self.ring = []
            # node:[hashcode1, hashcode2, ...]
            # 虚拟节点的个数,其实这个名字叫虚拟节点的个数不太合适,每个真实节点“虚拟化”后的节点个数比较好
            self.replicas = replicas
            self.hashnodemap = dict()
            for server in self.servers:
                self.addNode(server)
    
        def addNode(self, node):
            for i in range(0, self.replicas):
                temp = "{}#{}".format(node, i)
                code = hashcode(temp)
                self.hashnodemap[code] = temp
                self.ring.append(code)
                self.ring.sort()
    
        def removeNode(self, node):
            for i in range(0, self.replicas):
                temp = "{}#{}".format(node, i)
                code = hashcode(temp)
                self.ring.remove(code)
                del self.hashnodemap[code]
    
        def getNode(self, key):
            code = hashcode(key)
            for ringitem in self.ring[::-1]:
                if ringitem <= code:
                    return self.hashnodemap[ringitem]
            return self.hashnodemap[self.ring[0]]
    
    
    class Cacher(object):
        """
        带有虚拟节点的一致性哈希算法的应用
        """
        def __init__(self, servers):
            self.c = VirtualConsistHash(servers=servers)
            self.container = {"{}#{}".format(server, index): [] for index in range(0, self.c.replicas) for server in self.c.servers}
    
        def addServer(self, server):
            self.c.addNode(server)
            for i in range(0, self.c.replicas):
                temp = "{}#{}".format(server, i)
                self.container[temp] = []
    
        def removeServer(self, server):
            self.c.removeNode(server)
            for i in range(0, self.c.replicas):
                temp = "{}#{}".format(server, i)
                del self.container[temp]
    
        def cache(self, key, value):
            server = self.c.getNode(key)
            self.container[server].append({key: value})
    
        def get(self, key):
            server = self.c.getNode(key)
            return self.container[server].items()[key]
    
    
    if __name__ == "__main__":
        c = VirtualConsistHash(servers=servers)
        print_pretty_list(c.ring)
        print_pretty_dict(c.hashnodemap)
        cacher1 = Cacher(servers)
        for entry in entries:
            cacher1.cache(entry, entry)
        print_pretty_dict(cacher1.container)
        # 删除一个服务器
        cacher3 = Cacher(servers)
        cacher3.removeServer("192.168.0.1:11211")
        for entry in entries:
            cacher3.cache(entry, entry)
        print_pretty_dict(cacher3.container)
        # 添加一个服务器
        cacher2 = Cacher(servers)
        cacher2.addServer("192.168.0.5:11211")
        for entry in entries:
            cacher2.cache(entry, entry)
        print_pretty_dict(cacher2.container)
        # 计算缓存有效度
        print("==="*19, "删除一个缓存服务器后~")
        print_pretty_dict(
            compute_cache_percentage_virtual_ring(cacher1.container, cacher2.container))
        print("==="*19, "添加一个缓存服务器后~")
        print_pretty_dict(
            compute_cache_percentage_virtual_ring(cacher1.container, cacher3.container))

    实现效果

    python virtualconsisthash.py
    25929580212780940911456562527067013
    12101104964982711566768785763136289074
    74170601562041857353724622613970855161
    77290231086376083997830514397772133017
    108956197245253243279835718906668306846
    119181851294818588345880953329601308254
    148120148621525998622527044630882426909
    156975434986591250703568213828815453515
    166356565783230552968534833801964089480
    200325646817984951237589036984080642913
    314164546590207529500398448833042413158
    322409963387938480044046299781174104628
    74170601562041857353724622613970855161: 192.168.0.1:11211#0
    148120148621525998622527044630882426909: 192.168.0.1:11211#1
    77290231086376083997830514397772133017: 192.168.0.1:11211#2
    12101104964982711566768785763136289074: 192.168.0.2:11211#0
    166356565783230552968534833801964089480: 192.168.0.2:11211#1
    25929580212780940911456562527067013: 192.168.0.2:11211#2
    119181851294818588345880953329601308254: 192.168.0.3:11211#0
    156975434986591250703568213828815453515: 192.168.0.3:11211#1
    108956197245253243279835718906668306846: 192.168.0.3:11211#2
    200325646817984951237589036984080642913: 192.168.0.4:11211#0
    314164546590207529500398448833042413158: 192.168.0.4:11211#1
    322409963387938480044046299781174104628: 192.168.0.4:11211#2
    192.168.0.1:11211#0: []
    192.168.0.2:11211#0: [{'a': 'a'}, {'h': 'h'}, {'j': 'j'}, {'l': 'l'}]
    192.168.0.3:11211#0: []
    192.168.0.4:11211#0: [{'e': 'e'}, {'g': 'g'}, {'o': 'o'}, {'t': 't'}, {'v': 'v'}, {'x': 'x'}]
    192.168.0.1:11211#1: [{'m': 'm'}]
    192.168.0.2:11211#1: [{'b': 'b'}, {'d': 'd'}, {'f': 'f'}, {'i': 'i'}, {'k': 'k'}, {'p': 'p'}]
    192.168.0.3:11211#1: [{'n': 'n'}, {'q': 'q'}, {'u': 'u'}]
    192.168.0.4:11211#1: [{'w': 'w'}]
    192.168.0.1:11211#2: [{'c': 'c'}, {'r': 'r'}, {'y': 'y'}]
    192.168.0.2:11211#2: [{'s': 's'}]
    192.168.0.3:11211#2: []
    192.168.0.4:11211#2: [{'z': 'z'}]
    192.168.0.2:11211#0: [{'a': 'a'}, {'c': 'c'}, {'h': 'h'}, {'j': 'j'}, {'l': 'l'}, {'r': 'r'}, {'y': 'y'}]
    192.168.0.3:11211#0: [{'m': 'm'}]
    192.168.0.4:11211#0: [{'e': 'e'}, {'g': 'g'}, {'o': 'o'}, {'t': 't'}, {'v': 'v'}, {'x': 'x'}]
    192.168.0.2:11211#1: [{'b': 'b'}, {'d': 'd'}, {'f': 'f'}, {'i': 'i'}, {'k': 'k'}, {'p': 'p'}]
    192.168.0.3:11211#1: [{'n': 'n'}, {'q': 'q'}, {'u': 'u'}]
    192.168.0.4:11211#1: [{'w': 'w'}]
    192.168.0.2:11211#2: [{'s': 's'}]
    192.168.0.3:11211#2: []
    192.168.0.4:11211#2: [{'z': 'z'}]
    192.168.0.1:11211#0: []
    192.168.0.2:11211#0: [{'a': 'a'}]
    192.168.0.3:11211#0: []
    192.168.0.4:11211#0: [{'g': 'g'}, {'v': 'v'}, {'x': 'x'}]
    192.168.0.1:11211#1: [{'m': 'm'}]
    192.168.0.2:11211#1: [{'b': 'b'}, {'d': 'd'}, {'f': 'f'}, {'i': 'i'}, {'k': 'k'}, {'p': 'p'}]
    192.168.0.3:11211#1: [{'n': 'n'}, {'q': 'q'}, {'u': 'u'}]
    192.168.0.4:11211#1: [{'w': 'w'}]
    192.168.0.1:11211#2: [{'c': 'c'}, {'r': 'r'}, {'y': 'y'}]
    192.168.0.2:11211#2: [{'s': 's'}]
    192.168.0.3:11211#2: []
    192.168.0.4:11211#2: [{'z': 'z'}]
    192.168.0.5:11211#0: [{'h': 'h'}, {'j': 'j'}, {'l': 'l'}]
    192.168.0.5:11211#1: [{'e': 'e'}, {'o': 'o'}, {'t': 't'}]
    192.168.0.5:11211#2: []
    ========================================================= 删除一个缓存服务器后~
    192.168.0.1:11211: 4
    192.168.0.2:11211: 8
    192.168.0.3:11211: 3
    192.168.0.4:11211: 5
    ========================================================= 添加一个缓存服务器后~
    192.168.0.1:11211: 0
    192.168.0.2:11211: 11
    192.168.0.3:11211: 3
    192.168.0.4:11211: 8

    结果表明: 带有了虚拟节点的一致哈希实现,使得缓存的命中率得到了进一步的提高。而且平衡性也更趋于平和。

    总结

    通过上述分析,不难发现。

    • 硬哈希适用场景为“稳定”的缓存服务群,因此实际生产环境不怎么被用到。

    • 简单一致哈希,缓存命中率还算可以,但是缺乏平衡性,容易导致某台节点压力过大而有些节点空闲的状况。

    • 带有虚拟节点的一致哈希可以很好的解决上面的两个问题,但是具体的虚拟节点的设置replicas可能还需要根据实际的生产环境来进行设置。以此来达到一个最优的效果。

    展开全文
  • 为了提高高层次创新型科技人才的引进与管理的科学,弥补高层次创新型科技人才评价中的不足,本研究首先根据高层次创新型科技人才的概念及特征设计了三个层次的评价指标,运用模糊层次分析法对三级评价指标进行筛选;...
  • 下面是小编带来的关于党员的个人评价的内容,欢迎阅读!大学生党员的个人评价篇一 思想上,积极进取,坚持对党的理论知识的学习,进一步提高自己的思想觉悟。切实执行党的纪律、国家的法律以及学校、学院的各项规章...
  • 一种改进水环境质量模糊层次综合评价模型,褚克坚,华祖林,引入模糊一致矩阵概念,对传统层次分析法(AHP)进行改进,以解决判断矩阵一致性问题,并结合模糊评判法,建立了一种改进水环境
  • 提出用集对分析(SPA)多元联系数来描述煤矿水质评价确定和模糊不确定,并引入区间三角模糊数(ITFN)来对联系数同异反结构中差异度系数连续变化过程进行描述,最后提出了基于多元联系数区间三角模糊数决策...
  • 如果从数据完整度或数据一致性的角度来说,很多垃圾数据表现并不差,就算是考虑到数据与业务相关性,那也是需要建模进行描述性统计分析,这其中时间成本和人员素质要求可不低。 之前参加过几次信标委数据...
    最近在写关于数据质量的文档,一直在脑中有个问题,数据到底怎么给评价质量乃至数据价值?如果从数据完整度或数据一致性的角度来说,很多垃圾数据的表现并不差,就算是考虑到数据与业务的相关性,那也是需要建模进行描述性统计分析,这其中的时间成本和人员素质要求可不低。

    之前参加过几次信标委的数据标准研讨会,出席的专家大部分时间所讨论的,于我上面所讲的数据质量分析方法并无本质的区分。更有位中科院专门研究数据质量的专家称,数据质量不可严密考证,因为数据价值不可估量。

    是的,我非常同意数据价值要通过数据质量来体现这个观点,激进一点说,考虑到数据复制成本几乎为零,对照商品质量与商品价格的关系,可以认为数据质量等同于数据价值。但我们已经知道,数据价值并不是依靠数据本身来实现的,数据与其他的数据进行关联,做成产品,能够应用开来,解决业务痛点,数据的价值必须要升华为一种服务的能力。质量再高的数据如果没找到合适的应用途径,也是无用;我们可以给服务定价,但数据本身,是很难定价的。

    考虑到一种情况,如果数据在被生产的同时,已经带有了场景属性呢?比如说,一次购物行为,涉及到的对象:顾客、商家、银行,关键点:商品、网页点击、物流、顾客满意度等。暂且不问这些数据是怎么汇集起来的,光看结果,这个完整的数据集质量,其实是很高的。它几乎可以拿来就用,还可以相互比对,交叉验证等。可以说,这个数据集在质量上是接近完美的(考虑到数据采集的误差和人类参与整理的不可预知风险)。

    这就是中国大数据技术与应用联盟副理事长赵平生先生提出的粒数据概念,我把它做了下延伸。粒数据最大的革新在于,它让数据质量管理从事后转向了“事前”,严格地说应该是事中,事情发生过程中。再也不要面对数据的质量管理,而是数据产生参与各方的同心协力,“以合法、合规的方式产生一条真实的电子数据...一旦产生即不可被修改”。听听,是不是觉得有点像区块链技术?去中心化的记录,可扩展、安全可靠等,与其靠一个人来搜集维护,不如大家一起,形成一个联合共享式的数据仓库。
    粒数据一旦产生,将产生连锁效应,其联结的范围可以扩充至全世界、联结的深度可以贯穿全行业。它的魅力如此之大,以至于每家企业共享出来的数据可以得到潜在的几倍乃至几百倍的业务收益回赠。粒数据一出现,天然就带有革*min的诉求,它甚至带有某种共产主义的特质,一起劳动、一起收获,没有垄断和私自占有,全社会合作化大生产,听起来,很美好不是吗?

    这也是粒数据或者说是区块链的局限之处,为什么?有利益的地方就有人的“贪心”在作怪。参照比特币的安全性,区块链从技术上来说是接近完美的,然而,对于面向应用的区块链,一旦其赖以生存的加密机制被暴力破解或者某些参与者人为恶意制造假数据,致使整个区块链的参与者都要承担巨大的风险。看看各大金融机构对区块链的态度,基本都是在做前沿调研,谁也不敢真放开了做落地。没有绝对的安全,只有绝对的利益,从数据共享开放回滚到封闭自足,技术恐怕从来都不是决定因素。

    粒数据的概念,应该说是很超前的。就算在当下,市场监管和经济环境支撑不起粒数据的全面应用,在某些特定的领域,粒数据还是具有相当大的启发性的:比如说政府部门和企业内部,以产生数据的事件为一个集合,形成大数据应用的基本数据单位,而不是之前,把数据采集完了之后再去做关联。同时,这也有助于引导我们养成数据思维的好习惯。


    参考资料:
    区块链将彻底改变人工智能 | 熵、区块链和人工智能
    一文详解“粒数据”-大数据领域最新研究成果
    《DAMA数据管理知识体系指南》,p214-p230
    展开全文
  • 什么是层次分析法?层次分析法,是应用网络系统理论和多目标综合...运用层次分析法构造系统模型时,大体可以分为以下五个步骤:建立层次结构模型构造判断矩阵一致性检验计算各层权重总体一致性检验层次分析法优点...
  • 保持界面的一致性。用户界面设计在工作流程上分为结构设计、交互设计、视觉设计三个部分。结构设计也称概念设计(ConceptualDesign),是界面设计骨架。通过对用户研究和任务分析,制定出产品整体架构。交互设计...
  • 以灰度直方图表征光能分布, 进而给出均匀度的评判公式, 提出了均匀度评判精度P的概念, 并且通过编程给出离散灰度级所对应的网点位置, 从而实现精准优化。以184 mm×314 mm×0.55 mm的导光板为例进行仿真验证, 针对...
  • 通信规约相关概念

    2015-12-01 14:20:16
    规约性能评价标准:数据完整性、数据一致性、传输速率平衡传输(Balanced Transmission):没有主从之分,通信双方都可以启动报文传输。如对于平衡103而言,主站(不再是严格意义上主站)可以定时启动总召、广播校...
  • 在重述过程中,如果不相似度量保持一致,那么信息标准化过程就可以保持语言值语义不变。在现有许多文献中,对于标准语言值集合选取规则并未做过多要求,只是设定此集合势在7到13之间。为了进一步控制语言...
  • 经过计算得出一致性比例。 将最大特征值所对应特征向量归一化,即可得到本层次各因素重要性排序。 求出准则层对目标层权重之后,我们再去求备选层对准则层权重,方法同前述一致。 将两个步.
  • 首先针对软件可信没有一致定义的现状,提出了相对可信性的概念;接着基于模糊数理论,用三角模糊数表示专家评估中语言变量的主观和模糊,结合专家给出的模糊指标权重及待评软件可信等级的模糊评价,得到软件...
  • 简图记录总结~ 一、概念  LCD:liquid Crystal Display,液晶显示器。... 液晶:具有液体流动特性,同时具有晶体各向、双折射等特性。  偏振片:一种透光片,只有偏振方向一致的光波...
  • 层次分析法理解

    2020-08-07 11:39:31
    一致矩阵特点:一致矩阵引理:一致性检验步骤判断矩阵计算权重算术平均法求权重几何平均法特征值法求权重层次分析法局限性层次分析法框架图 层次分析法 评价类问题可用打分来解决,也就是说通过分数来量化一...
  • 针对犹豫模糊信息在现实决策中难以准确和充分的提供决策者评价信息的问题,引入了概率不确定犹豫模糊偏好关系(PUHFPR)的概念,其能够有效处理概率不确定犹豫模糊元(PUHFE)中元素发生概率信息部分已知和完全未知...
  • 检验概念的“唯一”会导致用另外方式做事。 第5课:支配观点。大多数情况下都有占统治地位观点。为了具有创造,必须摆脱这些观点束缚。 第6课:定义问题。对问题进行定义会使它更容易解决。 第7课:剔除...
  • 以一个水利工程评标为例进行分析,计算结果最佳方案(即最优投标单位)是A4,最劣方案为A1,表明利用该模型对水利工程评标中各投标方案进行优选具有一定操作,而且利用该方法得出的评价结果与实际情况比较一致
  • 在运用景气指数法预警、计算扩散指数 DI和合成指数 CI时 ,往往存在警度不一致并导致警情失真等弊端 ,直接影响到景气评价的科学 .在对传统 DI计算方法进行合理改进的...
  • 由于图像置乱分成位置和像素值置乱两类,图像置乱衡量也从这两方面进行分析。...通过对大量实验结果分析得出,该衡量算法可以准确地衡量图像置乱程度,与人视觉评价保持一致,具有可行和有效
  •  近年来,国外GIS与数据库开发商加紧了联合步伐,共同开发全关系GIS软件,使GIS软件能充分利用商用数据库中已经成熟众多特性,如内存缓冲、快速索引、数据完整性和一致性保证、并发控制、安全和恢复机制及...
  • 测试基础 软件质量

    2015-09-01 19:42:04
    2.软件质量的概念 ISO/IEC9126规定,软件质量可用6个特性来评价: 功能:软件所实现的功能达到它的设计规范和满足用户需求的程度 可靠:在满足一定条件的应用环境中,软件能够正常维持其工作的能力 可用:...
  • 客观性与一致性 ;数据可用性 ;文化因素 ;组织管理层人因分析 .最后从理论与应用两方面讨论了人因分析学科近期应发展三个范畴 :人因分析基础研究 ;人 -机系统设计指导 ;安全评价与事故防范 .
  • 交互设计

    2020-06-02 09:20:02
    设计目标可用性设计原则可视化屏幕元素选择、布局、呈现及装饰一致性直接映射有效反馈良好GUI设计原则设计过程Design(设计)Prototype(原型)Evaluation(评价) 基本概念 软件设计= 编码设计 + 交互设计...
  • SOA在十年前就提出了服务化的概念,那微服务到底是新的理论突破,还是新瓶装旧酒换了一个概念出来忽悠? 总结了微服务应该具备的特点: - 小, 且专注于做⼀件事情 - 独立的进程 - 松耦合、...
  • 软件工程知识点

    2012-12-02 21:34:25
    比较常用需求有效性验证方法与工具包括:需求评审、需求原型评价和基于CASE工具需求一致性分析。 6.需求规格定义 需求规格说明书是需求分析阶段需要交付基本文档,将成为开发者进行软件设计和用户进行软件验证...

空空如也

空空如也

1 2 3 4
收藏数 65
精华内容 26
关键字:

一致性评价的概念