- 对于 C 语言来说,占据了静态存储区,使程序变大
- 破坏封装,函数不是幂等的
- 代码可读性下降
- 多线程程序会造成竞态条件
其实很简单,就是把一段代码中需要依赖的另一个类从这段代码中移出来,然后把生成的结果传递到这段代码中,这就是 Inversion of Control 了
https://stackoverflow.com/questions/3058/what-is-inversion-of-control
Q: Demeter 定律(最小知识原则)说一个单元应该对其他单元了解的知识越少越好,而且应该只能和他的直接相关单元通信(或者说“不要和陌生人说话”)。你会写违反这个原则的代码吗?展示下为什么这个是不好的设计然后修复他。
比如说一个类不应该访问另一个类的数据成员,而应该通过getter方法来访问。当然这样做可能会使运行效率低下。但是比如说另一个类的实现改变的时候,我们不需要改动代码,因为没有依赖。
但是缺少灵活性,实际中当你每次处理一张表时使用这个模式是可以的, 但是当你要处理很多关联表,类继承关系较为复杂的时候就会有很多问题,这种情况你可以使用Data Mapper模式
像是 Django,RoR 都是采用的 Active Record 模式
ref: http://www.jacopobeschi.com/post/active-record-design-pattern
Q: Data Mapper 模式提倡使用一层mapper来在对象和数据库之间传递数据,但是保持了它们两者之间的独立。相反 Active Record 模式直接持久化到数据库中。关于两者你有什么看法?为什么使用其中一个而不是用其中另一个呢?
我们看到它在存数据的时候,没有用$user->save()去存,而是用了另一个类EntityManager去存。也就是说,它的模型$user没有继承一个数据库操作类,$user和数据库完全是分离开的。 它这样做有什么好处呢?$user没有继承一个庞大的基类,变得轻便多了。就好像蜗牛甩掉了重重的壳,变成了蛞蝓。 这是反Active Record人士最重要的攻击点,他们会嫌Active Record性能差。 另外一个就是在Data Mapper模式下,模型,数据操作层,数据库这三者是完全分开的,所以不必一一对应,这样在某些情况下是很灵活的。
ref: http://larabase.com/post/156
A: null 是一个没有值的值,这就是错误。实际上,比如在Python中,我就经常遇到 None object has no method xxx 的问题。
Null Ojbect pattern 就是定义一个空对象,让它来当做当值为空时候的对象,而不要使用Null值来表示空。比如返回空字符串而不是None,避免了检查返回是不是为null的问题。
在一些编程语言,尤其是函数式编程语言中,Option Type 是一个多态的类型,表示的是函数可能返回一个有效的值或者无效的值
ref:
- https://www.lucidchart.com/techblog/2015/08/31/the-worst-mistake-of-computer-science/
- http://www.cnblogs.com/gaochundong/p/design_pattern_null_object.html
- https://en.wikipedia.org/wiki/Option_type
A: 首先,类型系统看起来很好,太复杂了,问题就很多。其次,继承表达了 is-a 的关系,如果遇到要实现两个接口就很复杂。组合的话更加模块化一点。
ref: https://www.zhihu.com/question/49008835
通过在旧系统和新式系统之间放置防损层,将它们隔离。 此层转换两个系统之间的通信,在旧系统保持不变的情况下,新式应用程序可以避免破坏其设计和技术方法。
新式应用程序和防损层之间的通信始终使用应用程序的数据模型和体系结构。 从防损层到旧系统的调用符合该系统的数据模型或方法。 防损层包含在两个系统之间转换所必需的所有逻辑。 该层可作为应用程序内的组件或作为独立服务实现。
ref: https://docs.microsoft.com/zh-cn/azure/architecture/patterns/anti-corruption-layer
A: 这个也是经典问题了,但是实际上感觉并没有卵用,但是大家就是喜欢问
import threading
class SingletonMixin:
_singleton_lock = threading.Lock()
_singleton_instance = None
@classmethod
def get_instance(cls):
if not cls._singleton_instance:
# 其他语言中使用 lock 和 unlock,而 Python 的with语句就很方便了
with cls._singleton_lock:
if not cls._singleton_instance:
cls._singleton_instance = cls()
return cls._singleton_instance
也可以使用装饰器实现
A: 尽量使用 getter 和 setter,而不要直接访问数据成员。当然在 Python 中有更好的方法(properties)
A: 这也太简单了。。正常人哪儿有写重复代码的,基本都是过度封装居多。
- 首先用包管理器,不要手工拷贝代码管理依赖
- 多使用 virtual env 等虚拟环境工具
- 使用 docker 打包镜像
肯定最好别用。。
比如说对于一个函数来说,可以接受不同类型的值,但是,输出得时候要注意保证自己的输出是有效的。
def add(a, b):
a = int(a)
b = int(b)
return a + b
查询:当一个方法返回一个值来回应一个问题的时候,它就具有查询的性质; 命令:当一个方法要改变对象的状态的时候,它就具有命令的性质;
通常,一个方法可能是纯的Command模式或者是纯的Query模式,或者是两者的混合体。在设计接口时,如果可能,应该尽量使接口单一化,保证方法的行为严格的是命令或者是查询,这样查询方法不会改变对象的状态,没有副作用,而会改变对象的状态的方法不可能有返回值。也就是说:如果我们要问一个问题,那么就不应该影响到它的答案。实际应用,要视具体情况而定,语义的清晰性和使用的简单性之间需要权衡。将Command和Query功能合并入一个方法,方便了客户的使用,但是,降低了清晰性,而且,可能不便于基于断言的程序设计并且需要一个变量来保存查询结果。
在系统设计中,很多系统也是以这样原则设计的,查询的功能和命令功能的系统分离,这样有则于系统性能,也有利于系统的安全性。
一旦一个函数被抽像出来并实现了,那么使用函数的人就不用关心这个函数是如何实现的,同样的,一旦一个类被抽像并实现了,类的使用者也不用再关注于这个类的内部是如何实现的。
ref: https://coolshell.cn/articles/4535.html
耦合性与内聚性是模块独立性的两个定性标准,将软件系统划分模块时,尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。
有个例子很容易明白:一个程序有50个函数,这个程序执行得非常好;然而一旦你修改其中一个函数,其他49个函数都需要做修改,这就是高耦合的后果。
ref: https://www.cnblogs.com/robnetcn/archive/2012/04/15/2449008.html
因为 C 是从0开始的,大多数语言都受C的影响,另外就是C接近硬件,0表示的是偏移量
- 有了测试用例以后重构更容易,而重构可以带来更好的代码
- 测试更深入细节,可以更好的帮助思考
ref: http://www.jamesshore.com/Blog/How-Does-TDD-Affect-Design.html
内聚是应该在一起的,而耦合是不应该在一起的因为设计失误而在一起。
我同意,代码应该尽量是自解释的,而不是借助于注释才能明白
我觉得以下情况下才需要添加注释:
- 解释了业务逻辑和总体设计,这往往也是文档的一部分
- 采用了特殊的用法
- 算法比较复杂,代码无法解释清楚
这个问题也太抽象了吧,架构是设计的实现。。
- 测试定义了代码完成的标志
- 测试是你代码如何使用的文档
- 面向测试编程可以让你保持专注
C++ 支持多重继承,而在 Java 中允许一个类去实现多个 interface。使用这些方法对于代码的正交性有什么影响吗?使用多重继承和实现多个 interface 有什么区别吗?使用委托和使用继承有什么区别吗?
多重继承的不好就不用多说了吧,尽量避免继承。。
貌似意思是把业务逻辑都写在数据库里,这得多奇葩呀。。不过银行系统里似乎的确是这么用的,厉害啊
OO 的好处:
- 限制对数据成员的访问,减少代码耦合
- 提供了一个抽象层,类是对现实世界的事物的一个很好抽象
这个问题太抽象了
Python:GIL、性能慢、2 和 3不兼容
两个方面回答,一方面,为什么之前函数式编程不流行,函数式编程性能往往不高,例如垃圾处理等,这时候大家更愿意使用贴近硬件的 C 语言等 另一方面,函数式编程没有副作用,更好地适应并发高的情形。可以证明正确性。多核处理器的出现等等。方便实现高阶函数
闭包和类都创建了一个独立的作用域,其中定义的函数都可以访问这个空间内的变量,闭包创建的作用域在函数执行结束之后依然是有效的
function() {
var a = 1;
console.log(a); // works, -> 1
}
console.log(a); // fails, -> undefined
function outer() {
let a = 1
function inner() {
console.log(a)
}
return inner
}
let fn = outer()
fn() // -> 1
ref: https://stackoverflow.com/questions/36636/what-is-a-closure
def get_counter():
count = 0
def counter():
count += 1
return count
return counter
def sum(l):
ret = 0
for i in l:
ret += i
return ret
def sum2(l):
if len(l) == 0:
return 0
if len(l) == 1:
return l[0]
return l + sum2(l[1:])
函数可以向其他变量一样被传递
ref: https://stackoverflow.com/questions/5178068/what-is-a-first-class-citizen-function
filter([1, 2, 3, 4], lambda x: x % 2 == 0)
静态类型系统是指的变量绑定的类型在生命周期内不可变,而动态类型系统则相反。
强类型指的是两个互相操作的变量必须类型匹配,而弱类型则会自动转换。
比如在弱类型的 JS 中:
let a = "1" + 1 // a = 2
而在强类型的 Python 中:
In [1]: a = "1" + 1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-1-c5310317b555> in <module>()
----> 1 a = "1" + 1
TypeError: must be str, not int
实际上好多人分不清楚,什么是动态类型,什么是弱类型。
在开发大规模的软件的时候,使用静态强类型语言会好一些,这样编译器就可以做好多的检 查工作。
可以通过队列或者RPC来实现通信
可以让两个两个模块使用同一个名字
啰嗦。在语言上比较繁琐以及架构上各种过度设计。
太抽象了吧
Referential trasparency 指的是通过函数的参数就可以推断出函数的结果。比如下面两个函数
def add(a, b):
return a + b
MSG = 'hello '
def greeting(name):
return MSG + name
Pattern Matching 相对于 switch 更加灵活,switch 只能使用常量匹配,pm 可以根据类型、值等多种方法匹配
把异常和控制结构混在一起,可能会引起混淆。而且可能会鼓励用户把一些常见的错误也归 类为异常,比如打开文件。
异常本质上是一个不知道会跳到哪里去的 goto。
好处是强迫程序员在编写代码的时候就处理每一个错误,坏处是这样会混淆代码的核心逻辑
ref: https://golang.org/doc/faq#exceptions
不是, 模板特例化之后是不同的类
接口定义的是类的行为,而构造函数属于实现细节。如果允许的话,会有如下问题:如果一个类实现了两个接口,该如何调用构造函数呢?
首先,如果这个项目是可以停掉的,那直接停掉,迁移完毕之后验证数据就好了 如果这个项目不能停掉,可以按下面的步骤
- 更改代码,数据开始双写新旧数据库
- 更改读取代码,开始灰度读取新数据库数据
- 把历史数据导入新数据库
- 灰度下掉老数据库
预期会有数据不一致,性能问题等
因为 null 表示的是没有值,它不和任何值相等
ACID 是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)的缩写,几乎所有的数据库引擎都支持他们,关于这个话题,你了解多少?
一个支持事务(Transaction)的,必需要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。
-
原子性 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
-
一致性 在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。具体来说就是,比如表与表之间存在外键约束关系,那么你对数据库进行的修改操作就必需要满足约束条件,即如果你修改了一张表中的数据,那你还需要修改与之存在外键约束关系的其他表中对应的数据,以达到一致性。
-
隔离性 隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
-
持久性 在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。 由于一项操作通常会包含许多子操作,而这些子操作可能会因为硬件的损坏或其他因素产生问题,要正确实现ACID并不容易。ACID建议数据库将所有需要更新以及修改的资料一次操作完毕,但实际上并不可行。
目前主要有两种方式实现ACID:第一种是Write ahead logging,也就是日志式的方式。第二种是Shadow paging。
在使用WAL的系统中,所有的修改都先被写入到日志中,然后再被应用到系统状态中。通常包含redo和undo两部分信息。
ref: http://blog.csdn.net/shenwansangz/article/details/47614759 https://www.cnblogs.com/hzmark/p/wal.html
导出数据库,确保升级失败后能够重建数据库。把变更动作写成一个脚本,然后提交到仓库中。然后执行升级。
if (_AllCustomers == null) {
_AllCustomers = ExpensiveDataCall();
}
return _AllCustomers; // Was: _Customers, not sure if by design.
缺点是得到的数据可能是滞后的,以及更新策略的设计
https://softwareengineering.stackexchange.com/questions/278210/is-lazy-loading-always-required
举个例子,我们数据库中有两张表,一个是Customers,一个是Orders。Orders中含有一个外键customer_id,指向了Customers的主键id。
想要得到所有Customer以及其分别对应的Order,一种写法是 SELECT * FROM Customers;
对于每一个Customer: SELECT * FROM Orders WHERE Orders.customer_id = #{customer.id}
这样我们实际对数据库做了N+1次查询:选择所有Customer一次得到N个Customer,对于N个Customer分别选择其对应的Order一共N次。 所以,一共执行了N+1次查询,这就是N+1问题
N+1问题的一般解决方法
使用Left Join一次性取出所有数据:SELECT * FROM Customers LEFT JOIN Orders on Customers.id = Orders.customer_id
。 这样虽然取出的数据相对多一些,但是只需要一次执行
PS:感觉数据库所谓的几个范式优点纸上谈兵,如果完全按照这些范式设计的话,性能就成渣了,互联网公司实际上极少用join。不过产品使用 hive 查询数据倒是经常用 join。
ref: http://kevinsun.logdown.com/posts/1069599
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST where time>10 and command<>"Sleep"
或者设置日志
[mysqld]
slow-query-log = 1
slow-query-log-file = /var/log/mysql/mysql-slow.log
long_query_time = 5
log-queries-not-using-indexes = 1
数据规范化的主要目的是消除冗余信息,但是往往会对性能造成影响。如果性能更重要的话,应该放开规范化。
ref:
- https://stackoverflow.com/questions/934577/should-i-normalize-my-db-or-not
- https://stackoverflow.com/questions/1102590/what-exactly-does-database-normalization-do
- http://www.25hoursaday.com/weblog/2007/08/03/WhenNotToNormalizeYourSQLDatabase.aspx
蓝绿部署:https://www.v2ex.com/t/344341
因为大多数的 NoSQL 数据库都是分布式的,所以很难保证在任何时间都是完全一致的,但是可以保证在一定时间最终一致。
不一致是否可接受取决于客户应用程序。Vogels给出了一个网站的例子,例中真正重要的是“用户感知到的一致性”,也就是让不一致窗口——即“更新发生时刻到任何观察者都一定能观察到更新后数据的时刻之间的时间段”——“小于顾客对下一页面加载时间的期待”,这样更新就可在预期发生下一次读取的时刻之前传播到整个系统。
一致性有不同程度:
强一致性。在更新完成后,(A、B或C进行的)任何后续访问都将返回更新过的值。 弱一致性。系统不保证后续访问将返回更新过的值,在那之前要先满足若干条件。通常条件就是经过一段时间,也就是不一致窗口。 最终一致性。存储系统保证如果对象没有新的更新,最终(在不一致窗口关闭之后)所有访问都将返回最后更新的值。
ref:
- https://stackoverflow.com/questions/10078540/eventual-consistency-in-plain-english
- https://www.zhihu.com/question/20113030
一致性 (Consistency):一个写操作返回成功,那么之后的读请求都必须读到这个新数据;如果返回失败,那么所有读操作都不能读到这个数据。所有节点访问同一份最新的数据。 可用性 (Availability):对数据更新具备高可用性,请求能够及时处理,不会一直等待,即使出现节点失效。 分区容错性 (Partition tolerance):能容忍网络分区,在网络断开的情况下,被分隔的节点仍能正常对外提供服务。
理解CAP理论最简单的方式是想象两个副本处于分区两侧,即两个副本之间的网络断开,不能通信。
如果允许其中一个副本更新,则会导致数据不一致,即丧失了C性质。 如果为了保证一致性,将分区某一侧的副本设置为不可用,那么又丧失了A性质。 除非两个副本可以互相通信,才能既保证C又保证A,这又会导致丧失P性质。
CAP 理论并不是简单的三选二,而是至少保证P,然后在CA中二选一。P指的是分区容忍性,也就是网络分区,比如两个数据中心之间的网络断掉的情况如何提供服务的。所以CAP应该理解为当P发生的时候,A和C只能而选一。也就是当发生网络分区的时候,如果我们要继续服务,那么强一致性和可用性只能2选1。
当发生网络分区的时候,在如果要提供服务就可能无法保证强一致性,如果保证一致性,就不一定能提供服务。实际上强一致性不一定是必须的,往往满足了最终一致性就可以了。
ref:
- https://www.zhihu.com/question/64778723
- http://www.infoq.com/cn/articles/cap-twelve-years-later-how-the-rules-have-changed
- http://www.hollischuang.com/archives/666
- 传统的 SQL 数据库需要使用 ORM
- NoSQL 一般开始设计的时候就考虑了分布式的问题
- 非结构化的数据越来越多
ref:
NoSQL 放弃了 SQL 中提供的原子性等诸多特性,所以非常适合多机实现。
比如说:
- Dropping Atomicity lets you shorten the duration for which tables (sets of data) are locked. Example: MongoDB, CouchDB.
- Dropping Consistency lets you scale up writes across cluster nodes. Examples: riak, cassandra.
- Dropping Durability lets you respond to write commands without flushing to disk. Examples: memcache, redis.
ref:
基本不会采用 MongoDB。文档数据库中的好多特性现在 MySQL 都已经实现了,比如说 JSON Field
没用过 SVN,但是 SVN 好像是服务端分支,而 Git 在本地分支就可以了
没用过 SVN
有两个分支是长期存在的,master 和 dev,日常开发在dev 分支上,当 dev 分支上的可以 发布新版本之后,可以合并到 master 分支。master 分支上的总是稳定版本
除此之外还有一些临时的分支:
- 功能分支
- 发布分支
- Hotfix 分支
功能分支从 dev 分支上分叉出来,并且最终要合并会 dev 分支,名字可以随便起
发布分支可以从 dev 分支,开发完成后合并到 dev 或者 master 分支(不太理解为什么要有这种分支),名字 release-*
Hotfix 分支用于修复 bug,可以从 master 中分叉出去,但是注意要同时合并回 dev 和 master,名字 hotfix-*
https://nvie.com/posts/a-successful-git-branching-model/
顾名思义,就是改变当前 commit 的上一个节点(base node)
没用过 SVN
- 更好地利用多核
- CPU、内存、IO 之间速度有差异,并发可以更好地让速度块的部分不会被速度慢地拖累
- 多线程代码可能会使用全局变量
- 多线程代码之间的通信
当两个线程/进程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件。
COUNTER = 1
def add():
COUNTER = COUNTER + 1
ref:
当两个以上的运算单元,双方都在等待对方停止运行,以获取系统资源,但是没有一方提前退出时,就称为死锁。
进程长时间没有分配到自己所需要的资源
- 发生死锁
- 调度算法有问题
它保证了每一次调用都可以在有限的步骤内结束。避免出现进程饥饿的情况。
ref:
- http://www.cnblogs.com/yunnotes/archive/2013/04/19/3032290.html
- https://www.jianshu.com/p/bddfce1494d6
当被调用的系统花费时间过长的时候,可以让被调用的系统回调来通知处理结果。或者被调 用的系统不关心处理结果。
比较慢?
pubsub 支持多个消费者
Say I'm your Project Manager, and I'm no expert in programming. Would you try explaining me what Legacy Code is and why should I care about code quality?
"Individuals and interactions over processes and tools" and "Customer collaboration over contract negotiation" comprise half of the values of the Agile Manifesto. Discuss
Organize a development team using flexible schedules (that is, no imposed working hours) and "Take as you need" vacation policy
How would you manage a very high turn over and convince developers not to leave the team, without increasing compensation? What could a Company improve to make them stay?
Imagine your company gives you 1 month and some budget to improve your and your colleagues' daily life. What would you do?
What is CQRS (Command Query Responsibility Segregation)? How is it different from the oldest Command-Query Separation Principle?
The so called "multitier architecture" is an approach to design a client–server system aimed to keep physically and logically separated presentation, application processing, data management and other functions. The most widespread of the multitier architectures is the three-tier architecture. Would you discuss the pros and cons of such approach?
Someone gave the name "The "C10k problem" to the problem of optimising network sockets to handle over 10.000 open connections at once. While handling 10.000 concurrent clients is not the same as handling 10.000 open connection, the context is similar. It's a tough challenge anyway, and no one is expected to know every single detail to solve it. It may be interesting to discuss the strategies you know to deal with that problem. Would you like to try?
CGI 每个请求就要新建一个进程,而进程的创建开销是很大的。
在第三方 API 上再抽象一层,避免直接依赖对方代码或者 API。尽量使用开源软件,实在 不行还可以自己改。
PubSub 本质上是一个多生产者多消费者的队列。当消息量大的时候,如果没有很好地缓冲 机制,很可能造成缓冲溢出导致丢消息。另外这种模式也没有定义很好地持久化机制。
Does unity of design imply an aristocracy of architects? Putting it simple: can good design emerge from a collective effort of all developers?
https://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own
除了密码之外,再使用额外的设备提供一个密码,比如 OTG 或者硬件密码等。
只在开发环境记录敏感日志,在线上要关闭这些日志
ref:
# 如果 user_id = '1; drop table users;'
cursor.execute('select * from users where id = %s', % (user_id))
如果完全信任用户的输入,用户可能输入 <script>
的标签的形式注入自己的脚本。更严
重的是,如果 cookies 没有设置成 http only 的,那么用户的 cookies 很可能也被偷取。
ref:
CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!
浏览器在请求每个域名的时候会带上对应的 cookies,可以通过 img 标签的 src 等伪造 GET 请求,或者通过 js 来伪造表单提交的 POST 请求,这样就相当于代替用户请求了服务 器。
可以通过在页面上增加一个隐藏的 crsf_token 来,然后每次请求都校验这个 token 是不是合法。
ref:
在 http 等明文协议中,中间人(代理服务器、路由器)等等可以偷听、篡改数据包,而通 信双方都无法察觉。
https 通过密钥通信,而密钥只有通信双方知道,也就无法查看或者篡改数据包。
可以使用 https
ref:
函数是编程的每一个函数都是可验证的,可以证明程序是正确的。因为函数都没有副作用, 所以也天然适合并发。
谷歌通过广告挣钱,通过 Chrome,谷歌可以成为默认的搜索引擎,其他家也都类似
打开一个新的 tcp 链接需要三次握手,也就是 3xRTT 的时间,相比于复用一个已经打开的 链接的成本几乎为零。
ref:
没查到相关资料
不可变对象在并发应用种特别有用。因为他们不能改变状态,它们不能被线程干扰所中断或者被其他线程观察到内部不一致的状态。
不可变对象没有副作用、更容易缓存、也不会产生 null 引用。
ref:
使用不可变值每次都需要创建一个新的对象,可能开销很大。
比如说有两种对象:
- book
- author
每个人可能有很多本书,每本书也可能有好几个作者,所以数据库中就需要建三个表,
book
, author
, book_author_ref
, 而一些 ORM 则帮助做了这些映射。
创建一个连续内存块,进行连贯、大量、随机的有意义内存访问。这几点缺一不可,否则不能保证整块内存被 尽可能的放入Cache。在这种情况下,当内存块能够被整块放入Cache时,平均访问速度会显著的快。观察随 着内存大小提高,平均访问时间的跃升点,即可估计Cache大小。
ref:
tcp 是第四层的协议,是面向字节流的。而 http 是 第七层的协议,基于 tcp,但是是面 向报文的。
客户端渲染减轻服务器负担,可以把页面逻辑写在js中,不需要总是重载页面。但是不利于 SEO,同时可能造成白屏现象。
可以参考 TCP,IP 协议就是一个不可靠的协议,但是基于 IP 的 TCP 协议是可靠的。
TCP 有编号确认机制,还可以重发。
Imagine you want to remove the possibility to have null references in your preferred language: how would you achieve this goal? What consequences could this have?
As a software engineer you want both to innovate and to be predictable. How those 2 goals can coexist in the same strategy?
Say your Company gives you one week you can use to improve your and your colleagues' lifes: how would you use that week?
There is an aesthetic element to all design. The question is, is this aesthetic element your friend or your enemy?
How would you introduce Continuous Delivery in a successful, huge company for which the change from Waterfall to Continuous Delivery would be not trivial, because of the size and complexity of the business?
Let's have a conversation about "Reinventing the wheel", the "Not Invented Here Syndrome" and the "Eating Your Own Food" practice
What does an Operating System do when it has got no custom code to run, and therefore it looks idle? I would like to start a discussions about interrupts, daemons, background services, polling, event handling and so on.
协同过滤
function hookupevents() {
for (var i = 0; i < 3; i++) {
document.getElementById("button" + i)
.addEventListener("click", function() {
alert(i);
});
}
}
回答:
每一个元素点击都会提示 3,因为闭包捕获了 i,最终结果是 3
ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if (li.getClass() == lf.getClass()) // evaluates to true
System.out.println("Equal");
Java 中的泛型并没有把每个不同的模板参数特例化成不同的类,而是简单地把类型抹掉了。
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
pop 的时候没有缩小占用空间,而且也没有析构函数
public class Formatter {
private Service service;
public Formatter(Service service) {
this.service = service;
}
public String doTheJob(String theInput) {
String response = service.askForPermission();
switch (response) {
case "FAIL":
return "error";
case "OK":
return String.format("%s%s", theInput, theInput);
default:
return null;
}
}
}
重构:
public class Formatter {
}
public class TheService {
private final FileHandler fileHandler;
private final FooRepository fooRepository;
public TheService(FileHandler fileHandler, FooRepository fooRepository) {
this.fileHandler = fileHandler;
this.fooRepository = fooRepository;
}
public String Execute(final String file) {
final String rewrittenUrl = fileHandler.getXmlFileFromFileName(file);
final String executionId = fileHandler.getExecutionIdFromFileName(file);
if (executionId.equals("") || rewrittenUrl.equals("")) {
return "";
}
Foo knownFoo = fooRepository.getFooByXmlFileName(rewrittenUrl);
if (knownFoo == null) {
return "";
}
return knownFoo.DoThat(file);
}
}
function()
{
HRESULT error = S_OK;
if(SUCCEEDED(Operation1()))
{
if(SUCCEEDED(Operation2()))
{
if(SUCCEEDED(Operation3()))
{
if(SUCCEEDED(Operation4()))
{
}
else
{
error = OPERATION4FAILED;
}
}
else
{
error = OPERATION3FAILED;
}
}
else
{
error = OPERATION2FAILED;
}
}
else
{
error = OPERATION1FAILED;
}
return error;
}
这是典型的箭头形函数,可以参见酷壳的这篇文章:https://coolshell.cn/articles/17757.html
This section collects some weird questions along the lines of the Manhole Cover Question.