首页 文章 精选 留言 我的

精选列表

搜索[思考控制],共10005篇文章
优秀的个人博客,低调大师

关于规则引擎的选型和疑惑思考

这是一个一些业务开发人员或者架构设计人员经常遇到的困惑: 1、给我推荐一个最简单、易用的规则引擎 1、运营人员觉得之前做的规则引擎不好用,是否可以做一个适合我们使用的规则引擎?不用看懂代码,直接界面表单提交操作。 2、我们的操作者是运营人员,大部分无技术背景,人员还有流动性,所以选型倾向选择可视化易编辑易理解的开源规则引擎。 能否推荐下选型,并说明优缺点 我的观点: 1、你要的可视化易编辑易理解的开源规则引擎是不存在的。 通用的规则引擎只是把原来的java代码转化成了脚本来动态解析执行而已。本质上还是需要写代码,比如要写drools的表达式,如果你的运营人员不懂,并且培训无效那就没有办法了。 2、但是基于规则引擎的业务系统可以做到配置人员无需了解代码。 这个过程首先需要开发人员总结、提炼出目前的N个业务类型,然后针对每个业务类型开发出运营人员需要配

优秀的个人博客,低调大师

【思考】Python声明和定义可以分开么?

本博客共分为四个部分,每一个小部分都可以看作一个独立的小问题,但相互之间又联系紧密。 第一部分: 探究这个问题,还是因为编程的时候碰到了这个错误: 提示tcplink没有定义,tcplink是我自己写的一个给监听到的tcp连接请求分配新线程的函数,不过是写在了下面,就像这样: 如果是C++里面的话,解决这个问题很简单。在文件开头的时候,加上该函数的声明式就OK,这样不仅方便,还能最大限度的保持美观(雾)。但是问题来了,Python里面好像没有声明和定义这一说呀! 到底有没有呢?这个得要从Python脚本的运行机制来看了。 在C++里面,声明是告诉编译器我的程序里将会有这个符号,编译器将声明内容进行记录,在定义处记录入口,分配内存。换言之,由于C++是编译型语言,这就可以对完整的程序进行扫描,进行跨文本域的联系。 然而,Python却不可以,Python是解释型语言,虽然我们自己写的脚本是一个完整文件,但是在给Python解释器执行的时候,依然相当于是把脚本文件里的内容一行一行输入进解释器并执行。这就造成了如果执行的当前语句要调用tcplink,解释器立马会在之前输入的内容中寻找tcplink的定义并执行,如果无法执行则报错。因为有这个机制,直接就导致了不能像C/C++那样,先放个声明式在前面,在把定义放到其他地方。 第二部分: 有些人可能会问,拉倒吧,我编程的时候这样写,funcb在funcc前面,funcb内将执行funcc,为啥运行的时候什么错误都不会报呢? 这就更有的说了,我们先来把这一小段放到Python命令行交互模式下,看结果如何: 对,依然也是什么错误都没发生。那么,根据之前所说,Python解释器是进来一行解释一行,如果无法解释就会立马报错,为什么这里解释器读入了funcc,用户也没有进行funcc的定义,解释器却没有报错呢? 其实,“Python解释器是进来一行解释一行” 这种说法其实还不太严谨。细心的读者能够发现,当在Python解释器输入def funcb():并回车的时候,>>>变成了...,只有在funcb用户定义完成后并确认,才又会回到>>>。一般情况下,用户是输入一行回车,>>>不发生改变,并输出应该有的结果。所以这说明了什么呢?这说明了两点问题: 1.在定义funcb()的时候,用户的回车没有让输入的语句执行。 2.定义完成funcb()向解释器发送回车确认的时候,解释器也没有执行之前定义内的内容。(因为如果执行了,一定会报错,就像下面这样) 新的问题又出现了,所以之前解释器到底执行了什么?答案就是:执行了“定义funcb()”这一个语句。这样,第二部分开头的那个问题,我想大家心里应该有答案了。把第二部分开头的那段程序执行过程画个图来理解,就像这样: 简而言之,如果当前只是执行了“定义XXX”的语句,解释器并不关心你具体定义的内容,此时进来的内容,解释器暂不执行。所以由于之前的funcc()是funcb()内定义的内容,自然不执行,也就无关乎是否此时存在funcc()。但!如果我此时调用funcb,解释器就会转而执行funcb内的具体内容,此时如果funcc()还没有被定义,一定会报not defined的错误!咱们来验证一下: 看来,说的不错。而第二部分开头的代码,在funcc实际被执行的时候,已经获得了完整的定义,故就不会报not defined的错误拉~ 第三部分: 那么,有没有什么方法,能够让我的Python程序看起来更加整洁美观——不让所谓的“主程序”文件内函数太多而显得杂乱呢? 其实,import是个挺不错的方法,稍微熟悉Python的人都明白,import可以引用其他地方的py等模块,还可以用from module import function的形式,单独引入指定模块内的指定函数、类。 甚至!! 对于一个从C++过来的人,真是傻了。Python的import相当于“把import的东西原封不动塞进import处一整坨”,所以由于是在函数定义内import的,所以import的东西只有在该函数内才可使用~然而C++/C的单独#include预处理指令则是做不到的。 等等。是不是错过了什么重要的东西…… 是的,如果import直接导入本文件,是否是可以的呢?如果可以的话,那岂不是之前的例子中,在之前加上: from 本文件 import funca/b/c,就可以实现类似C++函数声明的作用了?万一成功了,那岂不是……真香? 我们来试试: 看来,真香失败。那么,为什么这种方法不行呢?我们来回顾一下第二部分中部那个我自己画的流程图,由于Python解释器是进来一句执行一句,所以这里执行的内容是:导入daliywork中的funcb。执行这一句的时候,funcb没有定义,故导入失败。但必须说明的一点是,“import 文件本身” 是可行的!可见接下来这张演示事例: (坏了,这里又埋下了一个种子,被导入的daliywork里面的导入的daliywork是否产生了执行?如果有,执行的内容显示到了哪里?) 第四部分: 最后一个问题,如果import整个文件自己本身,可不可以实现这种结果呢?(就和只执行定义XXX时解释器不会探究具体定义的内容一样,这种只执行导入整个文件的操作,解释器是否会关心整个文件内的具体内容呢?) 我们再来回顾一下第三部分内关于import一个很直观的解释(但不是很严谨): 好了,有了这个解释,我觉得大部分人心里已经有答案了。测试代码如下,我们直接执行来看一下结果: 异常栈首先提示funca没有定义,指向daliywork第六行,但这个错误又是因为daliywork的第三行import导致的。这是因为import整个文件后,相当于把除了import这句以外的部分,替换到了import本身的地方,然后执行这些代码,这时候,在引入的部分内,执行到funca,发现还是没有进行定义,这时候再报出funca没有进行定义的错误。需要注意,错误内报了funca没有经过定义,并不是报的执行文件中的funca没有定义(因为此时在源文件line3 import这一句就已经抛出异常了,程序已经停在这里了!),而是import的daliywork里面的第六行出现的错误。这一点十分重要,可以用以下的图解进行解释(PS:画图真好用): 虽然引入的内容里,包括了所有的定义内容,但是由于引入的文件也会发生执行,所以依然无法实现我们想要的效果…… 看来,由于Python特殊的解释执行机制,导致了没什么方法可以只把函数的声明提前。以后写代码的时候,还是乖乖要么把定义的函数都放到其他文件通过import module方式导入,通过module.function()形式进行调用;要么乖乖放在要执行该函数的代码的前面吧…… 最后献上一首小诗。 无题 声明定义要分离,Python解释行不行? 千变万化难模拟,绕了一圈空叹息。

