Long Luo's Life Notes

每一天都是奇迹

By Bertrand Russell

I

Like most of my generation, I was brought up on the saying “Satan finds some mischief still for idle hands to do.” Being a highly virtuous child, I believed all that I was told and acquired a conscience which has kept me working hard down to the present moment. But although my conscience has controlled my actions, my opinions have undergone a revolution. I think that there is far too much work done in the world, that immense harm is caused by the belief that work is virtuous, and that what needs to be preached in modern industrial countries is quite different from what always has been preached. Every one knows the story of the traveler in Naples who saw twelve beggars lying in the sun (it was before the days of Mussolini), and offered a lira to the laziest of them. Eleven of them jumped up to claim it, so he gave it to the twelfth. This traveler was on the right lines. But in countries which do not enjoy Mediterranean sunshine idleness is more difficult, and a great public propaganda will be required to inaugurate it. I hope that after reading the following pages the leaders of the Y. M. C. A. will start a campaign to induce good young men to do nothing. If so, I shall not have lived in vain.

像大多数同代人那样,我受过这句谚语的教诲:“恶魔总捉弄懒汉”。作为一个循规蹈矩的孩子,我深信所受的一切教诲,并具有一种促使我勤恳工作至今的良心。这种良心虽然支配着我的行动,但我的观念与过去却有天壤之别。我想在当今世界上工作过于繁重,工作即美德这一信念导致了极大的危害,现代工业国家需要宣扬的东西与历来所宣扬的截然不同。大家都知道一个到那不勒斯旅行的人的故事,当他看到12个乞丐躺着晒太阳时(这是发生在墨索里尼时代之前),想施舍一个里拉给其中最懒的一个。当场 11 个名丐一跃而起求对,于是,他把里拉给了第 12 个。这位旅行者所作所为当然无可厚非。在那些享用不到地中海阳光的国家,悠闲非同小可,需要大加广泛宣传方能开此先河。我希望基督教青年会的领袖们读了以下篇章后,开展一场运动,劝导善良的年轻人无所事事。倘若如此,我总算不会虚度此生。

Before advancing my own arguments for laziness, I must dispose of one which I cannot accept. Whenever a person who already has enough to live on proposes to engage in some everyday kind of job, such as school-teaching or typing, he or she is told that such conduct takes the bread out of other people’s mouths, and is, therefore, wicked. If this argument were valid, it would only be necessary for us all to be idle in order that we should all have our mouths full of bread. What people who say such things forget is that what a man earns he usually spends, and in spending he gives employment. As long as a man spends his income he puts just as much bread into people’s mouths in spending as he takes out of other people’s mouths in earning. The real villain, from this point of view, is the man who saves. If he merely puts his savings in a stocking, like the proverbial French peasant, it is obvious that they do not give employment. If he invests his savings the matter is less obvious, and different cases arise.

在陈述我的懒惰主张之前,我必需排除一种无法接受的看法。当一个人已经可以维持生活所需,他仍筹划着从事某项日常的工作,如教员或打字员,人们就会告诉他(她):这样做等于从他人口中夺走饮食,因而是不义之举。如果这一论点可以成立,那我们只消游手好闲就可能饱食终日了。这样说的人忘记了一个事实:一个人所赚来的通常供他花费,而其消费之行为又为别人提供了就业机会。只要一个人不断将其收入用于消费,那他为别人提供糊口之食的数量就与他从别人口里夺得的数量一般多。如此看来,真正的罪人是节俭者。就像众所周知的法国农民那样,假如他把节约下来的钱放进袜筒里,显而易见这钱并不提供就业的可能;如果他这钱用来投资,情况就不会如此简单,结果也将完全不同。

阅读全文 »

By Bertrand Russell

