hMXC

101个鲜为人知的超实用网站

这里列出了许多鲜为人知的好网站,还有那些大家知道却常常被遗忘的网站。
这些网站中,大部分都在某一个领域非常专业,并且都拥有非常简单的网址,你可以省略搜索的步骤,轻松将他们记在心里。

01. screenr.com —— 将你在电脑上的操作录制成影片并直接传送到YouTube上。

02. bounceapp.com —— 能够将一个网页进行完整的截图。

03. goo.gl —— 将网站地址进行缩写并可以将网址转换成二维码。

04. untiny.me —— 找到缩写网址的原始域名。

05. localti.me —— 能查询不只一个城市的当地时间。

06. copypastecharacter.com —— 复制你键盘上没有的特殊字符。

07. topsy.com —— Twitter专用搜索引擎。

08. fb.me/AppStore —— 无需运行iTunes就可以搜索iOS的手机应用。

09. iconfinder.com ——在这里可以找到图标的所有尺寸。

10. office.com —— 下载办公文件的模板、剪贴画以及图片。

11. woorank.com —— 你想知道的关于一个网站的所有信息都可以在这里找到。

12. virustotal.com —— 对任何可疑的文件或者邮件附件进行病毒扫描。

13. wolframalpha.com —— 不用搜索就可以知道问题的答案 —— 更多信息,请阅读Wolfram提示。

14. printwhatyoulike.com —— 完整的打印网页。

15. joliprint.com —— 将新闻和博客内容重新整合为报纸。

16. isnsfw.com —— 当你想要分享18X网页时为你做警示标记。

17. e.ggtimer.com —— 一个居家常备的简易在线计时器。

18. coralcdn.org —— 如果某网站由于服务器太繁忙而无法访问的话,试试通过CDN来进入网站吧。

19. random.org —— 帮你随机挑选数字,抛硬币~

20. mywot.com —— 测试任意网站的可信任指数。

21. viewer.zoho.com —— 帮你用浏览器来预览PDF文件和PPT。

22. tubemogul.com —— 能同时向多个视频网站上传视频。

23. truveo.com —— 最佳网络视频搜索。

24. scr.im —— 不用担心垃圾邮件困扰,安全无忧地分享你的邮件地址。

25. spypig.com —— 从今往后在你的邮箱里查看收据吧~

26. sizeasy.com —— 将任一产品进行视觉化并进行尺寸比较。

27. whatfontis.com —— 迅速通过图片来确定字体名称。

28. fontsquirrel.com —— 优质的字体大集合 —— 免费自用与商用。

29. regex.info —— 查出你照片中的隐藏数据

30. tineye.com —— 就像谷歌图片搜索应用的网页版。

31. iwantmyname.com —— 帮助你在所有TLD中找到你想要的域名。

32. tabbloid.com —— 将你最喜欢的博客转换成PDF

33. join.me —— 与网络上任何一个人分享你的桌面。

34. onlineocr.net —— 从扫描的PDF和图片中识别出其他文字

35. flightstats.com —— 随时查看世界各地机场的航班实况。

36. wetransfer.com —— 用来在线分享大型文件。

37. pastebin.com —— 一个临时的在线剪切板,方便你的文字编辑与记录编码片段。

38. polishmywriting.com —— 检查你文字中的拼写和语法错误。

39. awesomehighlighter.com —— 轻松标记网页中的重点部分。

40. typewith.me —— 与多人同时在一个文件上进行修改。

41. whichdateworks.com —— 正在计划什么活动吗?选一个合适的日期吧。

42. everytimezone.com —— 清晰易懂的世界时区表。

43. warrick.cs.odu.edu —— 当你收藏的网页被删除时,你就需要用到这个了。

44. gtmetrix.com —— 一个完美的在线工具,可以帮助你计算网页性能。

45. imo.im —— 可以在一个网页上使用多个聊天工具,Skype, Google Talk,等等。

46. translate.google.com —— 翻译网页、PDF以及办公文档。

47. youtube.com/leanback —— 享受无尽头的全屏Youtube视频吧。

48. similarsites.com —— 帮你发现与你喜欢的网站类似的其他网站。

49. wordle.net —— 使用标签云图快速总结长篇文字。

50. bubbl.us —— 用浏览器来做思维导图和头脑风暴。

51. kuler.adobe.com —— 获取配色的灵感,也可以从照片中提取颜色。