优秀的个人博客,低调大师

对缓存击穿的一点思考

前言 缓存(内存 or Memcached or Redis.....)在互联网项目中广泛应用,本篇博客将讨论下缓存击穿这一个话题,涵盖缓存击穿的现象、解决的思路、以及通过代码抽象方式来处理缓存击穿。 什么是缓存击穿? 上面的代码,是一个典型的写法:当查询的时候,先从Redis集群中取,如果没有,那么再从DB中查询并设置到Redis集群中。 注意,在实际开发中,我们一般在缓存中,存储的数据结构是JSON。(JDK提供的序列化方式效率稍微比JSON序列化低一些;而且JDK序列化非常严格,字段的增减,就很可能导致反序列失败,而JSON这方面兼容性较好) 假设从DB中查询需要2S,那么显然这段时间内过来的请求,在上述的代码下,会全部走DB查询,相当于缓存被直接穿透,这样的现象就称之为“缓存击穿”! 避免缓存击穿的思路分析 加synchronized? 如果synchronized加在方法上,使得查询请求都得排队,本来我们的本意是让并发查询走缓存。也就是现在synchronized的粒度太大了。 缩小synchronized的粒度? 上面代码,在缓存有数据时,让查询缓存的请求不必排队,减小了同步的粒度。但是,仍然没有解决缓存击穿的问题。 虽然,多个查询DB的请求进行排队,但是即便一个DB查询请求完成并设置到缓存中,其他查询DB的请求依然会继续查询DB! synchronized+双重检查机制 通过synchronized+双重检查机制: 在同步块中,继续判断检查,保证不存在,才去查DB。 代码抽象 发现没有,其实我们处理缓存的代码,除了具体的查询DB逻辑外,其他都是模板化的。下面我们就来抽象下! 一个查询DB的接口: 既然查询具体的DB是由业务来决定的,那么暴露这个接口让业务去实现它。 一个模板: Spring不是有很多Template类么?我们也可以通过这种思想对代码进行一个抽象,让外界来决定具体的业务实现,而把模板步骤写好。(有点类似AOP的概念) 改进后的代码: 从这里可以看出,我们并不关心缓存的数据从哪里加载,而是交给具体的使用方,而且使用方在使用时再也不必关注缓存击穿的问题,因为我们都给抽象了。