Francis Bacon, a man who rose to eminence by betraying his friends, asserted, no doubt as one of the ripe lessons of experience, that ‘knowledge is power’. But this is not true of all knowledge. Sir Thomas Browne wished to know what song the sirens sang, but if he had ascertained this it would not have enabled him to rise from being a magistrate to being High Sheriff of his county. The sort of knowledge that Bacon had in mind was that which we call scientific. In emphasising the importance of science, he was belatedly carrying on the tradition of the Arabs and the early Middle Ages, according to which knowledge consisted mainly as astrology, alchemy, and pharmacology, all of which were branches of science. A learned man was one who, having mastered these studies, had acquired magical powers. In the early eleventh century, Pope Silvester II, for no reason except that he read books, was universally believed to be a magician in league with the devil. Prospero, who in Shakespeare’s time was a mere phantasy, represented what had been for centuries the generally received conception of a learned man, so far at least as his powers of sorcery were concerned. Bacon believed—rightly, as we now know—that science could provide a more powerful magician’s wand than any that had been dreamed of by the necromancers of former ages.

英国一位靠出卖朋友而声名大噪的人——弗兰西斯·培根曾说:“知识就是力量。”这无疑是一句成熟的经验总结。托马斯·布朗爵士曾想弄清希腊神话中的海妖究竟唱什么歌,然而即使他确实清楚了,也不能帮他从一个地方长官提升为国家的高级行政长官。培根心目中的知识是指我们所说的科学知识。在强调科学的重要性时,他陈腐地承继阿拉伯和中世纪早期的传统,把知识看作主要由占星学、炼金术和药物学组成,这些都是科学的分支。一位精通这些学科的学者就是获得魔术般力量的人。11 世纪初,教皇西尔维斯特二世除了读些书外,并没有别的理由,就被普遍地看作是一个与魔鬼结盟的魔术师。普罗斯帕罗,在莎士比亚的时代只是一个虚构的人物,但几个世纪以来却代表着人们普遍接受的学者的概念,至今就其法力而言是人们所关注的。培根相信——正确地说,就如现在我们所知道的——科学能够提供比从前巫师任何幻梦还更有力的魔术师的魔杖。

The renaissance, which was at its height in England at the time of Bacon, involved a revolt against the utilitarian conception of knowledge. The Greeks had acquired a familiarity with Homer, as we do with music hall songs, because they enjoyed him, and without feeling that they were engaged in the pursuit of learning. But the men of the sixteenth century could not begin to understand him without first absorbing a very considerable amount of linguistic erudition. They admired the Greeks, and did not wish to be shut out from their pleasures; they therefore copied them, both in reading the classics and in other less avowable ways. Learning, in the renaissance, was part of the joie de vivre, just as much as drinking or love-making. And this was true not only of literature, but also of sterner studies. Everyone knows the story of Hobbes’s first contact with Euclid: opening the book, by chance, at the theorem of Pythagoras, he exclaimed, ‘By God, this is impossible’, and proceeded to read the proofs backwards until, reaching the axioms, he became convinced. No one can doubt that this was for him a voluptuous moment, unsullied by the thought of the utility of geometry in measuring fields.

培根在世时,英国的文艺复兴达到高峰,它包含一种对功利主义的知识概念的反抗。希腊人之熟悉荷马,有如我们熟悉音乐厅的歌曲,由于他们欣赏荷马,而不觉得是在忙于追求学问。但16世纪的人若不首先具备相当的语言学知识,就不能着手研究荷马。他们敬佩希腊人,并且又不愿意置身在他们的欢乐之外;因此在读那些古典著作时,他们总在仿效希腊人。在文艺复兴时,学习是生活乐趣的一部分,如同饮酒或性爱一佯。不仅对文学是这样,对那些较严肃的学科来说也是如此。人们都知道霍布斯首次接触欧几里德几何学的故事:一次他偶然翻开书,读到毕达哥拉斯定理,他大声叫道:“上帝,这是不可能的。”于是回头继续读它的证明,直至读到公理时,他才信服了。没有人会怀疑,对霍布斯来说,这一时刻如同耽迷酒色,然而想到几何学在测量土地中的效用,这种情绪被纯化了。