52. followupthen.com —— 通过邮件设置快速提醒。

53. lmgtfy.com —— 当你的朋友懒到不愿意自己用谷歌搜索时……

54. tempalias.com —— 临时邮箱用户名生成器,比一次性邮箱实用。

55. pdfescape.com —— 使用浏览器快速修改PDF文件。

56. faxzero.com —— 免费发送在线传真 —— 参加其他传真服务。

57. feedmyinbox.com —— 将RSS更新以邮件新闻的方式发送给你。

58. isendr.com —— 无需上传到服务器就可以传送文件。

59. tinychat.com —— 快速创建一个私人聊天室。

60. privnote.com —— 创建一个在阅读过后会自行毁灭的便条。

61. flightaware.com —— 实况转播世界各地机场航班动态。

62. boxoh.com —— 在谷歌地图上追踪任何运输信息。

63. chipin.com —— 当你需要为一个项目或者活动进行筹款时……

64. downforeveryoneorjustme.com —— 查出你的喜欢的网站是否下线了。

65. example.com —— 这个网站可以当做文档的范例来使用。

66. whoishostingthis.com —— 找到任何一个网站的网站主机。

67. google.com/history —— 是不是忘记曾经搜索过的某些关键词?用这个网站来找回吧。

68. errorlevelanalysis.com —— 辨识一张照片是否被PS过。

69. google.com/dictionary —— 查出一个单词的含义、发音以及例句用法。

70. urbandictionary.com —— 告诉你俚语和俗语的含义。

71. seatguru.com —— 在你为下一次航班选择座位时参考一下这个网站吧。

72. sxc.hu —— 免费下载库存图片。

73. imo.im —— 可以同时使用多个聊天工具跟朋友聊天,Skype, Google Talk,等等。

74. wobzip.org —— 在线解压压缩文件。

75. vocaroo.com —— 只需轻轻一点就可以记录下自己的声音。

76. scribblemaps.com —— 轻松创建自定义谷歌地图。

77. buzzfeed.com —— 绝不让你错过任何网络走红图片或视频。

78. alertful.com —— 快速设定重大日程的邮件提醒。

79. encrypted.google.com —— 防止网络供应商或者你的老板查看你的搜索记录。

80. formspring.me —— 你可以在这里提出和回答私人问题。

81. snopes.com —— 查出你收到的邮件是真实的或是诈骗邮件。

82. typingweb.com —— 通过这些练习环节变成打字大师吧。

83. mailvu.com —— 通过你的摄像头给其他人发送视频邮件吧。

84. ge.tt —— 神速传送文件,接收的人还可以在下载前进行预览哦。

85. timerime.com —— 使用音频、视频和图片来创建时间表。

86. stupeflix.com —— 利用自己的图片、录音和视频来制作一部小电影吧。

87. aviary.com/myna —— 一个能够编辑录音和混音的在线音频编辑器。

88. noteflight.com —— 打印五线谱,在线创作自己的音乐。

89. disposablewebpage.com —— 创建一个会自动销毁的临时网站。

90. namemytune.com —— 当你想知道这段旋律的名字时……

91. homestyler.com —— 从零开始进行室内设计,或者重新为你的家建模。

92. snapask.com —— 在手机上通过邮件查询球赛分数,或者查阅维基百科。

93. teuxdeux.com —— 长得像手写日记的日程应用。

94. livestream.com —— 在线直播任何活动和项目,包括你的电脑桌面。

95. bing.com/images —— 自动为你的移动设备找到合适的壁纸。

96. historio.us —— 将任何格式的网页完整保存。

97. dabbleboard.com —— 你的虚拟白板。

98. whisperbot.com —— 不需要使用自己的邮箱账户就可以发送邮件。

99. sumopaint.com —— 一个超棒的在线图片编辑器(图层编辑方式)。

100. lovelycharts.com —— 在线创建流程图、网络图表、网站地图等。

101. nutshellmail.com ——在你的收件箱中获取Facebook与Twitter最新消息。

深入Java核心 Java内存分配原理

一般Java在内存分配时会涉及到以下区域:

◆寄存器:我们在程序中无法控制

◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中

◆堆:存放用new产生的数据

◆静态域:存放在对象中用static定义的静态成员

◆常量池:存放常量

◆非RAM存储:硬盘等永久存储空间

Java内存分配中的栈

在函数中定义的一些基本类型的变量数据和对象的引用变量都在函数的栈内存中分配。
  
