-
程序员的价值观与网络的复杂性
2016-08-27 08:25:41网络是极其复杂的,这种复杂包含混沌和不确定性,网络是一个典型的复杂系统。然而网络映射到程序员的心里,它只是一条确定的管道!这种思路会带来问题。程序员与运维/网管之间的斗争依然在继续,在这个无休止的争论...网络是极其复杂的,这种复杂包含混沌和不确定性,网络是一个典型的复杂系统。然而网络映射到程序员的心里,它只是一条确定的管道!这种思路会带来问题。程序员与运维/网管之间的斗争依然在继续,在这个无休止的争论中,我不断切换着自己的角色,这一次,我将站在程序员的对立面。
从我的故事说起,这些故事我故意打乱了时间顺序,请看到此文的人并且知道这些事的,不要往自己身上映射,纯技术讨论,无关褒贬!我的故事一:手机访问慢
那是我刚毕业的时候了,在一家小公司做VOIP,我接手了一个Symbian UIQ程序的开发,这是一个联网的程序,经理的意思是,访问一定要快,绝不能慢。需求很明确,几乎所有的网络程序都是这么个需求。我于是就开始了没日没夜的奋战,我刚毕业时发誓要做一个标准程序员,我觉得这是一定可以完成的。然而,事后证明,这往往是程序员的通病。
...
后来我离职了。
因为,我无法做到访问不慢...其实这不是我的错,这是那个手机的错,那个手机买的带宽太低了,那时没有3G,那时只是GPRS,后来我知道,你只要换一张SIM卡,就快了,然而还是解决不了基站坏了导致的访问慢问题,事实上,我也解决不了由于地震海底缆线受损导致的访问慢问题,那时google还是可以用的...
我耿耿于怀,我离职了,因为我没有完成需求,这个需求是:必须快,不能慢!!PS:这个经理是一个当时有8年经验的老桌面程序(不怎么联网的那种)程序员。我的故事二:弹证书慢
那时的我在搞SSL相关的,而且那个时候我已经是公司里相比其他程序员更懂一点网络的人了,于是很多网络方面的问题大家都会问我。和故事一相反,这里的程序员会认为一切慢的原因都是网络的原因,而不是程序的原因,于是这活儿自然就落到我头上了。
怎么个慢法?我们的服务器是双向SSL认证的,浏览器要上传一张证书,如果有多张,那就要选择,因此会弹出一个选择证书的框,弹这个框从连接开始计时,特别慢!
虽然并不是说我必须解决,但即便友情支持也要尽可能完美,我比较崇尚德国工匠精神,精确,完美!
于是我把自己关在机房一个下午,最终确认这是一个Linux内核BUG导致的问题,与网络无关!出来后眼睛都是疼的。为什么大家会认为这是网络问题,而我第一反应却是程序问题呢?
因为我在只有一跳的自建环境内可以100%重现该问题。
自那以后,我经历了无数次的此类过程,水平也因此逐渐长进,逐渐形成了我的价值观和方法论。
知道我想说什么了吗?
能100%重现的,就不是混沌的,那是确定的事情,按照程序员的思维,确定的事情一定是哪里的一个语句使然!然而网络是混沌的,是不确定的。我的故事三:连接被重置
这可能是最近最近的事情了,我正反两面来讲。
我首先肯定一下自己。
多对多C/S环境,统计数据显示有大量的连接被重置,我第一时间分析的是数据的聚集特征,而不是去搞抓包这种细节。我是对的,因为根本无需抓包,大数据显示发生这类错误的服务器是同一台,和故事二一样,我直接盯上了那台服务器!然后从那台服务器作为一个新的开始,开始新的排查!最终,问题完美确认,请参考故事五。
然后我想说一下同事A。
和我的观点不同,同事A也有自己的方法论,他只是希望去分析抓包,我也照着比划了几下...不同点在于,我是自上而下的分析数据特征,他是自下而上的分析,所以,在这个场景下,我的效率会更加高些。这是为什么呢?因为网络是混沌的,是不确定的,但是主机是确定的,主机上跑的程序也是确定的,自上而下可以瞬间发现主机异常,而分析数据包则会湮没到茫茫海洋!这笔大数据是可贵的,它可以帮你发现每一个客户端的特征,只是还有大部分程序员不知道怎么用这笔数据。我的故事四:nmap扫描
网络上获得任何数据,都是统计数据,都不是精确的,这是程序员所不想看到的事实,然而却必须正视!
多对多C/S环境,必须符合一定规则的客户端才能参与连接,我查出一大批伪造的客户端,但我不能确定还会不会有别的。我的证据是什么呢?程序员可能更希望我能拿出抓包数据板上钉钉,说:看,这就是你们伪造客户端的证据!
可是,一个pcap包能看出什么呢?答案是什么也看不出!
我的方法是nmap。然而程序员可能不太相信nmap的结果,因为中间经历了太多的设备,很多东西都是Guess,不是确定的,不符合程序员的价值观!这也是为什么一帮程序员加班到深夜去Debug,然后来了一个运维一个traceroute就查出问题的原因。程序员宁可相信自己的代码有问题,也不愿猜测是网络有问题,因为代码是确定的,traceroute或者nmap的结果是不确定的。
好吧,说下结论吧,我nmap的结果完全正确。在nmap过程中,我当然也不是一扫定乾坤,我也是扫了大量的地址,然后看数据聚集性的。故事五:运营商不可信
接着故事三,当我查到异常设备后,我是怎么进一步分析的呢?由于异常设备只是一个代理,我需要去找原始主机,通过配置就能找到,很快,几乎不需要时间。然后呢?
然后我没有去查两台机器的日志,而是先去看两台机器的连通性!如果是程序员,为了尽快确认不是自己的问题,肯定会去查日志,查代码版本,查发布...
事实证明这是对的,两台机器之间的单向丢包率达到了90%+。然后呢?然后问题扔出去,就不管了,因为后面的事情我也关不着了,这是运营商的问题。
我为什么就知道连通性有问题,直觉吗?不是!还是那个观点,如果程序有问题,就不会在第二跳代码上发生错误聚集,而是普遍离散。所以一定是网络的问题。故事六:Spanning Tree与网线插反
CCIE真的不是吹的。敲各种命令,然后得到各种结果,还好,我能看懂这些。
2013年年中,我与一群CCIE共事,与其说共事不如说对抗,我在怀疑自己程序问题的同时,他们在证明网络没有问题。最终的结论是,程序没问题,网络有故障。这个故障太低级,以至于CCIE们根本不屑!
网线插反了!
这个故事好像没有任何结论,但事实上,我想说的是,要不是思考过以及搞过一段时间真正的网络,我真的要被那些CCIE给坑惨了!故事七:程序员看pcap包
这个不仅仅是我的故事,是所有程序员的故事。
程序员看数据包,一般都会集中于TCP或者应用层,展开点说不仅仅是看数据包,看日志也一样。而事实上如果已经发现聚集效应,IP头以及MAC头上的信息更加重要,因为IP和MAC是绑定于主机的。
故事八:统计意义
紧接着故事三,当我解决了大量(几乎所有)的连接重置问题后,接连几天平安无事。然而后面数据报表上有出现了连接被重置,于是被要求排查,但是我拒绝了。
拒绝的理由是,这些重置没有聚集效应,且数量太少,没有统计意义。互联网是一个没有法律的世界,如果有人违反了规则,谁也无法阻挡。所以我的理由是,解决这几起异常事件,出力不讨好,可能仅仅就是随机的恶意事件。
网络是一个统计实体,永远不要试图精确化,不然会死得很惨。世界上任何一个地方的任何一个事件都会让TCP/IP网络产生波动,比如英国有个傻逼上厕所忘了带纸,他会打电话给朋友,这么一件小事就会引起TCP/IP网络流量的波动,偶然间让你的数据从0.0035变成了0.0037,这是什么,这是蝴蝶效应!程序员经理会问,相差的那0.0002是怎么回事?然后有个人定位到英国那个傻逼在厕所拉完屎打了个电话...此乃真神!故事九:端到端与骨干网
一个程序员写了一套程序,一个客户端,一个服务端,然后写完了就集成测试,在自己的网络内测试一切良好。然后最终,最终这套程序要部署在两个地点,一个青海,一个上海,结果呢?
其行为完全不符合预期。
我就干过这事,那是很早之前了。
程序员往往会忽略骨干网。因为他们根本没有机会接触真正的网络。真正的网络都是那些技校毕业然后在社会上考了个HCSE或者CCNP的人才会接触的,我就是其中半个,我的另外半身是程序员。
程序员永远都只会把网络当成一条理所当然的管道,当程序的行为与预期不同时,他们(我曾经是”他们“的一员,但现在我只是”他们“的半员)总是期待修改程序就能解决问题,因为程序是唯一他们能控制的,但是运维和网管却看清了一切,虽然也不是100%的看清,但起码比程序员看得清。当程序员越来越多的被那些所谓的”框架“引导到更加上层的位置时,他们失去的却是底层网络基本的知识。
这个现状正如当今的”女司机“一词一样,会开车,但只是简单的开车,没有解决突发情况问题的能力...引发车祸...
作为一个懂点(我很自信比大多数程序懂的更多)网络的程序员,我想说的是,不要当鸵鸟,把头埋在土里忽略网络,不要当”女司机“,只会开不会修...
此文以上,无论褒贬请勿对号入座。涉及到的事情都是真事,但只是想传达一种理念,无关褒贬。
----Gaius Julius Caesar如是说:人们只想看到自己想看到的那部分,那就把这部分给他们看!(同时利用他们看不到的那部分奴役他们) -
IntelliJ IDEA 复杂的重构技巧
2017-12-25 00:00:00本文作者:ice1000 ...但是 IDE 永远不是我们肚子里的蛔虫,有时我们会有复杂到 IDE 不可能...下面我来告诉大家怎么利用有限的 IDE 重构功能, ~~创造无限的价值~~ 处理复杂的情况。复习一下快捷键先复习一下快捷键吧,我本文作者:ice1000 原文链接:http://ice1000.org/2017/12/21/IDEARefactoring/
重构是 IDE 给人类生活带来便利的一个重要方面。但是 IDE 永远不是我们肚子里的蛔虫,有时我们会有复杂到 IDE 不可能直接提供的重构需求。
下面我来告诉大家怎么利用有限的 IDE 重构功能, ~~创造无限的价值~~ 处理复杂的情况。
复习一下快捷键
先复习一下快捷键吧,我们这次就看两个就好。
inline
这个叫
inline
的东西快捷键是 Ctrl+Alt+n。 这个东西的作用是把当前光标上的东西,在代码级别内联掉。按下这个快捷键后,会看到一个弹窗(这个是
inline
一个 Kotlin 方法的弹窗,对于 Java 还多几个选项。 不过这都不是重点啦):我们都默认选第一个,就是在
inline
之后删除被inline
的东西,第二个是inline
后保留。 如果你是在调用处而不是定义处这么搞,第三个选项就可以选,是只inline
这一处。我们一般不管,使用第一个。
rename
这个我就不多介绍了,应该是最常用的快捷键之一了: Shift+F6 。
删除一个被多次引用的空函数
场景
我们知道, IntelliJ 会把 “没有被用到的函数” 标灰(这个 “没有被用到” 的定义其实蛮复杂的,比如你实现了一个接口, 那么这个接口的方法即使没被调用也不会被标灰。这里我就不纠结这个细节了),并且会给出 “Safe delete” 的提示。 这往往不是我们想要的,因为我们看到这个东西的时候, 多半都是刚写完一个函数还没来得及调用的时候。
而我们有时在重构的时候,一个函数里面的东西被全部移出去后,这个函数体就是空的了,而它仍然在多处被调用。 我们这时想删除这个函数,以及它的所有调用处。
fun SymbolList.addGetSetFunction() {
}
比如这个,我在重构 Lice 的时候,就产生了很多上面这种东西。 这个函数被调用了,所以 IntelliJ IDEA 不会给出 “Safe delete” 的选项。
虽然语言是 Kotlin ,但是这就是一个朴素的函数声明,我觉得不需要进行进一步的说明。
private fun initialize() {
addDefines()
addGetSetFunction()
addControlFlowFunctions()
它像这样被不停调用着。
当然,你可以按下 Ctrl 然后点击这个函数,再一处一处地删除。
解决方法
不过我们为什么不试试直接
inline
掉它呢?private fun initialize() {
addDefines()
addControlFlowFunctions()
它的函数体本身就是空的,所以说
inline
掉后,每个调用处就啥都没了。修改大量出现的相同结构
场景
比如,我们有这样的,自己用的库代码(为了让更多人看懂,我在这里使用了 Java):
// code 0
class Val {
private Object o;
public Object getO() { return o; }
}
interface Node { Val eval(); }
然后我们可以通过
someNode.eval().getO()
来获取一个Object
,对吧。 然后想象一下我们有这样的业务代码:// code 1
Object a = xxx.getNode().eval().getO();
xxx.use(yyy.eval().getO());
Val bla = blablabla.eval();
switch (bla.getO().toString()) {
case "2333":
break;
}
...
这是我们现在的代码。
问题
然后我们经过一番小重构,把刚刚的库代码重构成了这样:
// code 0
interface Node { Object eval(); }
直接把
Val
去掉了,然后让这个eval()
直接返回原本装在Val
里面的变量,然后Node
的各种实现也都改了。 这时候我们的业务代码已经是一坨红色了。我们想批量去掉这个
.getO()
的结构,应该怎么办呢?首先我们不考虑查找替换,因为
有这种结构的文件很多(假设有一万个),很麻烦(不过 IntelliJ IDEA 有 “Replace in path” 功能)
有很多其他的叫
getO()
但不需要被重构掉的函数,会受到波及(这才是最主要的)
这也是很常见的原因,对吧。
这时我们就需要技巧性地重构了。
解决方法
首先,我们先把库代码中的
Node
临时性地改成这个样子(也就是说,临时性地把Val
弄回来,只是实现变得不一样了):// code 0
class Val {
public Object getO() { return this; }
}
interface Node { Val eval(); }
注意这里的
getO()
被改成了返回this
。这时我们刚刚的代码中,
.getO()
上的红色已经消失了(毕竟这几乎就是改之前的样子)。然后,我们对 public Object getO() { return this; } 中的 getO() 使用 inline, 这样所有的
.getO()
结构就被消除了(想想为什么,很简单的道理):然后我们 把 Val 重命名为 Object ,然后直接删除 ,这样剩下的代码中用到
Val
的地方也就全部变成了Object
, 也就是我们所期望使用的那个类型啦。另一种情况
上面说的,是针对 “批量删除对于一个方法的调用” 的解决方案。 但我们有时不是想删除,而是增加。这怎么办嘞?
比如,我们现在有上面那段重构完了的代码(which 没有
getO()
)。 我们现在要把每一处eval()
后面加上toString()
(反正就是需要加一层方法调用)。这个也很好解决,我们只需要先把
eval()
随便改成(不是重命名,是直接改)另外一个名字(比如rua
):// code 0
interface Node { Object rua(); }
然后我们可以看到业务代码全红了:
然后我们再写一个叫
eval
的方法,里面返回这个rua
的调用结果再toString()
(就是加上你要的那个方法调用):// code 0
interface Node {
default Object eval() {
return rua().toString();
}
Object rua();
}
这时业务代码已经不报错了。 我们再对这个
eval()
进行inline
,之后就是这个样子的了:然后再把
rua()
使用 IntelliJ 的重命名功能改成之前的eval()
,就一切照旧啦。本文完
祝大家圣诞节快乐。
__________________________________________________
| _ |
| /|,/ _ _ _ / ` /_ _ . _ _/_ _ _ _ _|
|/ / /_' / / /_/ /_, / / / / _\ / / / / /_| _\ |
| _/ |
| ~~** ice1000 **~~ |
|__________________________________________________|
___
/` `'.
/ _..---;
| /__..._/ .--.-.
|.' e e | ___\_|/____
(_)'--.o.--| | | |
.-( `-' = `-|____| |____|
/ ( |____ ____|
| ( |_ | | __|
| '-.--';/'/__ | | ( `|
| '. \ )"";--`\ /
\ ; |--' `;.-'
|`-.__ ..-'--'`;..--'`
:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*:._.:*~*
这是一个来自 coding.net 的惊喜,我在推送代码的时候看到的:
推荐阅读
Spring干货汇总(含Spring Boot与Spring Cloud)
点击 “阅读原文” 看看本号其他精彩内容 -
tcp的复杂机制
2010-02-09 17:35:00懂socket编程的人不一定理解tcp协议,实际上很多计算机编程高手都不一定懂tcp协议,编程高手很多都是对api很理解,对于api下面的机制就不一定理解了,我是一个学网络出身的人,在我会用java或者c写hello world之前我...懂socket编程的人不一定理解tcp协议,实际上很多计算机编程高手都不一定懂tcp协议,编程高手很多都是对api很理解,对于api下面的机制就不一定理解了,我是一个学网络出身的人,在我会用java或者c写hello world之前我就知道了tcp的原理,记得当时为tcp的滑动窗口,慢启动等着迷过,成夜成夜的研究路由协议和交换机原理,仅为理解mss,mtu等等概念,然后白天申请到机房去做实验...后来看了linux源码,看了linux中对tcp/ip协议栈的实现,突然发现竟然是如此复杂,tcp的三次握手在socket编程时是看不到的,但是在内核中却能看到,必须在内核中看到,如果内核都不实现协议栈,那么靠谁实现呢?三次握手在linux中是通过一个状态机来实现的,三次握手完毕后跳出内核的状态机,进入用户空间的socket进程。
典型的tcp协议要求每一个数据段发送之后都要有一个ack回复,然后才能发送下一个数据段,虽然这样能保证数据的可靠传输,但是效率呢?由于tcp是全双工通信,在等待一个数据段的ack恢复之前网络将会闲置,因此效率将会受到极大影响,因此协议提出了滑动窗口子协议,专门负责数据的传输,滑动窗口子协议分为简单的停-等协议,后退N协议,以及选择重传协议三个子子协议,其实三个子子协议可以由一个例程表示,只是一个例程的三个不同情况,比如发送和接收窗口都为1时就是简单的停等协议。三个子子协议都很复杂,只有靠这种复杂的机制才换取了网络链路的高效利用。
-
Qt实现复杂的列表控件
2018-03-28 10:04:21Qt实现复杂的列表控件[日期:2013-04-22]来源:Linux社区 作者:wangtaohappy[字体:大 中 小]有人问,复杂列表控件怎么做?控件布局如下图,求指点思路有高手指点如下,红框圈起来的是QLabel,1个进度条,2个...Qt实现复杂的列表控件
[日期:2013-04-22] 来源:Linux社区 作者:wangtaohappy [字体:大 中 小] 有人问,复杂列表控件怎么做?
控件布局如下图,求指点思路
有高手指点如下,
红框圈起来的是QLabel,1个进度条,2个按钮(toolButton),1个布局,1个QWidget(容器),组成一个widget。
放进QListWidget里。进度条用样式表美化一下,参考:点击这里。
其中主要用这个函数:void QListWidget::setItemWidget(QListWidgetItem * item, QWidget * widget) 然后应用css样式美化。
类似的,如下面的界面也可以借鉴以上思路:
楼主试验,外面大布局可以用QListWidget,然后将listItem写成自定义的控件集合,用函数setItemWidget()加载就好。
可以将自定义的控件集单独写成一个类,然后用这个类生成表项。
代码参考如下:
ui->alarmListWidget->setResizeMode(QListView::Adjust);
ui->alarmListWidget->setAutoScroll(true);
QWidget *wContainer = new QWidget(ui->alarmListWidget);
QHBoxLayout *hLayout = new QHBoxLayout(wContainer);QLabel *alarmIcon = new QLabel(tr("beih"));
QLabel *placeLabel = new QLabel(tr("北京"));
QLabel *videoNumLabel = new QLabel(tr("8"));
QLabel *dateLabel = new QLabel(tr("2013-4-16"));
QLabel *alarmMsgLabel = new QLabel(tr("违章搭建"));
//QPushButton *pDeleteBtn = new QPushButton(QIcon(),tr("delete"));hLayout->addWidget(alarmIcon);
hLayout->addStretch(1);//将空白没有widget的地方分成了若干份,按比例分配
hLayout->addWidget(placeLabel);
hLayout->addStretch(1);
hLayout->addWidget(videoNumLabel);
hLayout->addStretch(1);
hLayout->addWidget(dateLabel);
hLayout->addStretch(1);//将空白没有widget的地方分成了若干份,按比例分配
hLayout->addWidget(alarmMsgLabel);
hLayout->setContentsMargins(5,0,0,5);//关键代码,如果没有很可能显示不出来
// wContainer->setLayout(hLayout);//如果layout在创建时就已经将父窗口指针当参数,那就不用setlayout
wContainer->resize(350,50);
// wContainer->show();QListWidgetItem *alarmItem = new QListWidgetItem(ui->alarmListWidget);
ui->alarmListWidget->setItemWidget(alarmItem,wContainer); -
复杂系统的5个属性
2016-04-05 20:38:11复杂系统往往是由层次结构的形式存在,如果人有表层-肌肉-内脏一样。由一些相关的子系统构成,这些子系统往往又有它们自己的子系统,如此下去,直到最底层的基本组件。 相对本原: 复杂系统基础组件的本质,选择哪些... -
IntelliJ IDEA 复杂的重构技巧(二)
2018-10-13 12:25:02看到大家的反响之后我就感觉那个可能不大亲民,因为很多人连 inline 这功能都不知道(那岂不是把 IntelliJ 用成了记事本), 于是我决定再写一篇讲讲 IntelliJ 已经提供好了的一些复杂的重构功能。 这就不再是需要... -
复杂网络研究的意义
2005-11-17 00:32:00复杂网络研究的意义 clarensis复杂网络的研究,为我们提供了一种复杂性研究的新视角、新方法,并且提供了一种比较的视野。可以在复杂网络研究的旗帜下,对各种复杂网络进行比较、研究和综合概括。首先,网络的现象... -
tcp是一个复杂的协议
2010-04-07 23:14:00tcp是一个很复杂的协议,这是每个人都知道的,但是它是很重要的,超过半数的公司在应届生面试时会提供tcp三次握手的面试题,我当年就碰到了N次,只可惜我对网络比较了解,这件事几乎没有给我带来什么故事。... -
IntelliJ IDEA 复杂的重构技巧(一)
2018-10-14 00:13:11IntelliJ IDEA 复杂的重构技巧 转载 重构是 IDE 给人类生活带来便利的一个重要方面。但是 IDE 永远不是我们肚子里的蛔虫,有时我们会有复杂到 IDE 不可能直接提供的重构需求。 下面我来告诉大家怎么利用有限的... -
复杂网络
2018-04-11 19:44:59一 复杂网络 具有自组织、自相似、吸引子、小世界、无标度中部分或全部性质的网络称之...小世界特性指出:社交网络中的任何一个成员和任何一个陌生人之间所间隔的人不会超过六个. 在考虑网络特征的时候,通常使... -
有人会用java写导出复杂表格吗?或者什么工具类可以实现的
2018-11-15 02:37:18 -
复杂的大数据技术栈
2017-05-20 16:19:35提到大数据,很多人可能都听说过4V - Big Volume, Big Velocity, Big Variety, Big Value,大数据从业人员的工作内容也都和这4个V中的某些内容密切相关。 相比较传统的数据库技术,大数据的技术栈在过去几年取得... -
分解-解决复杂问题的办法
2019-02-28 17:33:34很多人知道刻意练习是最好的学习方法,不断重复地学一项技能,直到学会为止。但是,如何重复地学习某种技能呢? 答案是:将要完成的动作分解为多个彼此独立的小动作,重复地练习...我发现,无论多么复杂的计算机系... -
对于复杂网络解决现实的网络问题
2018-11-26 22:02:20关于复杂网络的应用与发展 复杂网络(Complex networks) 在以往,我们认为网络是通过随机的方式形成的,并且将这些网络成为随机网络,例如在一次马拉松比赛里,参赛人员之间从互相不认识到相互认识,这就是一个随机... -
复杂性思维第二版 一、复杂性科学
2017-10-27 21:44:26一、复杂性科学 原文:Chapter 1 Complexity Science 译者:飞龙 ...2002年,Wolfram 发表了 “新科学”一文,在这里介绍了他和其他人在细胞自动机上的工作,并描述了一种用于计算系统研究的科 -
复杂系统与复杂网络
2009-11-02 17:57:00复杂系统与复杂网络 20世纪90年代以来,以Internet为代表的信息技术的迅猛发展使人类社会大步迈入了网络时代。从Internet到WWW,从大型电力网络到全球交通网络,从大脑神经网络到各种新陈代谢网络,从科研合作网络到... -
复杂对象的组装与创建——建造者模式(一)
2012-04-04 17:35:53没有人买车会只买一个轮胎或者方向盘,大家买的都是一辆包含轮胎、方向盘和发动机等多个部件的完整汽车。如何将这些部件组装成一辆完整的汽车并返回给用户,这是建造者模式需要解决的问题。建造者模式又称为生成器... -
一文教会你如何写复杂业务的代码
2019-09-21 08:28:02了解我的人都知道,我一直在致力于应用架构和代码复杂度的治理。这两天在看零售通商品域的代码。面对零售通如此复杂的业务场景,如何在架构和代码层面进行应对,是一个新课题。针对该... -
springBoot整合MongoDB复杂查询条件的实现
2018-09-04 11:52:46- 不知道是MongoDB国内用的人太少,还是因为最后大家都放弃了,反正国内博客里面资料都是非常过时的东西。 - 还有一点我需要吐槽,MongoDB真的不适合做复杂场景的业务DB,因为MongoDB相对MySQL存在很多不足,其次... -
Kubernetes 真的很复杂吗?
2018-12-22 08:58:00近日,VMware首席工程师、Kubernetes项目创始人之一Joe Beda发表了一篇有关Kubernetes复杂性的精彩推文(https://twitter.com/jbeda/status/993978918196531200)。我建议你们看看这篇推文,里面有一些在我个人... -
设置复杂密码的简单技巧
2019-10-12 11:47:33最近几年互联网发展的越来越好,人们的生活越来越方便,我们可以使用众多的APP,改善我们的生活质量,一些烦恼随之产生,比如众多的APP,我们的用户名和密码为了便于记忆,很多人设为一样的,这个风险是很高的。... -
系统方法——复杂问题的解决方案
2013-10-05 21:53:25系统方法——复杂问题的解决方案 分类: 杂谈2013-10-05 02:43 231人阅读 评论(0) 收藏 举报 解决方案软件 目录(?)[+] 系统方法——复杂问题的解决方案 前言: 传统的... -
一个复杂的nf_conntrack实例全景解析
2017-10-28 08:28:38近期搜集了一些关于iptables,NAT相关的问题,其中最令人觉得麻烦的还是nf_conntrack相关的东西,比如它和NAT的关系,它和state match的关系,它的Helper机制怎么使用等等。 因此决定写一篇随笔来一个情景分析,... -
项目接入实现复杂布局的vlayout
2018-03-08 09:40:25前言V- Layout 是阿里出品的基础 UI 框架,用于快速实现页面的复杂布局,在手机天猫 Android版 内广泛使用电商图让人激动的是,在上个月V- Layout终于在Github上开源!Github - alibaba - vlayout Github在五一假期... -
《最简单的图形与最复杂的信息:如何有效建立你的视觉思维》
2017-01-12 17:02:20对于我这种没有一丁点艺术细菌的人来说,真是获益匪浅,读完这本书,我的艺术细菌增加了 10 万+。 狡猾型和实在型 其中有这么两种作者,一种是狡猾型,一种是实在型。 狡猾型的作者会告诉你 条形图的直条之间... -
【理想流】软件开发究竟是简单的还是复杂的
2011-12-05 00:14:20强调软件复杂的最有代表性的观点来自《人月神话》:Brooks认为复杂性是软件的根本特质,而非偶然特质。强调软件简单性的观点则时见于国内某些MIS开发公司以及外包公司:他们大多时候会把需求分析(业务分析)的权重... -
复杂的正则表达式应该如何构造
2010-08-09 09:48:00文题本来是《如何构造复杂的正则表达式》,但是觉得有些歧义,就感觉正则式本来很简单,我在教人如何将它小事化大一样。正好相反,我的本意是说,即使复杂的正则式也不怕,找出合适的方法,将其构造出来。 ...
-
Glasterfs 分布式网络文件系统
-
响应式编程入门与实战(Reactor、WebFlux、R2DBC)
-
Python下划线命名模式 - 小结(转载)
-
UL 859:2017 Household Electric Personal Grooming Appliances(个人护理)-完整英文版(192页)
-
MaxScale 实现 MySQL 读写分离与负载均衡
-
2019年上半年 软件设计师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
linux基础入门和项目实战部署系列课程
-
-191-4-源码
-
NFS 网络文件系统
-
(单细胞-SingleCell)单细胞标准流程(简化版)
-
axios控制台爆红问题Uncaught (in promise):xxx解决
-
华为HCNA路由与交换eNSP实战(5)RIPv2基础配置
-
JavaWeb之过滤器与监听器
-
ELF视频教程
-
2009年上半年 网络工程师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
2016年下半年 信息系统监理师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
2009年下半年 信息系统管理工程师 上午试卷 综合知识 软考真题【含答案和答案解析】
-
ASHRAE_Extended_Environmental_Envelope_Final_Aug_1_2008.pdf
-
如何利用python做一个简单的天气预报
-
设计需求分析方法与过程