It is true that the renaissance found a practical use for the ancient languages in connection with theology. One of the earliest results of the new feeling for classical Latin was the discrediting of the forged decretals and the donation of Constantine. The inaccuracies which were discovered in the Vulgate and the Septuagint made Greek and Hebrew a necessary part of the controversial equipment of Protestant divines. The republican maxims of Greece and Rome were invoked to justify the resistance of Puritans to the Stuarts and of Jesuits to monarchs who had thrown off allegiance to the Pope. But all this was an effect, rather than a cause, of the revival of classical learning, which had been in full swing in Italy for nearly a century before Luther. The main motive of the renaissance was mental delight, the restoration of a certain richness and freedom in art and speculation which had been lost while ignorance and superstition kept the mind’s eye in blinkers.

确实,文艺复兴发现了古典语言与神学相关的实际用途。新感受到的古典拉丁文的最初成果之一,就是不再相信编造的教皇教条和康士坦丁的捐赠。在拉丁文圣经和希腊译文圣经之间出现的偏差,使得希腊文和希伯来文成为新教神学家准备争论的一个必要组成部分。希腊与罗马的共和主义被用来证明清教徒与斯图亚特王朝、耶稣会会员与那些不再忠顺于教皇的君主之间的对抗是合理的。但所有这一切都是路德以前在意大利将近一个世纪自由发展的古典学术之复兴的结果,而不是其原由。文艺复兴的主要动机是精神上的欢愉,是复兴在艺术和思维中曾经出现过、但后来由于无知和迷信蒙住了我们的心灵而失落的那种丰富而自由的精神。

阅读全文 »

By Long Luo

今天重新刷了下手机,结果之前的备份都是2个月前的,刷完机我就想了下,我手机必备App是哪些呢?

列出了下面这张必备App清单:

新闻

  1. ZAKER: 查看新闻,根据你的爱好订阅文章
  2. 新浪微博:作为微博的重度用户,微博的媒体属性很强,大于其社交属性。我的不少朋友已经告别微博了,但是我还是喜欢微博。与其在微信上与熟悉的人聊天,不如在微博上和陌生人交流。
  3. 网易新闻:交互做的很好,163评论常有亮点。

SNS·社交

  1. QQ: 不用说。超级App,超好的用户体验,本土化,非常强大。
  2. 微信:不用说。腾讯系的很多产品都极大的提高了我们的工作效率和生活效率,一定要用好他们。
  3. 微博:我用微博主要是学习和了解别人的很多观点,还能够结交很多朋友。
  4. LINE:主要是微博和微信的熟人太多,有些东西不好在朋友圈里吐槽,但LINE没有一个熟人,所以可以很方便的在朋友圈里吐槽发泄:-)
  5. LinkedIn:工作商务类的,也有很多干货。

阅读·电子书

  1. 知乎日报:打发碎片时间,同时了解很多各行各业的知识。
  2. 知乎:重度知乎用户,可以看到更大的世界,拓展你的思维界限。
  3. 多看阅读:电子书,在阅读体验我个人觉得是最好的,书的资源很多而且也不是很贵。

理财

  1. 支付宝:不用说。
  2. 招行手机App:主要用的都是招行卡。
  3. 招行信用卡:平常能刷信用卡的地方绝对使用信用卡。

消费·购物

  1. 手机淘宝:Shopping
  2. 京东:买书,购物等
  3. 美团:看电影,吃饭,订餐等O2O

股票证券类

  1. 广发证券:目前炒股的账户在广发。
  2. 自选股:腾讯系出品的一款炒股软件,美中不足的是交易不支持广发证券。
  3. 东方财富:炒股和市场行情。

交通出行

  1. 百度地图:国内最好的地图产品,对于我重度地图爱好者是真爱。
  2. Google地图:在国内被百度地图秒杀,但国外的话就是Google地图了。
  3. 爱帮公交:公交地铁线路图,还可以离线查询。
  4. 12306:火车出行必备

电子邮件

  1. QQ邮箱:很好用的一个电子邮件客户端,同时对Gmail的支持性很好。
  2. 邮箱大师:网易出品的一个邮箱客户端,这2个都可以。

