先行发生原则(Happens-Before)是Java内存模型定义的一个等效判断原则。 依赖这个原则,我们可以通过几条简单规则判断数据是否存在竞争,线程是否安全,而不需要陷入Java内存模型苦涩难懂的定义之中。---“先行发生”原则指的是什么。 下面是Java内存模型下一些“天然的”先行发生关系,这些先行发生关系无须任何同步器协助就已经存在,可以在编码中直接使用。 Java 语言无须任何同步手段保障就能成立的先行发生规则有且只有上面这些。---“时间上的先后顺序”与“先行发生”之间有什么不同?一个操作“时间上的先发生”不代表这个操作会是 “先行发生”。 时间先后顺序与先行发生原则之间基本没有因果关系,所以我们衡量并发安全问题的时候不要受时间顺序的干扰,一切必须以先行发生原则为准。
“先行发生”(happens-before)的原则。 一、什么是先行发生原则 现在就来看看“先行发生”原则指的是什么。 “j=i”,那么可以确定在线程B的操作执行后,变量j的值一定等于1,得出这个结论的依据有两个:一是根据先行发生原则,“i=1”的结果可以被观察到;二是线程C还没“登场”,线程A操作结束之后没有其他线程会修改变量 ,根据程序次序规则,“int i=1”的操作先行发生于“int j=2”,但是“int j=2”的代码完全可能先被处理器执行,这并不影响先行发生原则的正确性,因为我们在这条线程之中没有办法感知到这点。 上面两个例子综合起来证明了一个结论:时间先后顺序与先行发生原则之间基本没有太大的关系,所以我们衡量并发安全问题的时候不要受到时间顺序的干扰,一切必须以先行发生原则为准。
先行发生”原则。 先行发生是Java内存模型中定义的两项操作数之间的偏序关系,如果说操作A先行发生于操作B,就是说在发生操作B之前,操作A产生的影响能被操作B观察到,“影响”包括修改了内存中共享变量的值、发送了消息、调用了方法等 线程启动规则 :Thread对象的start方法先行发生于此线程的每个动作; 线程终止规则 :线程中的所有操作都先行发生于对此线程的终止检测; 线程中断规则 :对线程的interrupt()方法的调用先行发生于被中断线程的代码检测到中断时间的发生 ; 对象终结规则 :一个对象的初始化完成先行发生于它的finalize方法的开始; 传递性 :如果操作A先行发生于操作B,操作B先行发生于操作C,那么,操作A也就先行发生于操作C。 依次分析一下先行发生原则中的各个原则:由于两个方法分别在不同的线程中被调用,程序次序原则不适用;没有同步块,自然不会发生lock和unlock操作,管程锁定原则不适用;value变量没有被volatile
)原则 这个原则非常重要,它是判断数据是否存在竞争,线程是否安全的主要依赖。 先行发生原则 指的是JMM中定义的两项操作之间的依序关系 happens- before关系 主要用于强调两个有冲突的动作之间的顺序,以及定义数据争用的发生时机 如果说操作A先行发生于操作B,就是在说发生 线程中断规则(Thread Interruption Rule) 对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过Thread.interrupted() A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论 一个操作”时间上的先发生“不代表这个操作会是”先行发生“,那如果一个操作”先行发生“是否就能推导出这个操作必定是”时间上的先发生 也是不成立的,一个典型的例子就是指令重排序 所以时间上的先后顺序与先行发生原则之间基本没有什么关系,所以衡量并发安全问题一切必须以先行发生原则为准。
文章目录 一、指令重排序规范 二、happens-before 先行发生原则 一、指令重排序规范 ---- 指令重排指的是 , 线程中如果两行代码 没有逻辑上的上下关系 , 可以对代码进行 重新排序 ; 规范 : 先行发生原则 ; 二、happens-before 先行发生原则 ---- happens-before 先行发生原则 : A happens-before B , A 先于 B 发生 , 使用 指令重排 ; happens-before 先行发生原则 适用场景 : 在以下场景中 , 不进行指令重排 , 这些先后顺序 , 绝对不能被打乱 , 否则会出现严重线程安全问题 ; 程序次序原则 检测到 中断时 事件的发生 ; 必须先发生中断 , 然后才能被检测到 ; 不能还没发生中断 , 就可以检测到中断发生 ; 对象终结 : 对象的创建 先于 对象的终结 , 创建就是调用构造函数 , 终结就是调用 finalize 方法 ; 只要符合上述规则 , 不需要进行同步 , 就可以成立 ; 通过 " happens-before 先行发生原则 " 可以判定两个线程的操作 , 是否有发生冲突的可能 ;
2010年的全球移动通信大会上,谷歌时任首席执行官Eric Schmidt 提出:产品设计应遵循 “移动先行” 的原则。 该原则具体指什么?遵循该原则的依据有哪些?为什么它在产品设计中如此重要? 一、什么是“移动先行” 原则? 为了更好地理解该原则,首先要了解两个概念: 1. 响应式网页设计(RWD) 一种网页设计方法。 因为“移动先行”原则,就是“逐步增强” 策略的一个具体表现形式。 “移动先行”,顾名思义,即在设计多终端产品时,首先设计限制较多的移动端版本,再一步步向高级终端迈进。 ? 二、为什么在产品设计中,“移动先行”的原则如此重要? 除了以上提到的“逐步增强”的设计策略的可操作性更强外,“移动先行”原则其实还具有强大的现实基础:移动端需求的爆炸式增长。 移动端需求的爆炸式增长,要求设计师在进行产品设计时,重视产品的移动端版本,遵从 “移动先行” 的设计原则。 三、如何在产品设计中践行移动先行原则?
关于Java异常处理的9条原则在Java编程中,合理有效地处理异常对于保证程序的稳定性和可维护性至关重要充分发挥异常优点,可以提高程序可读、可靠、可维护性本文基于Effective Java 异常章节总结 9条异常处理原则只针对异常情况才使用异常不要使用异常来做程序的流程控制,只有针对异常情况才使用异常不主动判断数组下标是否越界,而使用异常控制流程的反例: int[] ints = {1, @throw要记录在哪种情况下可能抛出的受检异常和运行时异常在异常信息中保留关键信息异常中会存储字符串保留当时发生异常的现场相关信息,这种信息对于我们的排查是非常有利的为了能够更容易的保留这种关键信息, ,从而导致数据不一致发生这种情况后,如果再使用数据不一致的对象就会发生错误在实现方法时应该努力让发生异常导致失败时保持原子性,失败的调用方法应该让对象处于之前的状态保证原子性的方法有5种:使用不可变对象 (类似第二种) 比如TreeSet需要内部元素实现比较器,如果未实现比较器或者元素类型不同,会发生类型转换异常,从而抛出异常不会执行添加操作将源对象进行拷贝,如果发生异常错误可以找回源对象(或直接使用拷贝的对象进行处理
先行发生原则 如果JMM中所有的有序性都只靠volatile和synchronized,那么有一些操作将会变得很繁琐,但我们在编写Java并发代码时并没有感到这一点,这是因为Java语言中有一个先行发生 先行发生原则是指JMM中定义的两项操作之间的依序关系 如果说操作A先行发生于操作B,就是在说发生B前,A产生的影响能被B观察到,“影响”包含了修改内存中共享变量的值、发送了消息、调用了方法等。 传递性(Transitivity):如果操作A先行发生于操作B,操作B先行发生于操作C,那就可以得出操作A先行发生于操作C的结论。 一个操作”时间上的先发生“不代表这个操作会是”先行发生“,那 如果一个操作”先行发生“是否就能推导出这个操作必定是”时间上的先发生“呢?也是不成立的,一个典型的例子就是指令重排序。 所以时间上的先后顺序与先生发生原则之间基本没有什么关系,所以衡量并发安全问题一切必须以先行发生原则为准。
官方尚未正式发布64位Raspbian,近期有团队移植了Debian 9 arm64到树莓派3B,将“装死”一年多的树莓派3B的性能完全释放出来,测试跑下来发现CPU性能最高比32位系统高30倍! 3 Model B 16GB Class 10 TF卡 5v2.5A电源 以太网网线及能连外网路由设备 软件测试环境: GEEEKPI-64bit-beta(内核移植版,操作系统是基于Debian 9的 arm64位源码,Debian 9目前还没发布,目前属于beta版,RaspberryPi 官方也没有发布64bit操作系统的计划,但是我们迫切需要64bit的性能) sysbench 压力测试软件 首先开机后联网 adsbygoogle = window.adsbygoogle || []).push({}); 总结: GEEEKPI 团队最终对比表格如下: 测试项目 Raspbian2017-03-03 Debian 9 94.3Mbps 1.26倍 文件连续读写 5.7655 7.1506 见下文说明 文件随机读写 不支持 21.8336 无 互斥锁性能 0.0231s 0.0186s 1.24倍 Debain 9
要记住的 9 个干净代码原则 有意义的名称:为变量和函数命名以揭示它们的用途,而不仅仅是它们的值。 一个功能,一个责任:功能应该做一件事。 避免使用幻数:将硬编码值替换为命名常量以赋予它们含义。 代码应该是不言自明的:编写良好的代码需要较少的注释,因为它读起来像一个故事。 SQL 联接的 4 种类型 SQL 联接根据相关列合并两个或多个表中的行。 以下是您可以使用的不同类型的联接: Inner Join 仅返回两个表之间的匹配行。它只保留公共数据。 Left Join 返回左表中的所有行和右表中的匹配行。 如果左表中的行与右表中的行不匹配,则右表中的列将在该行中包含 NULL 值。 Right Join 返回右表中的所有行和左表中的匹配行。 如果左表中不存在与右表中的记录匹配的记录,则结果中左表中的列将包含 NULL 值。 FULL OUTER JOIN 返回两个表中的所有行,为缺少的匹配项填充 NULL。
均为原创,读架构整洁之道的笔记。里氏替换原则:(LSP :Liskov Substitution Principle)。使用一个父类对象,替换成该父类对象的子类对象后,该程序不会发生异常。 (该书指的为接口,而没有提到继承关系)或者说,调用一个Interface,切换成直接调用该接口的实现对象后,该程序不会发生异常。 按照业务切换实现类,业务是可以正常进行的,不会破坏程序的正确性,不会发生异常。最关键的是这两个实现类,可以直接替换掉License接口。这样就是符合LSP原则的。 r.setW(5);r.setH(2);assert(r.area()==10);即可以确认,子类型,并不能完全替代其父类,会发生逻辑上的问题。 LSP 与软件架构可以看出,上述讲的是类和接口的继承与实现关系。然而随着时间推移,LSP演变成了一种更广泛的,指导接口与其实现方式的设计原则。
响应式web设计对于解决多类型屏幕问题来说是个不错方案,但从印刷的角度来看,其却存在着很多的困难。没有固定的页面尺寸、没有毫米或英寸,没有任何物理限制,让人感到无从下手。 随着建立网站可用的各种小工具越来越多,像素设计局限于桌面和移动端也已经成为历史。因此,现在就让我们来说明一下如何运用响应式web设计的各项基本原则来实现,而不是抗拒流畅的网页体验。 相对单位 你的设计对象可能是台式桌面,也可能是移动端屏幕或者介于两者之间的任意屏幕类型。像素密度也会彼此不同,所以我们需要使用灵活可变,并且能够适应各种情况的单位。 断点 断点可以让页面布局在预设的点进行变形,也就是说,在台式桌面上显示3栏,在移动设备上仅显示1栏。大多数CSS属性都可以实现断点之间的变形。断点放置的位置通常取决于内容。 但断点使用时需要谨慎——如果搞不清内容之间的逻辑关系,很容易弄的一团乱。
现存的原则会发生改变,新的原则会被加进来,旧的原则将不再适用。实践和从实践中获得的经验,促使我们发展了那些原则。 忽视上述变化可能在短期内会让生活看起来更容易,但最终的系统将无法使用。 原则9 促使开发者与客户的目标一致 项目经常会因为客户和开发人员的目标不同(或不兼容)而失败。 与原则185和201 (强调软件部署后,需求可能发生巨大变化)不同,本原则想表达,在开发过程中,软件也可能发生巨大变化。这些变化可能体现在编写新的代码、新的测试计划或新的需求规格说明上。 第9章 演变原则 演变是与修改软件产品相关的一系列工作,用于: 1.满足新功能。 2.更有效地运行。 3.正常运行(当检测到原始产品中的错误时)。 为了避免这种情况的发生,要确保你正在做的变更是经过核准的(见原则182及183),对每项变更进行核查(见原则97),并在每组变更后进行回归测试(见原则196)。
数字钱包的兴起 杜兰德说,人们将越来越多地在手机上存储关于自己的经过验证的数据。举个例子,他们的真实身份将通过苹果和谷歌提供的数字钱包保存在政府颁发的身份证中。 从好的方面来说,它们可以确保用户在商业或金融交易中的身份,减少欺诈和身份盗用,并降低通常创建物理身份验证方法的组织的成本和开销。 对僵尸和影子 API 的攻击 影子或僵尸 API 会带来安全风险,因为它们通常是隐藏的、未知的并且不受传统安全措施的保护。 IT与OT的融合 随着 IT 团队承担物理设备安全的责任,信息技术和运营(物理)技术将发生冲突。 杜兰德说,客户并不真正关心幕后发生的技术流程。相反,他们想要无缝的数字体验,以便他们可以轻松访问他们的帐户并进行购买。不提供流畅用户体验的面向消费者的公司将被那些提供流畅用户体验的公司抛弃。
,但尽力写的详细点,这比较适合新手,老手可以忽略繁琐的部分。 IP核配置 ---- 定制输出数据位宽 这里的输出数据指的是输出的波形数据,其位宽相关参数介绍如下: ? 较小的值可提供较高的频率分辨率,并且需要较大的累加器。较大的值会减少硬件资源。根据噪声整形的选择,可以增加相位宽度,并且频率分辨率高于指定的分辨率。 如果仅选择正弦或余弦之一,则将其符号扩展并放入m_axis_data_tdata的最低有效部分。 下图显示了这三种配置的TDATA的内部结构。正交输出,仅余弦和仅正弦。 因此我们可以这么认为,由于存在扩展符号位的关系,我们可以提取低一半的数据为COS,高一半的数据未SIN。 其他设置 有了上面的定制参数,输出波形是没有问题了,至于其他的定制参数,本文选择默认: ?
在二十世纪五十年代就存在深度学习的概念了。麦肯锡全球研究院发文简要回顾了深度学习是如何从概念发展为现实的,而使之实现的关键人物又是谁。 后来,美国麻省理工学院(MIT)的马文·明斯基(Marvin Minsky)和西摩·帕普特(SeymourPapert)在其1969年出版的书《感知器》中,用数学的方法展示了感知器只能进行很基础的任务, 他们的书还讨论了训练多层神经网络的难点。 2012年,辛顿和他的学生在著名的 ImageNet 竞赛中取得了突出的结果,彰显了深度学习的强大。该竞赛以李飞飞等人整理的数据集为基础。 深度学习也增强了强化学习这一已存在的领域,理查德·萨顿(Richard Sutton)就是其中一位顶尖的研究人员,他牵头让谷歌DeepMind开发的系统取得了多次棋类比赛的胜利。
Open-Closed Principle,"开闭原则"百科上是这么说的:一个软件实体(如类、模块、函数)应该对扩展开放,对修改关闭。 为什么? 开闭原则是面向对象设计原则中最基础的原则,可称之为原则的原则,也可以说是原则的指导思想,它强调的是既稳定又灵活,在不修改源代码的情况下又增加了新功能,核心思想是面向抽象编程。 "开闭原则是抽象类,其他五大原则是具体的实现类。"对测试的影响,可以提高复用性,提高可维护性,面向对象开发的要求。 怎么用? (来说说抽象,抽象是对一组事物的通用描述,它没有具体的实现,也就表示它有很多的可能性,在程序语言中抽象表现为在接口或抽象类定义一些可变的行为,并且能够实现对扩展开放,其包含三层含义: 第一,通过接口或抽象类约束扩展 最后再说说封装变化,包含两层含义: 将相同的变化封装到一个接口或抽象类中; 将不同的变化封装到不同的接口或抽象类中;
今天在群里有个同学问,说他给github上的一个项目写了个插件,然后对方说他的插件的空格缩进不对,他就想问问几个空格缩进才对? 先说下我的观点,我是4个空格,并且我直接就是tab键排齐就完事了。 另外JS本身也确实没有一个真正官方的代码风格指南,没有官方文档,然后各个社区也没有共识。 但真要是用2个空格来缩进,这代码确实有点难看,看这个angular.js,这个网上找来的看看 ? 这事也分二面说,如果你是给别人写插件,那相当于你加入别人的项目,自然要按着别人的规矩来。别人是4空格,你写的JS就必须是4空格。。 所以这事说到最后吧,前端就是一个约定大于规范的地方,就没有一个最权威的规范。所以一般就是开工之前,大家坐在一起,约定一下。目前最适合的吧,就是一个tab的缩进,相当于4个空格。
本月底,华南地区规模最大的制造业展会深圳机械展将着力聚焦机器人。可以预见的是,近两年风靡珠三角的机器人今年将延续之前的热度在珠三角发酵。 诚然,若没有需求,就不能催生产业发展空间,珠三角庞大的制造型企业对“机器代人”的强烈渴求成为机器人产业发展的助力器。 在珠三角的很多生产车间里,或出于替代人工的未雨绸缪,或出于先行试吃的气魄,机器人已渐替代人工。 成本收益 喜:有企业两年投入2.7亿,年均节省人力成本1.8亿 机器人应用这笔账怎么算? 而经过一番“机器换人”之后,该企业工人数量从最高峰时的6000人降至目前的2000人左右,而每年的销量却比往年高出不少。“最开始的投入是有点大,但现在看来是值得的。”该负责人说。 忧:暂无回报,还处于观察阶段 很多大型企业作为工业机器人试吃的先行者,数年经营投入已稍有成效,但对于一些发展中的小型企业来说,引进机器人则是一个更加艰巨的行为,其成本收益情况也同样不明朗。
Dependence Inversion Principle,DIP"依赖倒置原则",依赖倒置的原始定义是: Hign level modules should not depend ; 高层模块依赖抽象层:高层模块基于抽象层编程; 低层模块依赖抽象层:低层模块继承或者实现抽象层; 细节:实现接口或者继承抽象类而产生的类; 模块间的依赖通过抽象发生 ,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或者抽象类产生的;接口或者抽象类不依赖于实现类;实现类依赖接口或者抽象类,核心思想是面向接口编程; 采用依赖倒置原则可以减少类之间的耦合性, 提高系统的稳定性; 举个例子: ? 最佳实践 依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块彼此独立,不互相影响,实现模块间的松耦合,我们在项目中应该尽量做到: 1.每个类尽量都有接口或者抽象类,或者抽象类和接口两者都具备