当在一段代码块定义一个变量时,Java就在栈中 为这个变量分配内存空间,当该变量退出该作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

Java内存分配中的堆

堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。

在堆中产生了一个数组或对象后,还可以 在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量。  引用变量就相当于是 为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。引用变量就相当于是为数组或者对象起的一个名称。

引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。而数组和对象本身在堆中分配,即使程序 运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍 然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是 Java 比较占内存的原因。

实际上,栈中的变量指向堆内存中的变量,这就是Java中的指针!
 
常量池 (constant pool)

常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。除了包含代码中所定义的各种基本类型(如int、long等等)和对象型(如String及数组)的常量值(final)还包含一些以文本形式出现的符号引用,比如:

◆类和接口的全限定名;

◆字段的名称和描述符;

◆方法和名称和描述符。

虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integer和 floating point常量)和对其他类型,字段和方法的符号引用。

对于String常量,它的值是在常量池中的。而JVM中的常量池在内存当中是以表的形式存在的, 对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值,注意:该表只存储文字字符串值,不存储符号引 用。说到这里,对常量池中的字符串值的存储位置应该有一个比较明了的理解了。
在程序执行的时候,常量池 会储存在Method Area,而不是堆中。

堆与栈

Java的堆是一个运行时数据区,类的(对象从中分配空间。这些对象通过new、newarray、 anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存 大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态 分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是 确定的,缺乏灵活性。栈中主要存放一些基本类型的变量数据(int, short, long, byte, float, double, boolean, char)和对象句柄(引用)。

栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:

  1. int a = 3;   

  2. int b = 3;  

编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。

这时,如果再令 a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响 到b的值。

要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b, 它是由编译器完成的,它有利于节省空间。而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。 

String是一个特殊的包装类数据。可以用:

  1. String str = new String("abc");   

  2. String str = "abc";  

两种的形式来创建,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。而第二种是先在栈中创建一个对String类的对象引用变量str,然后通过符号引用去字符串常量池 里找有没有"abc",如果没有,则将"abc"存放进字符串常量池 ,并令str指向”abc”,如果已经有”abc” 则直接令str指向“abc”。

比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==,下面用例子说明上面的理论。

  1. String str1 = "abc";   

  2. String str2 = "abc";   

  3. System.out.println(str1==str2); //true  

可以看出str1和str2是指向同一个对象的。

  1. String str1 =new String ("abc");   

  2. String str2 =new String ("abc");   

  3. System.out.println(str1==str2); // false  

用new的方式是生成不同的对象。每一次生成一个。

因此用第二种方式创建多个”abc”字符串,在内存中 其实只存在一个对象而已. 这种写法有利与节省内存空间. 同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("abc");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。

另 一方面, 要注意: 我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为,创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的 对象。只有通过new()方法才能保证每次都创建一个新的对象。
 
由于String类的immutable性质,当String变量需要经常变换 其值时,应该考虑使用StringBuffer类,以提高程序效率。
 
1. 首先String不属于8种基本数据类型,String是一个对象。因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。

2. new String()和new String(”")都是申明一个新的空字符串,是空串不是null;

3. String str=”kvill”;String str=new String (”kvill”)的区别

示例:

  1. String s0="kvill";   

  2. String s1="kvill";   

  3. String s2="kv" + "ill";   

  4. System.out.println( s0==s1 );   

  5. System.out.println( s0==s2 );  

结果为:

true
true

首先,我们要知结果为道Java 会确保一个字符串常量只有一个拷贝。

因为例子中的 s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字 符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中” kvill”的一个引用。所以我们得出s0==s1==s2;用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

示例:

  1. String s0="kvill";   

  2. String s1=new String("kvill");   

  3. String s2="kv" + new String("ill");   

  4. System.out.println( s0==s1 );   

  5. System.out.println( s0==s2 );   

  6. System.out.println( s1==s2 );  

结果为:

false
false
false

例2中s0还是常量池 中"kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分 new String(”ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。

4. String.intern():

再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的 intern()方法就是扩充常量池的 一个方法;当一个String实例str调用intern()方法时,Java 查找常量池中 是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常 量池中增加一个Unicode等于str的字符串并返回它的引用;看示例就清楚了

示例:

  1. String s0= "kvill";   

  2. String s1=new String("kvill");   

  3. String s2=new String("kvill");   

  4. System.out.println( s0==s1 );   

  5. System.out.println( "**********" );   

  6. s1.intern();   

  7. s2=s2.intern(); //把常量池中"kvill"的引用赋给s2   

  8. System.out.println( s0==s1);   

  9. System.out.println( s0==s1.intern() );   

  10. System.out.println( s0==s2 );  

结果为:

false
false //虽然执行了s1.intern(),但它的返回值没有赋给s1 
true //说明s1.intern()返回的是常量池中"kvill"的引用 
true

最后我再破除一个错误的理解:有人说,“使用 String.intern() 方法则可以将一个 String 类的保存到一个全局 String 表中 ,如果具有相同值的 Unicode 字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中”如果我把他说的这个全局的 String 表理解为常量池的话,他的最后一句话,”如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:

示例:

  1. String s1=new String("kvill");   

  2. String s2=s1.intern();   

  3. System.out.println( s1==s1.intern() );   

  4. System.out.println( s1+" "+s2 );   

  5. System.out.println( s2==s1.intern() );  

结果:

false
kvill kvill
true

在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一 个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。

s1==s1.intern() 为false说明原来的”kvill”仍然存在;s2现在为常量池中”kvill”的地址,所以有s2==s1.intern()为true。

5. 关于equals()和==:

这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是 比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。

6. 关于String是不可变的

这一说又要说很多,大家只 要知道String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”; 就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” ” 生成 “kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的”不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原 因了,因为StringBuffer是可改变的。

下面是一些String相关的常见问题:

String中的final用法和理解

final StringBuffer a = new StringBuffer("111");
final StringBuffer b = new StringBuffer("222");
a=b;//此句编译不通过
final StringBuffer a = new StringBuffer("111");
a.append("222");// 编译通过

可见,final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象 的变化,final是不负责的。 

String常量池问题的几个例子

下面是几个常见例子的比较分析和理解:

  1. String a = "a1";   

  2. String b = "a" + 1;   

  3. System.out.println((a == b)); //result = true  

  4. String a = "atrue";   

  5. String b = "a" + "true";   

  6. System.out.println((a == b)); //result = true  

  7. String a = "a3.4";   

  8. String b = "a" + 3.4;   

  9. System.out.println((a == b)); //result = true 

分析:JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true。

  1. String a = "ab";   

  2. String bb = "b";   

  3. String b = "a" + bb;   

  4. System.out.println((a == b)); //result = false 

分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。

  1. String a = "ab";   

  2. final String bb = "b";   

  3. String b = "a" + bb;   

  4. System.out.println((a == b)); //result = true 

分析:和[3]中唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量 池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。

  1. String a = "ab";   

  2. final String bb = getBB();   

  3. String b = "a" + bb;   

  4. System.out.println((a == b)); //result = false   

  5. private static String getBB() {  

  6. return "b";   

分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面 程序的结果为false。

通过上面4个例子可以得出得知:

String  s  =  "a" + "b" + "c"; 
  
就等价于String s = "abc";  

String  a  =  "a";   
String  b  =  "b";   
String  c  =  "c";   
String  s  =   a  +  b  +  c; 

这个就不一样了,最终结果等于: 
 

  1. StringBuffer temp = new StringBuffer();     

  2. temp.append(a).append(b).append(c);     

  3. String s = temp.toString(); 

由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:

  1. public class Test {  

  2. public static void main(String args[]) {  

  3. String s = null;  

  4. for(int i = 0; i < 100; i++) {  

  5. s += "a";  

  6. }  

  7. }  

每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行 append操作。

String对象的intern方法理解和分析:

  1. public class Test4 {  

  2. private static String a = "ab";   

  3. public static void main(String[] args){  

  4. String s1 = "a";  

  5. String s2 = "b";  

  6. String s = s1 + s2;  

  7. System.out.println(s == a);//false  

  8. System.out.println(s.intern() == a);//true    

  9. }  

这里用到Java里面是一个常量池的问题。对于s1+s2操作,其实是在堆里面重新创建了一个新的对象,s保存的是这个新对象在堆空间的的内容,所 以s与a的值是不相等的。而当调用s.intern()方法,却可以返回s在常量池中的地址值,因为a的值存储在常量池中,故s.intern和a的值相等。

总结

栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容

堆中存放使用new关键字创建的对象.

字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常 量池中,而有的是运行时才被创建.使用new关键字,存放在堆中。


今天做的一个仿朋友网的发表功能,主要是利用ueditor的功能实现的。