优秀的个人博客,低调大师

[Android Pro] InputStream.skip方法的思考

参考 :http://blog.csdn.net/gsyzhu/article/details/8102286 在java.io.InputStream类中定义了skip这个方法。在API中的描述如下: skip public long skip(longn) throws IOException Skips over and discards nbytes of data from this input stream. The skipmethod may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly 0. This may result from any of a number of conditions; reaching end of file before nbytes have been skipped is only one possibility. The actual number of bytes skipped is returned. If nis negative, no bytes are skipped. Theskipmethod of this class creates a byte array and then repeatedly reads into it untilnbytes have been read or the end of the stream has been reached. Subclasses are encouraged to provide a more efficient implementation of this method. For instance, the implementation may depend on the ability to seek. Parameters: n- the number of bytes to be skipped. Returns: the actual number of bytes skipped. Throws: IOException- if the stream does not support seek, or if some other I/O error occurs. 翻译如下: skip(long n) throwsIOException 跳过和丢弃此输入流中数据的n个字节。出于各种原因,skip方法结束时跳过的字节数可能小于该数,也可能为0。导致这种情况的原因很多,跳过n个字节之前已到达文件末尾只是其中一种可能。返回跳过的实际字节数。如果n为负,则不跳过任何字节。 此类的skip方法创建一个 byte 数组,然后重复将字节读入其中,直到读够n个字节或已到达流末尾为止。建议子类提供此方法更为有效的实现。例如,可依赖搜索能力的实现。 n 要跳过的字节数。 return 跳过的实际字节数。 Throws IOException: 如果流不支持搜索,或者发生其他 I/O 错误。 同时,其子类FileInputStream中也继承了skip这个方法。如API中所描述的,skip方法会存在跳过的字节数小于预期的情况。如果不对返回值进行处理的话,很容易忽视这个问题,导致结果错误。最近在看baksmali的源码,其中有一个简单而巧妙的方法来避过skip方法的这个弊端。 在分片上传文件的时候,进行skip,该处理手段非常重要。 FileInputStream in = new FileInputStream(file); int at = offset; while(at > 0) { long realSkip = in.skip(at); if (realSkip == -1) { throw new RuntimeException(file + ": unexpected EOF"); } at -= realSkip; } 分类: Android Pro, Java基础 本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/p/4973042.html如需转载请自行联系原作者 demoblog

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册