时间管理·便签

  1. FitMemo: 非常轻量级的一款便签类,美中不足的是好久没有更新了,不支持云同步功能。
  2. Any.Do:支持多平台同步,非常好的时间管理App,用了就知道。
阅读全文 »

By Long Luo

上次在迅雷面试的时候,遇到了一个算法题,题目是:

有一个很长很长的字符串,全部都是由大写字母组成,要求求出其中每个字母在这个字符串中出现的次数。 不允许使用STL中的方法。

当时拿到这个题目,我首先想到了以下几个方法:

  1. 穷举法,一个个比较,最后算出每个字母出现的次数,这种方法可行,但不轻巧与优雅。
  2. 每个字符与’A’想减,会得到一个,统计下这个值出现次数,和方法1类似。(事后回顾这个已经很接近了,但是还是没能完美解决。)

其实这个题目,事后回顾起来,是比较简单的,但遗憾的是,当时未能在规定时间内解答出来,导致未能通过面试,拿到Offer,在此将这个题目记录下来。

重新认真解答这个题目。

How?

其实这个题目有一个很简单的解决方法,新建一个数组,大小为26,将字符串中每个字符都与'A'相减,得到的就是每个字母在数组中的元素下标值,我们最后得到的这个数组就是每个字母在这个字符串中出现的次数。

根据以上分析,可以写出如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.algorithm.alphabetSort;

/**
* 有一个很长的字符串,其中都是一些字母,求其中每个字母出现的次数(大小写区分)。
*
* @author luolong
* @date: 2015-04-12 00:54:17
*
*/
public class AlphabetSort {
private static String str = "AWQEYIOAHDHDKKLDLAHFHJALAFHANNAFGJCXCKBZCQIEOPADHAZBZVCFGCSHDJCKCLDMDHFAKAIIAYQO";

private static int[] outArray = new int[26];

public static void main(String[] args) {
AlphabetSortString(str);
printSortArray(outArray);
}

public static void AlphabetSortString(String str) {
char cTemp;

for (int i = 0; i < str.length(); i++) {
cTemp = str.charAt(i);

outArray[cTemp - 'A']++;
}
}

private static void printSortArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
char c = (char) ('A' + i);
System.out.print("" + c + "=" + arr[i] + " ");
}
}

}

引申与扩展一

如果字符串不仅仅是大写字母,而是大小写字母都存在的情况下,那应该如何写呢?

其实也很简单,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
if (cTemp >= 'A' && cTemp <= 'Z') {
/**
* 大写字母
*/
outArray[cTemp - 'A']++;
} else if (cTemp >= 'a' && cTemp <= 'z') {
/**
* 小写字母
*/
outArray[cTemp - 'a' + 26]++;
} else {

}
阅读全文 »

By Long Luo

最近在学习Java多线程时,遇到了一个下面的笔试题,题目如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
编写一个程序,程序会启动4个线程,向4个文件A,B,C,D里写入数据,每个线程只能写一个值。 
线程A:只写A
线程B:只写B
线程C:只写C
线程D:只写D

4个文件A,B,C,D。

程序运行起来,4个文件的写入结果如下:
A:ABCDABCD...
B:BCDABCDA...
C:CDABCDAB...
D:DABCDABC...

网上搜索了下,好像还是一个Google笔试题,这个问题涉及到的知识点有:多线程, 并发, , 线程间通信

个人分析过程:

  1. 创建4个线程;
  2. 每个线程在输出时都需要加锁;
  3. 操作文件的代码要加锁;
  4. 一个线程完成之后,通知下一个要执行的线程;

根据以上分析,可以写出如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
package com.imlongluo.Practise;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Practise {

public static void main(String[] args) {

final Task task = new Task();

/** 创建4个线程,同时启动 */
/**
* Thread A
*/
new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
task.outputA();
}
}
}, " Thread A").start();

/**
* Thread B
*/
new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
task.outputB();
}
}
}, "Thread B").start();

/**
* Thread C
*/
new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
task.outputC();
}
}
}, "Thread C").start();

