软件设计

软件设计css

  1. 必定是建立订单的时候填充market字段,我曾经一度打算在回调的时候再根据回调方来填充Market,可是若是没有回调呢?Market这样的标志性字段必定要依赖于靠谱的操做;
  2. 对于重载方法要注意,尤为套调用的重载方法,对于某些核心校验必需要放置在里层方法调用,不然由于重载都是public出去的,均可以被外界调用,若是在外层方法实现校验,里层重载方法被外界直接调用,校验会被跳过;考虑CheckMarket是放在CreateOrder(String encryptedString)仍是CreateOrder(OrderInfo orderInfo)中实现?前者解析加密字符串调用后者,最后想通了是要放在后者中进行校验;
  3. 设计的时候必定要在设定的场景中多走几遍,这样作的目的是跳出实现,要把实现放在应用中进行验证;本质:任何实现都是一个流程的一个环节,其意义在于上下游,而不是实现自己;
  4. 获取玩家信息其实使用旧有的接口便可,可是我却搞混了玩家信息表和订单表;分析问题就是要极端:向上谋求大的方向,向下到根(表,字段级别),谋求准确;
  5. 腾讯之因此二次验证是由于:担忧回调返回信息没有接收到,没有扣款;这个机制不一样于其余平台,其余平台若是没有收到,将会续发;腾讯这样处理实际上是把球抛给了游戏服务器;
  6. OpenId已经修改成String类型真的是百搭啊,做为众多市场使用的字段,int的范围仍是过小了;这个让我想到了CreateOrder的返回值,对于适配众多状况的字段、方法类型必定要考虑百搭的类型;Factory入口参数已经由枚举改成了字符串类型,由于我发现了一个问题,须要枚举和显示字符的互转,这样每增长一个市场,同时须要维护枚举和常量,太不靠谱了;这样看来单独一个类里面封装常量实际上是比枚举具备更大的描述能力;CreateOrder之初设计的返回int,这个返回值过小了,包含的信息量远远不够,尤为是对于支持众多市场;好比面对腾讯的支付机制,返回的就是一个JSON串,因此对于通用的接口设计返回值的格式要复杂一些,描述能力强一些;
  7. 支付市场流程中,支付服务器回调游戏服务器,其实主要的用意是通知游戏服务器添加金币,增长道具;
  8. 我已经修改成统一使用BasePaymentInfo做为参数,这样的替换大大减小了代码,以前须要字典对参数进行接收,而后再PaymentService在取出参数进行处理;
  9. 其实不少时候一个空的基类,做用就是用于实现开闭原则的闭,BasePaymentInfo里面什么都没有;可是BaiduPaymentInfo以及QihuPayemntInfo都是继承自它;
  10. 前天我在和Steven在谈论是否须要把支付拿成一个dll的时候,Steven讲到他能够保证部署的时候不出错;可是这样上纲上线有意义吗,由于是否就是保证修改代码的人必定可以取到最新的代码,是否部署的人必定就是Steven?最小的部署就是可以尽可能不要依赖于人的因素,或者尽可能减少人的因素;
  11. PaymentService的价值在于对于支付这个领域提供了一层的封装,对于外界的调用而言只须要知道一个Pay接口就能够了,而不须要知道还有一个Factory,还有一个Manager
  12. 今天测试发现了一个Bug,更新Bill表以后直接操做更新了PlayerData表,这里有个问题:若是Bill表查到的数据为空,是不须要更新后者的,结合另一个Bug,支付失败了是不须要更新PlayerData的;其实这两步操做不是代码关联,实际上是:两步操做,牵涉到了两部分业务(逻辑),这种跨域的操做必定是要有一个分析和校验过程,是否具有关联性;这两个问题提供了一个视角:你再来作项目不要只是看到代码,而是要抽象到一个更高的角度,从"模块化"(业务、逻辑)以及全流程来看待开发自己;
  13. 建立订单等操做仍是要放置在BasePaymentManager,而不是Service,由于建立订单逻辑多是会变得,你须要让PaymentManager的实现类可以重写;若是放置在Service里面就很差处理了;其实开闭原则,讲的是对变化开放,对稳定关闭,换句话讲,就是对于开放接口是关闭,内部实现是开放,好比对于Service(领域入口)必须是关闭的,须要设计参数都是具备必定的伸缩性,可是对于内部实现,manager是哪一个,应该具备扩展性;
  14. 对于接口的伸缩性,好比服务器增长了一种状况为,有的客户端可能须要改代码,享受新增长的功能,有的客户端就不须要改代码,旧有的功能就能够了,这个时候接口标准是不变的,不须要享受的也不须要改动;保证了请求多样性;
  15. 对于sessionKey的保存最开始打算保存在redis中,可是动物快跑,水浒传等牙根就没有Redis,另外,sessionKey是一个很重要的变量(Confirm环节须要拿去和支付服务器作支付确认的),不是那种丢了就丢的重要信息,必定是要保存在数据库中的;我添加了一个EXT_INFO字段用于存放sessionKey信息;
  16. 微信支付Demo中的WXPayData是键值对形式(封装了toXmltoJson等方法),里面包了一个SortDictionary方法;这种数据结构扩展性很好;很大程度上能够和空基类相提并论;缺点是没法进行编译时报错;
  17. 微信平台公共平台的开发由于没法调用外网;因而我把得到路径封装为一个方法,若是是测试环境(根据配置文件数据),我将会返回一个模拟功能的ashx文件进行数据返回;这样能够测试下去了;
  18. 在非Web环境下,Controllersession对象为空;这个时候为了可以进行单元测试,我设计了一个CaseBase类,这个类会根据配置文件配置,测试环境下(Test工程跑步),就采用内置Diction进行数据保存;正式Web环境下就采用session进行保存;为了保证全局可访问,不随着controller消亡而消失,Diction对象须要声明为static变量;
  19. 说到了单元测试,我以为在biz层的设计必定要和前端的神马(Web技术)技术解耦,就是一个biz框架,提供了那些功能,Web也好remoting也好,仍是Webservice都是能够直接调用;这个很独立的第三方;
  20. 做为类库,能够考虑返回值为OperationResult,内部发生异常不要抛出来,让调用方判断是抛出仍是过去;
  21. 单元测试若是测试的机制和待测试代码机制同样也就失去了测试了意义;
  22. 梳理清楚业务:1.调用的场景;2.操做了什么表;3.过得了什么信息(字段)4.总体流程是怎样的;
  23. 掌握一门技术,要首先搞懂几个问题:1.这个技术解决了什么问题;2.优点是什么,适合什么场景;3.缺点是什么,不适合什么场景;4.提供功能的原理是怎样的;才算是了解了一门技术;
  24. 架构师的世界:一切尽在掌握,对于各个生命周期阶段都可以切入和控制;这样便于扩展,这就须要两种工具:封装和隔离(好比MVC很大的好处就是能够控制view,好比我想要把view缓存,就能够经过在contrroller里面作,可是传统的ASP.Net若是想要对view缓存就不是很直观;这也是为何要封装日志接口;Session接口;好比serverlet是被tomcatstandwrapper封装而不是直接使用;归拢,核心系统套一个壳子隔离和第三方;为何过时自动删除redis不多的应用场景,由于删除不少时候须要业务逻辑判断以及处理;因此不少时候采用的判断时间戳,到期了再如何如何;
  25. 今天在使用印象笔记发现一个问题,搜索以后,用户不知道怎么回到初始状态,其实咱们作系统设计不少时候都会忽略行为的回朔,就是任何动做以后,都要让用户可以很容易回到某种状态,至少应该是回到初始状态,最后还好,在左侧菜单找到了"笔记"的图标,返回了初始页面,可是这个图标并不明显,不论怎样,evernote仍是考虑到了这一点,搞了一个总回头的图标恢复状态;
  26. 需求驱动架构,架构驱动架构,架构驱动测试,测试驱动开发;
  27. 测试用例的设计,作到一个方法只测试一个点;
  28. 对入口参数校验真有意义,好比buildcommand方法,若是传入的cebidentifiercommand不一致,报错,问题一下清晰了;
  29. 刚才纠结于getdatabuf是否要若是null返回一个new对象,后来发现不须要:就像c++遭人骂就是由于行为里面作了太多的事情,职责清晰,尽可能简单;
  30. 框架,是自成体系,只不过有些缺失部分,须要进行填充,而后框架就成为了系统,系统,是流程,生命周期完备的东西;
  31. 开发天天至少应该有39%的时间是在思考,学习;
  32. 架构/框架的本质是定义行为,定义行为的前提是定义好模块以及模块功能,让这些模块经过组合可以完成系统的功能;
  33. 关系,关系,关系!作设计很重要的一点就是理清楚关系,从session池的处理(链接到同端的连个session怎么区分),到通知参数(多个文件状况如何通知应用),都在说明,设计就是要捋顺对象间关系,面向对象就是构建世界,貌似简单,可是世界对象间不少关系是隐含的,并不显式,有些关系能够忽略不用构建,考虑,可是有些确实要挖掘。
  34. 框架思惟,何为大者,就是看到的点是大的方面,对于系统的理解和开发过程都要放到一个框架思惟来进行设计
  35. 什么是框架?框架就是一种机制,保证某些维度功能的机制(好比开发效率,性能,隔离原则等);
  36. 每当你在设计缓存的时候,考虑数据丢失是否能够,是否有机制从新获取,这种机制是否实现;
  37. 其实一件事情没有作完就开始下一件事情,寄托于将来完善,能够,可是必定是一个成品,而不是概念品,由于,你将来再作这件事情最大的成本就是,你须要从新进行梳理思路。续传就是这样,单元测试作完了,没有结合测试,回过头来再完善,发现思路全忘了,还要重头来;
  38. 每当你引入一个新的对象,好比任务的临时ID,都要考虑他的生命周期,以及他的生命周期和别的对象生命周期之间的影响,其次要把生命周期和事件捋顺了,好比任务的生命周期是INIT-RECEIVING-REVCOMPLETE-SENDING-SENDCOMPLETE,其中INIT是发生在DATA2HandlerReceving是发生在DATA指令等。
  39. 认证,用意就是证实这个用户存在,受权,就是这个用户能够干这个事情。
  40. 都是提供功能,和业务逻辑相关的称之为服务,和业务逻辑无关的称为基础设施
  41. 作架构设计必定要从重要的,重点的地方设计,不然你的设计极可能就卡在这些地方。好比当时对于断点续传考的不全面,直接致使了开发到了后面的问题;
  42. switch有一个缺点,容易忘记break, 并且若是多了,其实结构并不清晰,还不如else if;
  43. string有一个巨大的问题,就是他实际上是一个弱类型,首先比较容易出错,是用==仍是用equals,其次复制了一个常量,忘记更名字了,除非运行时测试,不然不自知。这一点是枚举的好处。
  44. PraCommand处理的时候须要知道发送方是否就是目的端。能够有两个地方进行处理,目的端发现本身是目的端,则更新PraCommandisTail字段;第二个地方是接收方来判断,发送方是否和路由的最后一个设备一致。后来我选择的是前者,这是由于这样可以有效的减小判断;好比做为转发端,转发十个端那么判断十次;可是做为目的端而言其实只须要判断一次便可。这是一种分压/分流的机制。
  45. 想好了,一鼓作气写,减小手敲,增长拷贝,那个写perl的哥们,c++代码写的时候就是绝大多数是拷贝
  46. 今天发现了一个方法居然套了五层方法,taskfilestorage里面居然判断任务状态的逻辑在里面,想一想也是醉了,当初这个类定位就是将任务信息放置到文本文件而已。做为设计,必定要划分好类职责,这种实现方法的机制不要超过三层。
  47. 传输项目作到如今,我最大的心得就是1.控制异常抛出范围;2.并发控制3.设计的重要性,设计的重要性在于重点难点的设计,全局的考量。
  48. 今天发现觉得写入进度信息到任务文件的异常,致使后续的将文件片进行保存的核心操做都没有进行处理,在写代码的时候必定要将功能进行划分域,域和域之间不要有本质影响。
  49. 必定要使用自定义的异常,而且尝试抛出他,其实在日志中很容易发现异常的信息;不处理的异常其实并非坏的事情,吞咽异常不少时候是隐藏问题。因此经过自定义的异常,并让他抛出来而且catch打印出来,其实很方便跟踪问题。
  50. 线程必定要考虑到异常处理,不然这个线程将会挂掉,特别是那些定时任务的。
  51. 抽象成服务/组件的一个巨大好处就是封装性,好比断点续传,如今就是逻辑散落在各个类中,与之相反,若是有专门的一个或者几个类处理,那么就能够看到续传类的全貌了。
  52. 考虑设计上面的闭环,好比向monitor队列中放入一个元素就要考虑如何撤掉,哪几种可能须要撤掉。
  53. 对于相似于发送反馈的处理,内部异常就处理掉,不要外抛,不要由于这种无关主业务的操做致使后续操做没法进行。
  54. handler是事件,service是服务,事件组装服务,服务要拥有比较好的封装性,好比全部的和断点续传相关的操做都要封装在一个类中。服务封装1.代码集中度高,内部高耦合成型;2.好测试,前提保证服务入参简单,不要让外部业务污染服务,好比传入了一个session,就意味着测试的时候须要构建一个session。我忽然以为本身这种设计和领域驱动有些接近。
  55. 我发如今方法体的开始把重要的入参打印出来是一个很好的习惯。
  56. 生态,掌握一门技术,其实自己并不难,可贵是掌握它的生态。
  57. 传输的多线程,异常抖动状况下仍是有问题。其实最核心的代码就是在于client.put, client.executeNext两个方法,分明就应该好好的规划线路分析如何来处理并发、异常抖动等状况,可是我却没有很好地树立这个地方,你看到不是一端代码,一个函数,看到的应该是一个流程,分支,以及这个分支的各个节点。
  58. 对象中的属性和方法的存取也是有权限的,好比对于taskgetclient,其实只有发端任务才有权限,收端任务无权访问此属性,不然将会报异常,因此,设计属性和方法的时候必定要考虑成员权限问题,不管是设计仍是使用。
  59. 从新下发,这个策略很好,刚才我就在纠结发现一份报没有有效性怎么处理,其实就让运维人员删除后从新下发就结了。其实不少时候,不要纯技术思惟,当发现技术没法很好的解决一些问题,考虑一下是否能够采用手工的方式来进行处理;
  60. 作项目设计,首先是识别对象,好比三部的项目,包括单位,节点,文件等等,在识别对象的时候同步要把核心属性识别出来;而后是识别行为和关系,两者能够同步交替进行,OO三剑客以后,项目搞掂了。
  61. 不要纠结底层区别,由于区别不大,占用内存之争不是颇有意义;
    实例和静态的根本区别在于概念;面向过程年代,你们都是静态函数,单例模式是面向对象提出以后的设计模式,若是一个类里面的函数是和这个类有机的一体的,则是单例,若是类只是做为容器(好比工具类),那么就是静态。
    网上一则比喻很恰当,一我的的胳膊腿,面容是和一我的息息相关的,并且因人而异,这个时候,须要实例,若是说人类所属的纲目,这些泛华的内容则是静态的,不由于每一个人的不一样而不一样,那么就是静态的。
  62. 什么样的类是单例,什么样的类不是呢?若是实例千篇一概,好比配置(文件)类,整个应用程序都是使用一个配置文件,那么他的映射的ConfigProperties类就应该是单例;若是说不同,好比文件类File,每一个文件都是不一样的,那么就是一个实例;
  63. 不管是加密机,传输机,仍是组装机,他们最好不要知道任务内容,这样,每一个机的业务逻辑最纯洁,至于任务状况,由总控来调度任务管理处理,总控只是负责调度,任务只是维护任务信息,各类机只是负责对文件粒度的处理便可。
  64. 架构一个很重要的意义在于将复杂问题分解。因此架构的价值在于有效合理识别,归类和分解。明白此处,系统分析以及架构基本成了。
  65. 作开发要想明白一些事情,好比数据的处理,数据要放在内存,仍是放在能够持久化的缓存,仍是放在数据库中?这些都是在设计的时候要进行设计的。
    再好比,controller中的返回数据是封装在个类里面,仍是要散列的存放;这种数据的组织形式也是要考虑
  66. 今天充分体会到了设置类型为List<T>的实惠了;原本在HiveController中调用historyService.findList()返回的是arrayList;可是后来发现数据结构其实应该是Queue,因而改成了LinkedList,可是这样的改动其实对于Controller毫无影响。因此这种泛型在封装向上面有很好的应用,可使用类的函数返回值,本类函数返回值中应用反应,做为屏蔽封装部分的复杂性。
  67. 前者是非等幂操做;须要进行判断是否有重复的;可是对于后者则是几乎是等幂的;不过可能还有一个点须要check就是并发问题,你所改的是否是脏数据。这个在数据库层面能够进行判断;可是若是是修改配置,这个就要看配置是否支持。总之每一个操做以前都要首先想一想是否有须要校验的地方。安全是大事,其实技术到了高手以后,就是看谁的安全意识和解决方案更合适了。
  68. 以前调试结果有点问题,苦于没有找到缘由;后来看到原来code中这个地方有一个print,一会儿就定位到了是由于loaddataset的问题(书中代码和github代码不一致)。这里说明了输出日志文件的重要性。日志必定要具备其可跟踪性,可追溯性。html

技术前端

  1. 自定义异常很大程度上解决了测试异常的问题;好比如今使用resultCode来判断错误类型,若是使用异常的话彻底能够利用Exception进行处理;另外.netExceptedException真的好弱啊,只能判断类型,Message都指定不了,难道只能try...catch中增长assert吗?
  2. 多线程开发,对于每个线程而言,代码都是独立的,他们不过是按照顺序去执行附加的代码;可是代码段自己是共享的,这里系统会为每一个线程分配本身的参数堆栈,若是是代码段内部的变量(局部变量),各自堆栈维护,不会有任何问题;操做有交集,可是操做数据都是本身的数据;这个就像过去的合厨作饭同样,炉子是公用的,可是锅碗瓢盆,菜果都是本身的,及时彼此作饭有交集,用的都是公用的炉子,空间,可是作出来的都是本身的饭菜;可是,对于共享的变量就不同的:由于他会变,并且不会由于你的操做而变,好比合厨的液化气,你用完以后,第二次再用存量就会少,由于别人(别的线程)也会用;因此,当你想要对这种公共变量操做的时候,为了保证操做间原子性,须要为操做加锁(锁上合厨的门);
  3. Buddy描述的关系,并不一点是要好友才使用SFS中的Buddy,可以用Buddy的关系来描述的均可以使用它;
  4. 8bit = 1byte;可是位(bit)是计算概念,二进制运算;可是byte是表示概念,一个byte表示能够容纳一个ascii码值,2byte能够表示为容纳一个汉字;
  5. 1KB = 1024byte1GB = 1024KBbitbyte8进制,可是BKBKBGB则是10+3E进制(1024);
  6. USE_FLG价格索引后,查询效率当即提升了;
  7. 证书加密的本质:服务器交给客户端一把钥匙一把锁;客户端将会使用这把钥匙来打开服务器端发送的"黑匣子",客户端会用这把锁来锁住"黑匣子"而后寄给服务器端;客户端一样也会把一把钥匙和锁头给服务器端;
  8. 构建一个性能解决方案列表:insert而不用updateDB迁移到memcacheEFSaveChange致使性能降低,那么就采用存储过程;查询昵称致使性能问题,那么就一次性把ID导入到内存中来;
  9. ASCII中有空"",代码是0,这也是为何字母排序机制中,"逐位比较"机制中,"aaa"是要小于"aaaa"的缘由,到第四位进行比较的时候,前者是空,ASCII值为0,后者是"a",值为65;备注,0ASCII值为48
  10. MIMEMultipurpose Internet Mail Extensions)最初是应用在电子邮件上面,能够根据MIME信息进行指定应用程序打开传输内容;后来这种技术被浏览器扩展,早期的浏览器是不支持传输非ASCII内容的;后来扩展了MIME技术到浏览器上面,这样就能够经过HTTP协议进行传输各类应用类型文件,浏览器将会根据MIME信息安排指定的应用程序打开/运行;好比文本文件text/htmlpdf文件application/pdf,浏览器看到了application/pdf就会使用内嵌的pdf插件进行打开;调查MIME的由头是application/octet-stream类型,后来这种MIME类型是任意二进制文件;
  11. SCSI: Small Computer System Interface,定义了系统和设备交流的标准,好比和硬盘,CD-ROM,另一种经常使用的接口常见的接口是IDE
  12. cpu版本x8632位,x86_64则是intel为了兼容AMD64位指令而设计的;x64则是AMD的架构了;IA-64Intel输惨了;Windows2008原本答应开发基于IA-64的操做系统,结果好久都没有完成;
  13. 负载均衡有两种,均衡操做,集群中的读写分离就是这种均衡(基于主从服务器);还有一种是访问压力均衡,好比一致性算法,NginxIP_Hash等;
  14. 设置为cache-controlmax-age以及Expire关键字以后,在各个浏览器张行为一致的是经过页面点击连接二次连接会缓存页面,以及新的Tab页面输入一样地址后发送请求,都将不会触发二次请求,直接用本地缓存文件;对于F5刷新,各个浏览器都是每次都从服务器取值;对于IEfirefox而言,在地址栏敲回车不会由于二次请求,chrome依然会进行二次请求;使用firefox以前各类状况都会向服务器发送请求,后来诊断肯定是由于配置中将缓存空间设置为0致使;
  15. 另一种相关的配置是LastModified,这个指令是response的时候,服务器给客户端的,这样下次向一样的资源发出请求的时候,将能够直接返回304告知客户端什么都没有改变,这样就能够放心大胆的使用客户端缓存内容了,可是在和业务后台相关的处理中,须要代码来判断是否有改变,须要controller实现LastModified接口,并实现方法进行业务判断;
  16. Ctrl+F5,强制重服务器取出新的内容;其实就是在Request头中添加了Programa:no-cacheCache-Control:no-cache;其实你若是使用FF就会发现,若是设置缓存空间为0,那么不管你是地址栏敲回车,仍是页面连接,F12里面的"网络"面板都会感应出请求信息,可是一旦你设置了空间,就会在该面板中显式要你刷新;这就说明了前面的状况是由于根本就没有向服务器发出请求,走的本地缓存;
  17. Keey-alive容许了客户端发送请求后,并不立刻断开Http通道(TCP通道),多个Http请求公用一个TCP通道很大程度上减轻了服务器为每一个请求建立进程处理的成本(另外还有三次握手,Http是基于TCP的);由于一个Html,除了页面元素,还有cssjs都是要经过http进行屡次请求完成的;可是keep-alive还有一个缺点,就是若是不能及时释放将会致使资源浪费;因此Keep-alive通常都是指定timeoutmaxmax指的是一个通道最多可以接受的请求;timeout指的是断开链接的时长;若是在timeout时长内请求数达到了max上限,将自动断开链接;
  18. hosts文件中看都有一个注释掉的::1,这个实际上是表明ipv6地址,ipv6采用128位进行表示,格式为8个四位16进制组成,1234:5678:90abc:def0:1234:5678:90ab:cdef,为了兼容Ipv4地址,ipv4地址将被表示为0000:0000:0000:0000:0000:0000:192.168.0.1ipv4地址占据两段,这意味着ipv432位的);对于前面的六段四位0,能够简单表示为::192.168.0.1;因此你看到的hosts文件中的::1其实就是为ipv6地址作准备的;
  19. "()"在正则表达式中表明模式,前面能够是一堆^*.,可是真正闪亮登场的确是"模式",模式表明着真正要匹配的部分,对于replace方法而言,要替换的就是模式部分,若是表达就是模式能够省略()
  20. Java里面当心转意须要使用\\,由于字符串里面内容才是表达式,好比替换掉全部括号里面内容replaceall("\\([^(]*\\)",""),或者在表达式中先后添加()也能够,语义更加准确,表示模式
  21. 使用filebuffer来封装hasHMAP<string, queue<commandexchangbuffer>>,可是后来发现这种封装损失了对于key的遍历好处,判断某个是否存在还须要遍历,而不是contains,十分不优雅;
  22. xmlns:xsi是指web.xml遵照xml规范;xsi全名:xml schema instance
  23. xsi:schemaLocation是指具体用到的schema资源, 是命名空间和xsd文档配对出现,校验xML是否合法,就是到此得到xsd文件,对节点属性进行check的;若是你把xml:context删掉了,spring将会作xML文档校验,对于<context>节点就没法进行解析,编译将会出错;
  24. spring多作了一点,若是你的xsd文件没有指定版本号,那么就不从网址下载,而是从本地的springjar文件中,找相应的文件进行处理;避免由于网络缘由没法得到xsd文件而启动失败
  25. spring拦截器,经过mapping以及exclude-mapping,可以指定那些请求须要拦截,那些请求不须要拦截;拦截器须要指定处理bean,对于拦截的请求,交给bean进行处理。
  26. spring的配置文件头中指定了不少命名空间;
  27. 事务的acid

    原子性,帐户转移,A帐户转到B帐户,a转了10元,B必定会接收到10元,要么成功,要么全失败;ios

    一致性,A少了10元,B多了10元;c++

    独立性,原子操做未完成,B在操做过程当中是不会发现事务过程;git

    持久性,对于修改是持续可见的。github

    1. 我如今更加发现抽象美妙之处,使用niosession,完美解决tcpsession以及datagRAMsession问题。
    2. 对于有中文的地方,不管是序列成流,仍是反序列化,都须要进行编码设置。
    3. eclipse引用web工程

a) web工程的deployment assembly中将deploy修改成/,这样处理是为了打包的时候外面不须要套一个WEB-INF。web

b) 主工程引用该web工程,保证开发时引用工程的类可见,在主工程的deploy assembly中add->project->选择web工程,默认是将工程打包成war,而后能够手工修改成jar,这保证了运行是类能被加载。正则表达式

c) 切记要把被引用的工程要用到的jar包拷贝到主工程的lib下面redis

  1. 调错于其余
  1. 今天使用log4Net,每条记录都被打了两条,个人第一反应是代码执行了两边,可是实际上是由于log4Net配置的问题,配置了两个logger对象(root以及一个自定义的logger对象);
  1. 状态,当初不该该图省事采用commanidentifier,应该从新定义一套定义,语义仍是不太同样;
    1. 刚才看到一个问题,总控调用传输失败,看到的异常是初始化失败,后来才知道,传输是经过一个线程起来的,在初始化过程当中报了异常,只是throw了,并无记log,致使后续再调用传输类,报初始化错误,因此多线程起来的异常必定要记录,它抛出的异常并无主线程来捕获;
相关文章
相关标签/搜索