| 泠岚's profile雪汐斋PhotosBlogLists | Help |
|
June 18 Essential Insights of Living昨天被师兄拜托写作文,果然是很久不练手生了,一个400words的东东折腾了快一个小时,一点多才睡下。写完了给人家发过去了,觉得不爽了,没有成就感啊,于是贴上来,慰籍一下今天的黑眼圈。
Essential Insights of Living
It was long ago when I heard that phenomenon of suicide was not rear in campus, and at that time I just could not believe it. But, now it is proved to be a hard fact that many youngsters abandon their precious lives before tasting those best things life should offer. This arises my thought on the essential insights of living and the correct way to treat it. There are mainly two reasons which may make some people lose the hope or the passion of their lives and even commit suicide desperately: great sorrow of losing the ones who they love most, or incomparable depress of failure. For the first reason, those ones in the great sorrow of losing loved ones should know that those they loved are not disappear, but merge the individual beings into the universal life, and death is not the end but a begin of another way of existence. Killing one’s self is not a wise way to memorize the dead ones. The only contribution that suicide can make is to depress the living ones, and force the living ones to face a second hurt of losing. For the second reason, the only thing that those who want to murder themselves need is merely positive attitude. The best way to get the hope and passion back is to make their interests gradually wider and more impersonal, until bit by bit the walls of the ego recede, and they will know the meaning of life is not the success but the process to pursue it. Though they are not succeed as they expected, others will carry on what they haven’t finished, and thus their endeavor is not meaningless. In some way, they’ve done contribution to human-beings as whole. The man who, in failure, can see his life in this way, will not suffer from the feeling of desperate. To sum up, suicide is anything but the way to solve problems. As a responsible person, you have too many things to do before you have right to kill yourself: it is your duty to support your parents, to foster your children and to take good care of your spouse. Try to view the things happen around you in a positive way, and surely you will find life is the most treasure gift you’ve ever possess. Enjoy it when you still have chance. June 01 生日礼物过生日了,又老了一岁。今年收到的第一份生日礼物十分特别,与往年决不相同,我猜想大概没有几个人能有我这样得福气,嗯,的确是份以外惊喜:
食堂的牛肉米线里吃来出的马蜂
当时明明没有点“泡汤油炸马蜂”这道菜啊,不知道为什么会收到这么特别的礼物。为了表示自己的惊喜之情,我当即尖叫一声,声震整个学二食堂。若是苍蝇之类,本大小姐一定令它“见怪不怪,其怪自败”,不过马蜂倒还是第一次,正所谓“长江后浪推前浪,一代马蜂换苍蝇”!
奇怪奇怪真奇怪,世界之大无奇不有。喧嚣的食堂,来往的人群,龌龊的饭菜,神秘的马蜂……这里有你想知道的,有你想看到的,有你无法相信的,有你永远都不愿意错过的视听盛宴!
一只聪明善良活泼可爱的马蜂,为何飞到滚烫牛肉米线中,了却它短暂而光辉的一生?食堂的武林高手们使用了何种独家秘笈,逼迫可怜的小马蜂选择米线作为自己的墓场?一个鲜活的生命就此消逝,一碗醇香的牛肉米线就此归于垃圾桶中……惨剧已经酿成,警钟再次鸣响。这是怎样的哀痛者和郁闷者啊!在如此轰轰烈烈的时代背景下,在这般滚滚滔滔的历史洪流中,主题活动“马蜂是如何溺死牛肉米线之中?”拉开帷幕,敬请各位未来柯南.道尔、福尔摩斯们参与破案,破案者将得到一份由天津大学学二食堂特别提供的大奖:带油炸马蜂作佐餐的牛肉米线一碗。奖品有限,先到先得!欢迎大家积极报名,踊跃参加!本次活动的解释权归雪汐斋所有。 May 30 java 传值 vs. 传引用java程序的函数调用到底是传值呢还是传参呢?这可是个难缠的问题,如果搞不清楚还是挺容易出错的:P对于这个问题,最经典的解释莫过于“java函数是传值的,java函数传递的参数是对象的引用”
这两句话好像初听上去有点绕,不过意思倒是表达得蛮精确的。 我看到过几个解释这个问题的例子,不过个人感觉看过例子之后还是只知道是什么不知道为什么,停留在照猫画虎的水平上还是挺容易出问题的。所以举例子之前,先从jvm的实现原理上有个了解应当是不无裨益的。jvm的结构图前一阵子贴到blog上了,那可是从“深入java虚拟机”这本巨牛的书上看来的,绝对有权威性。从jvm的结构图上可以看出来,jvm在实现的时候将属于它的内存分为五部分,其中程序代码(严格的说应当是字节码)是放在java栈的栈帧中,而对象是从堆中分配的,堆这个东西我看可以理解成“对象池”。程序和程序中需要用到的对象放在两个相对独立的区域中,那么程序怎么使用对象呢?答案是程序中真正使用对象的地方其实只是声明了一个对象的引用,也就是把堆中分配了的相应对象的地址放到引用中,栈和堆之间就是通过一个一个的引用来联系的。引用嘛,我理解就是一个指针常量,指针常量又是个什么东西呢?说白了,就是一个无符号整数,这个整数所表达的是引用对象的地址。好了,这下清楚了,不管是基本类型变量(int,float,double什么的)还是对象,相应的内存地址中存放的都是一个数(无符号整数,整数,浮点数等)。传递参数的时候传递的就是相应内存地址中的数,所以说“java函数是传值的”。当然,这个数对于基本类型和对象类型来说意义是不一样的,对于基本类型这个数就是其值本身,传递值的结果就是,改变新的变量的值不影响旧的变量的值;而对于对象来说这个数是它的地址,传递这个值就相当于传递了真实对象的引用,传递了引用或者说是地址的结果就是变化会全局可见,所以又可以说“java函数传递的参数是对象的引用”。
唔,松口气啦。经过上面这一小堆讨论,不难理解为什么java在传递参数时对于基本类型和对象表现不同:)
现在开始举例了,举网上搜来的例子,看看是不是比原来没有上面的解释的时候好理解一点?
public class TestRef
{ public static void main(String[] args) { ValueObject vo1 = new ValueObject("A", 1); System.out.println("after vo1: " + vo1.getName()); //=A changeValue1(vo1); System.out.println("after changeValue1: " + vo1.getName()); //=A1, changed changeValue2(vo1); System.out.println("after changeValue2: " + vo1.getName()); //=A1, changeValue2内部的赋值不会影响这里。 } /** * 使用vo1自身的函数对其内部数据进行改变是有效的,函数外可反映出来, * 因为这是对对象本身的操作
* 这种object称为可变的(mutable) * @param vo1 */ private static void changeValue1(ValueObject vo1) { vo1.setName("A1"); } /** * 在函数内给vo1重新赋值不会改变函数外的原始值,因为这种改变了引用的指向 * @param vo1 */ private static void changeValue2(ValueObject vo1) { vo1 = new ValueObject("B", 2); System.out.println("inside changeValue2: "+ vo1.getName()); //=B,赋值操作引起的结果变化仅在changeValue2内部有效 } } class ValueObject { public ValueObject() {} public ValueObject(String name, int id) { this.name = name; this.id = id; } private String name; private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } java中对象的每个实例(就是对象)内存地址是唯一的,它一旦被创建,能够对这个地址进行操作的就是其本身,如果ValueObject类中没有public void setName之类的方法对这个类的实例中的数据进行修改的话,程序是没有任何别的方法可以修改ValueObject类的实例中的数据,这个就是java的封装特性。对于不提供修改内部数据的方法的类,我们称为不可变(immutable)的类。在函数中对传入的参数变量进行赋值操作,只能在函数范围内改变局部变量指向的引用地址,但是不会改变原始地址的内容。因此,在changeValue2(...)函数内部的vo1和函数外的vo1虽然名字相同,但是实际上是不同的实例变量,只不过指向了和函数外的vo1同样的地址,所以当我们用vo1=... 对其进行赋值的时候,只不过是把函数内的临时变量指向了新的地址,并没有改变原始vo1内存地址中的内容。这就是在运行changeValue2(...)之后,vo1的值在main范围内仍然没有被修改的原因。而changeValue1里面是调用的ValueObject本身的function来更改其内容,因此是原始内存地址中的数据被更改了,所以是全局有效的. 总结: 对于引用类型的传参也是传值的,传的是引用类型的值,其实就是对象的地址。 1. java参数传递值的。 2. java所有对像变量都是对像的引用。 不知道我解释清楚没,要是还是不能理解java参数传递的原理,强烈推荐看看“深入java虚拟机”一书的第五章,中文翻译的不是特别出色,可以看看英文原版,应该比中文版好懂:) May 29 盘山走马西来欲到天
去过长城的第二天又去了盘山,一直以为盘山就是个小山包,看了这张导游图才知道这趟旅行的任务并不轻松。
相传三国曹魏时田畴隐居于此,亦称田盘山。一入此处,想必是胜景在前,物华天宝、人杰地灵。引得乾隆慨言“早知有盘山,何必下江南 ” 。
山光悦鸟性,潭影空人心
山水相辉,楼台相映,天予安排
野芳发而幽香,佳木秀而繁阴
五峰、八石、三盘、七十二寺、十三塔
试上最高处闲坐地,东,也在图画里,西,也在图画里
大肚能容,容天下难容之事
笑口常开,笑世上可笑之人 疏篱曲径田家小,云树开清晓
会当临绝顶
一览众山小 连峰去天不盈尺
枯松倒挂依绝壁 别来几向梦中看
蓟门长城长城谣 其实很小的时候就听过蓟门关的大名,记得好像唐朝有个叫祖咏的还写了首叫做《望蓟门》的,赞美这里“燕台一望客心惊,箫鼓喧喧汉将营。万里寒光生积雪,三边曙色动危旌。沙场烽火连胡月,海畔云山拥蓟城。少小虽非投笔吏,论功还欲请长缨。”那个时候很喜欢他的最后两句,向往蓟门的“海畔云山”,“万里寒光”。只是一直没有想到大名鼎鼎的蓟门就是今天天津的蓟县。蓟县有长城,名曰黄崖关,位于北京之东,天津之北,居于蓟北部群山之中,黄崖关地处北京、天津、唐山、承德的正中间,自古为兵家必争之地,又是北部之敌进犯京都的要冲,祖咏的短短几言道尽蓟门无限风光和无可取代的军事地位。
东方欲晓,莫道君行早,风景这边独好。
城堞远望如刀齿,咬定青天不放松。 隆庆二年(公元1568年),明政府下令任命戚继光总理蓟州、昌平、辽东、保定军务。 抗击倭寇,修筑长城,戚继光将军用他的铮铮铁骨写下又一首永恒的诗篇。岳飞曾经慨然道“三十功名尘与土,八千里路云和月”,戚继光有何曾不是怀着这样一种“待从头收拾旧山河”的热忱?他日日横戈马上,用全部生命为家国而战斗。“南北驱驰报主情 江花边草笑平生 一年三百六十日 都是横戈马上行”
拾级而上,都倍感吃力,可想当年筑城的艰辛。长城的每一块沉重的石头砖块都用手搬、肩扛、背驮上去。一万两千七百里的长城呵,承载了中华民族多少血泪辛酸?孟姜女哭长城,千古绝唱谁人听……
残破的长城见证了中华民族几千年来抗击外族侵略的决心,当刀光剑影已经黯淡,鼓角争鸣离我们远去,后人能否记得为了民族的繁衍生息而逝去的先辈?“誓扫匈奴不顾身,五千锦貂丧胡尘。可怜无定河边骨,犹是春闺梦里人。”长城角下有几多白骨,几多不屈的魂灵?
无路请缨,等终军之弱冠
有怀投笔,慕宗悫之长风 表里山河
长城拱身拧体,利爪牢牢抓住山的脊梁,盘垣卓立,与雄浑的山势构成一派凶险的气象。
离着黄崖关长城不远处蓟县城内就有乾隆皇帝的行宫。一边是边疆战士“岁岁金河复玉关,朝朝马策与刀环”,远离家园在苦寒的塞外流血战斗,另一边却是帝王“朝朝玉树后庭花,步步金莲潘丽华”,穷奢极欲挥金如土荒淫无度;一边是疆场之上“髑髅皆是长城卒,日暮沙场飞作灰”,另一边却是宫闱之内“凤阁龙楼连霄汉,碧树琼枝作烟罗”。
保家卫国,战争没有停止过。“辞凤阁,盼滦河,别离此情将奈何?羽盖峨峨,虎皮驮驮,雁远暮云阔…”昭君出塞了,留下满路的驼铃,然而修好只是暂时,不多久风烟又起;我们的祖先曾让胡人有过“北斗七星高,哥舒夜带刀。至今窥牧马,不敢过临洮”的胆战心惊;也留下了“遗民泪尽胡尘里,南望王师又一年”的凄凉悲歌。
城上城下争战了一部历史,多少个隘口就有多少次的悲欢,你永远是个无情的建筑 ,蹲踞在荒莽的山巅 ……
离开的时候正是日暮,想起一首歌
狼烟起江山北望
龙起卷马长嘶剑气如霜 心似黄河水茫茫 二十年纵横间谁能相抗 恨欲狂长刀所向 多少手足忠魂埋骨它乡 何惜百死报家国 忍叹惜更无语血泪满眶 马蹄南去人北望 人北望草青黄尘飞扬 我愿守土复开疆 堂堂中国要让四方 来贺 May 26 约瑟夫问题的java实现讲讲这个Josephus游戏的故事先:据说著名的犹太史学家Josephus有过以下故事,在罗马人占领乔塔帕特后,39个犹太人与Josephu和他的朋友躲到一个洞中,39个犹太人决定宁愿死夜不愿被敌人俘虏,于是决定了一个自杀的方式,41个人排成一个圆圈,由第1个人开始报数,每报到第3人该人就必須自杀,然后再由下一个人重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假裝遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
今天又看到josephus问题觉了,总觉得会有一种简单的办法来解决这个问题,可以既不使用链表又不用struct和多维数组什么的,呵呵,结果真的找到了,下面这个就是了
public class Josephus
{ public static void main(String args[]) { if(args.length != 2) //处理参数数目不正确情况 { System.out.println("Please Input a number!"); return; } int i, j, n, m; n = Integer.parseInt(args[0]); m = Integer.parseInt(args[1]); if (n <= 0 || m <= 0) //处理参数值不正确的情况 { System.out.println("Paramter must bigger than zero!"); return; } int a[] = new int[n]; for (i = 0; i < n; i++) a[i] = i + 1; int k = 1; //标识处理第k个离开的人 i = -1; //数组下标,下一个为0,即第一个人 while (true) //k等于n表示只剩下一个人了 { for (j = 0; j < m;) //在圈中数m个人 { i = (i + 1) % n; if (a[i] >0) j++; //a[i] >0表示第i个人还没有离开 } if(k==n) break; System.out.println("No." + a[i] + " is out!"); a[i] = -1; //表示该人离开 k++; } System.out.println("No." + a[i] + " is the winner!"); } } 输入:
C:\Documents and Settings\circle\桌面>java Josephus 9 4
输出结果:
No.4 is out! No.8 is out! No.3 is out! No.9 is out! No.6 is out! No.5 is out! No.7 is out! No.2 is out! No.1 is the winner! 运行速度比较快,输入java Josephus 1,000,000 9(也就是说有一百万个人排成一圈,每隔9个出局一个),程序只需要两三秒钟就可以得到最后的winner:No. 963295,当然,要是输出"No." + a[i] + " is out!"这句就很花时间了。
ps:刚才在网上搜到一个更强的,c程序,只有8行!!!暴快!!!汗一下……
用的是倒推法,而不是向上面那样模拟游戏的方法。
#include <stdio.h> main() { int n, m, i, s=0; printf ("N M = "); scanf("%d%d", &n, &m); for (i=2; i<=n; i++) s=(s+m)%i; printf ("The winner is %d\n", s+1); } 求X个的质数,嗯,这个算法好简洁 算法P:
求X个不同的质数,PRIME[]为一个数组,存储所有求得的质数
P1. [初始化]PRIME[1]<-2, N<-3, J<-1(N跑遍所有奇数,因为只有奇数可以成为质数 的候选者;J用来标记至今已找到多少个质数)
P2. [N是质数]置J<-J+1, PRIME[J]<-N P3. [找到X个?]若J=X,则全部要求的质数找到,退出程序 P4. [增加N]置N<-N+2 P5. [K<-2]置K<-2(PRIME[K]将跑遍N的所有可能的质因子) P6. [K/PRIME[K]?]以PRIME[K]除K;设Q是商,R是余数,若R=0(因此N不是质数),转 向P4
P7. [PRIME[K]足够大了?]若Q<=PRIME[K],则转P2(在这种情况下,N必然是质数) P8. [增加K]K加1,并转P6 算法来自The Art of Programming,的确是大师,窥一斑而见全豹,就这么个小东西都能看出来人家的厉害之处,我以为求N是不是质数就要一个一个挨个除到N的平方根呢,这个方法可快多了。 May 25 交换变量a和b不引入变量c算法Change:
变量a和b交换,一般要引入第三个变量c:
c=a;
a=b;
b=c;
其实变量c没有什么实质性的作用,只是作为一个“中转站”出现。如果不想引入变量c而完成交换,可以通过以下方法实现: a = a + b; b = a - b; a = a - b; 或者使用位运算符“异或” a = a ^ b; b = a ^ b; a = a ^ b; May 22 Java虚拟机结构图《深入java虚拟机》看完了,挺难理解的,不是很懂,嘿嘿,这个自然了。虽然他的大部分思想还是很自然也挺符合人们的思维习惯的,但是毕作为一个先进的技术它的深层原理和具体技术还是不那么显而易见的,远远超出了我仅有的理解能力:P不懂的实在比不懂的多得多,不过上面那幅图倒是让我明白了点JVM底层的实现机制,受益匪浅。很多以前很诧异理解不了的语法和概念在仔细研究了这幅图之后变得清晰起来。
执行引擎处于JVM的核心位置,在Java虚拟机规范中,它的行为是由指令集所决定的。尽管对于每条指令,规范很详细地说明了当JVM执行字节码遇到指令时,它的实现应该做什么,但对于怎么做却言之甚少。Java虚拟机支持大约248个字节码。每个字节码执行一种基本的CPU运算,例如,把一个整数加到寄存器,子程序转移等。Java指令集相当于Java程序的汇编语言。
由于指令系统的简单性,使得虚拟机执行的过程十分简单,从而有利于提高执行的效率。指令中操作数的数量和大小是由操作符决定的。如果操作数比一个字节大,那么它存储的顺序是高位字节优先。例如,一个16位的参数存放时占用两个字节,其值为: 第一个字节*256+第二个字节字节码。
指令流一般只是字节对齐的。指令tableswitch和lookup是例外,在这两条指令内部要求强制的4字节边界对齐。
未完,待续 |
|||||
|
|