/**
* Thread D
*/
new Thread(new Runnable() {

@Override
public void run() {
for (int i = 0; i < 10; i++) {
task.outputD();
}
}
}, "Thread D").start();
}

/**
任务类
*/
public static class Task {
/**
创建一个Lock锁对象
*/
private Lock lock = new ReentrantLock();

private BufferedWriter bw1 = null;
private BufferedWriter bw2 = null;
private BufferedWriter bw3 = null;
private BufferedWriter bw4 = null;

private int ctl = 0;

/**
* Condition: 线程条件
*/
private Condition cond1 = lock.newCondition();
private Condition cond2 = lock.newCondition();
private Condition cond3 = lock.newCondition();
private Condition cond4 = lock.newCondition();

private boolean[] outputThisRound = { false, true, true, true };

public Task() {
try {
bw1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(
"/Users/luolong/Code/Android/workspace/MultiThreads/A.txt"))));
bw2 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(
"/Users/luolong/Code/Android/workspace/MultiThreads/B.txt"))));
bw3 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(
"/Users/luolong/Code/Android/workspace/MultiThreads/C.txt"))));
bw4 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(
"/Users/luolong/Code/Android/workspace/MultiThreads/D.txt"))));
} catch (Exception e) {
e.printStackTrace();
}
}

public void outputA() {

lock.lock();

try {
while (outputThisRound[0]) {
System.out.println("outputA begin to await!");
cond1.await(); //阻塞A线程
}

if (ctl % 4 == 0) {
bw1.write("A");
bw1.flush();
} else if (ctl % 4 == 1) {
bw4.write("A");
bw4.flush();
} else if (ctl % 4 == 2) {
bw3.write("A");
bw3.flush();
} else if (ctl % 4 == 3) {
bw2.write("A");
bw2.flush();
}

outputThisRound[0] = true;
outputThisRound[1] = false;

System.out.println("outputA signal outputB!");
cond2.signal(); //唤醒B线程
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}

}

public void outputB() {

lock.lock();

try {
while (outputThisRound[1]) {
System.out.println("outputB begin to await!");
cond2.await();
}

if (ctl % 4 == 0) {
bw2.write("B");
bw2.flush();
} else if (ctl % 4 == 1) {
bw1.write("B");
bw1.flush();
} else if (ctl % 4 == 2) {
bw4.write("B");
bw4.flush();
} else if (ctl % 4 == 3) {
bw3.write("B");
bw3.flush();
}

outputThisRound[1] = true;
outputThisRound[2] = false;
System.out.println("outputB signal outputC!");
cond3.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void outputC() {
lock.lock();
try {
while (outputThisRound[2]) {
System.out.println("outputC begin to await!");
cond3.await();
}

if (ctl % 4 == 0) {
bw3.write("C");
bw3.flush();
} else if (ctl % 4 == 1) {
bw2.write("C");
bw2.flush();
} else if (ctl % 4 == 2) {
bw1.write("C");
bw1.flush();
} else if (ctl % 4 == 3) {
bw4.write("C");
bw4.flush();
}

outputThisRound[2] = true;
outputThisRound[3] = false;
System.out.println("outputC signal outputD!");
cond4.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}

public void outputD() {
lock.lock();

try {
while (outputThisRound[3]) {
System.out.println("outputD begin to await!");
cond4.await();
}

if (ctl % 4 == 0) {
bw4.write("D");
bw4.flush();
} else if (ctl % 4 == 1) {
bw3.write("D");
bw3.flush();
} else if (ctl % 4 == 2) {
bw2.write("D");
bw2.flush();
} else if (ctl % 4 == 3) {
bw1.write("D");
bw1.flush();
}

outputThisRound[3] = true;
outputThisRound[0] = false;
ctl++;
System.out.println("outputD signal outputA!");
cond1.signal();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}

以上。

如果大家还有其他更好的方法,欢迎一起讨论:-)

Created by Long Luo at 2015-04-09 22:14:02 @Shenzhen, China. Completed By Long Luo at 2015-04-09 23:46:29 @Shenzhen, China.

0%