想要成为一名优秀的Java程序员,你需要这8个锦囊

私底下,隔三差五就有读者问我:“二哥,怎么样才能像你一样,成为一名优秀的Java开发者呢?”假如把“怎么才能像你一样”去掉的话,这个问题就是一个好问题,否则的话,总有点彩虹屁的嫌疑。但话说回来,我喜欢这种提问的艺术。从上大学那会学Java到现在,我已经积攒了10多年的编程经验,虽然离优秀还有很长的距离,但总归是可以分享一些心得给你,这对你来说,算不上至关重要,但多少是有点用的,至少在我看来。01、学习Java8如果我没记错的话,已经Java14了。但很遗憾的是,我的IDE中配置的JDK版本还停留在Java13,还有一个备用版本,就是Java8。之所以没有追赶时髦,可能是因为学习的劲头不像年轻时候那么足了,让我先惭愧一会儿。还有一个客观上的原因,就是Java8的新特性实在是开天辟地、空前绝后。像Lambda表达式,Stream流,可以称得上是好用到爆。事实上,还有不少Java程序员没有掌握它们(扎心了吧)。Java8之前,启动一个线程要这样:Thread t = new Thread(new Runnable() { ...

不要写很酷但同事看不懂的Java代码

你好呀,我是沉默王二,一个和黄家驹一样身高,和刘德华一样颜值的程序员。为了提高Java编程的技艺,我最近在GitHub上学习一些高手编写的代码。下面这一行代码(出自大牛之手)据说可以征服你的朋友,让他们觉得你写的代码很6,来欣赏一下吧。IntStream.range(1, 5).boxed().map(i -> { System.out.print("Happy Birthday "); if (i == 3) return "dear NAME"; else return "to You"; }).forEach(System.out::println);我虽然拥有10年的Java编程经验,但说实话,很惭愧,这段代码就好像一块板砖拍在我脑袋上,有点懵逼。Lambda表达式我是学过的,Stream流我是学过的,forEach()方法我也是学过的,但把这些知识点全部塞到一行代码中,我还是有点消化不良。我总...

如何快速打好Java基础?

二哥,我是一名大学生,专业是电力工程,但想自学Java,如何快速打好基础呢?微信上tison向我提出了这个问题。我想我是有资格来回答的,从北京奥运会那年开始学Java,到现在已经有10多个年头了,真的是从一名编程白痴一步步走到现在的。我在各大技术网站上分享了不少Java方面的原创文章,不知道影响了多少初学者,反正文章的留言中经常能看到他们由衷的感谢。现在每天仍然有不少同学(tison是其中之一)加我微信,问我怎么一路过来的,希望能够把宝贵的经验分享出来,让他们少走一些弯路。借这个机会,就统一回答下。既然要快速,咱就没法面面俱到,必须挑重点、讲实用。下面就根据我的实战经验,谈一谈具体的学习过程。01、准备学习之路是一项很逆人性的差事,并不是每个人都能够坚持下来,尤其是打基础的阶段,过于强求的话可能就会适得其反,没入门先放弃了。1)对Java感兴趣,对互联网的高薪感兴趣,对“程序员秃顶”的段子视若无睹,只有这样,你才能真正地坚持下去。2)富有坚韧不拔的学习能力,别总遇到一点点困难,就自暴自弃。3)设定一个目标就死磕,如果你经常拿不到最终结果,需要反思是不是从来没有成功做成过一件困难的事情,...

Java 并发编程(一):简介

这篇文章的标题原本叫做——Java并发编程(一):简介,作者名叫小二。但我在接到投稿时觉得这标题不够新颖,不够吸引读者的眼球,就在发文的时候强行修改了标题(也不咋滴)。小二是一名Java程序员,就职于沉默公司,工龄是两年零一个月零三天。和刚毕业那会相比,编程能力已经大有提升,但领导老王一直没敢把并发编程的开发安排给小二,这让小二心里耿耿于怀。这事不怪老王,小二心里很清楚:编写正确的程序很难,编写正确的并发程序更是难上加难。自己功力还不到那个份上,万一搞砸了,难免让一向谨慎的老王面上无光。小二想来想去,办法只有一个,主动去学!就找老王要了一本《Java并发编程实战》,据说这本书是并发编程中的经典之作。拿到书后,随手翻了翻,竟然发现里面藏着一封情书:小二激动坏了,想象着老王写情话的样子,不由得笑出来声。(戛然而止)小二的背景就先介绍到这。接下来,我们来一起鉴赏下小二读完这本书后写下的第一篇文章。01、为什么需要操作系统我喜欢在写文章(不用纸和笔用电脑了)的时候听音乐(不用MP3用电脑了),假如电脑只能做一件事情的话,我就只能在写完文章的时候再听音乐,或者听完音乐的时...

Java 并发编程(三):如何保证共享变量的可见性?

上一篇,我们谈了谈如何通过同步来保证共享变量的原子性(一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行),本篇我们来谈一谈如何保证共享变量的可见性(多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值)。我们使用同步的目的不仅是,不希望某个线程在使用对象状态时,另外一个线程在修改状态,这样容易造成混乱;我们还希望某个线程修改了对象状态后,其他线程能够看到修改后的状态——这就涉及到了一个新的名词:内存(可省略)可见性。要了解可见性,我们得先来了解一下Java内存模型。Java内存模型(JavaMemoryModel,简称JMM)描述了Java程序中各种变量(线程之间的共享变量)的访问规则,以及在JVM中将变量存储到内存→从内存中读取变量的底层细节。要知道,所有的变量都是存储在主内存中的,每个线程会有自己独立的工作内存,里面保存了该线程使用到的变量副本(主内存中变量的一个拷贝)。见下图。  也就是说,线程1对共享变量chenmo的修改要想被线程2及时看到,必须要经过2个步骤...

重学Java(一):与《Java编程思想》的不解之缘

 说起来非常惭愧,我在2008年的时候就接触了Java,但一直到现在(2018年10月10日),基础知识依然非常薄弱。用一句话自嘲就是:十年IT老兵,Java菜鸡一枚。于是,我想,不如静下心来,重新读一遍那些经典的Java技术书,并且没读完一章就输出一篇原创技术文章。从哪一本开始呢?想了一想,还是从《Java编程思想》开始吧!毕竟这本书赢得了全球程序员的广泛赞誉,从Java的基础语法到最高级特性,都能指导我们Java程序员轻松掌握。记得刚上大学那会,就买了一本影印版的《Java编程思想》,但由于初学Java,对编程极度缺乏信心,导致看这本书有一种看天书的感觉。后来,去苏州参加工作的时候把它作为最宝贵的纪念品带了过去。2014年回洛阳的时候它送给了一位关系不错的同事,权当是分别的礼物吧。2016年的时候,我又重新买了一本,希望自己能够夯实一下基础。但事与愿违,它被我束之高阁了——又两年过去了,我重新捧起它,总觉得有一种负罪感。读一本书,最好能从它的前言开始。那么我们就来看看BruceEckel在前言里都说了些什么吧。01、Java的核心目的是&ldquo...

Java 并发编程(二):如何保证共享变量的原子性?

线程安全性是我们在进行Java并发编程的时候必须要先考虑清楚的一个问题。这个类在单线程环境下是没有问题的,那么我们就能确保它在多线程并发的情况下表现出正确的行为吗?我这个人,在没有副业之前,一心扑在工作上面,所以处理的蛮得心应手,心态也一直保持的不错;但有了副业之后,心态就变得像坐过山车一样。副业收入超过主业的时候,人特别亢奋,像打了鸡血一样;副业迟迟打不开局面的时候,人就变得惶惶不可终日。仿佛我就只能是个单线程,副业和主业并行开启多线程模式的时候,我就变得特别没有安全感,尽管整体的收入比没有副业之前有了很大的改善。怎么让我自己变得有安全感,我还没想清楚(你要是有好的方法,请一定要告诉我)。但怎么让一个类在多线程的环境下是安全的,有3条法则,让我来告诉你:1、不在线程之间共享状态变量。2、将状态变量改为不可变。3、访问状态变量时使用同步。那你可能要问,状态变量是什么?我们先来看一个没有状态变量的类吧,代码示例如下。class Chenmo {    public void write() {&nb...

Java 网络编程:必知必会的 URL 和 URLConnection

java.net.URL类将URL地址进行了封装,并提供了解析URL地址的基本方法,比如获取URL的主机名和端口号。java.net.URLConnection则代表了应用程序和URL之间的通信链接,可用于读取和写入此URL引用的资源。URLConnection看起来只是比URL多了一个Connection,它们之间的关系也仅限于此吗?01、什么是URL为了搞清楚什么是URL,需要引入另外两个概念URI和URN。什么鬼,URL都没搞清楚,又来两个搞不清楚的?别担心,我能像变了魔法一样让大家把三个都搞清楚。URI=UniversalResourceIdentifier,中文释义为统一资源标志符URL=UniversalResourceLocator,中文释义为统一资源定位符URN=UniversalResourceName,中文释义为统一资源名称它们之间的关系如下图所示:  这图啥意思啊,怎么办呢?张小敬有问题就去问葛佬,咱不会就去问“维基百科”啊。URI可以分为URL和URN,或者是URL和URN的结合体(同时具备Locator和Name)。...

Java Socket:飞鸽传书的网络套接字

在古代,由于通信不便利,一些聪明的人就利用鸽子会飞且飞得比较快、会辨认方向的优点,对其进行了驯化,用来进行消息的传递——也就是所谓的“飞鸽传书”。而在Java中,网络套接字(Socket)扮演了同样的角色。套接字(Socket)是一个抽象层,应用程序可以通过它发送或接收数据;就像操作文件那样可以打开、读写和关闭。套接字允许应用程序将I/O应用于网络中,并与其他应用程序进行通信。网络套接字是IP地址与端口的组合。01、ping与telnet“老王啊,能不能帮我看一下这个问题呢,明明本地可以进行网络通信,可等我部署到服务器上时就通信不了了,搞了半天也不知道什么原因,我看代码是没有问题的。”小二的语气中充满了沮丧。“ping过吗?或者telnet了吗?”老王头都没回,冷冰冰地扔出去了这句话。“哦,我去试试。”小二心头掠过一丝愧疚。ping与telnet这两个命令,对调试网络程序有着非常大的帮助。ping,一种计算机网络工具,用来测试数据包能否透过IP协议到达特定主机。pin...

Java内存映射,上G大文件轻松处理

内存映射文件(Memory-mappedFile),指的是将一段虚拟内存逐字节映射于一个文件,使得应用程序处理文件如同访问主内存(但在真正使用到这些数据前却不会消耗物理内存,也不会有读写磁盘的操作),这要比直接文件读写快几个数量级。稍微解释一下虚拟内存(很明显,不是物理内存),它是计算机系统内存管理的一种技术。像施了妖法一样使得应用程序认为它拥有连续的可用的内存,实际上呢,它通常是被分隔成多个物理内存的碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。内存映射文件主要的用处是增加I/O性能,特别是针对大文件。对于小文件,内存映射文件反而会导致碎片空间的浪费,因为内存映射总是要对齐页边界,最小单位是4KiB,一个5KiB的文件将会映射占用8KiB内存,也就会浪费3KiB内存。java.nio包使得内存映射变得非常简单,其中的核心类叫做MappedByteBuffer,字面意思为映射的字节缓冲区。01、使用MappedByteBuffer读取文件假设现在有一个文件,名叫cmower.txt,里面的内容是:沉默王二,一个有趣的程序员PS:哎,改不了王婆卖瓜自卖自夸这个臭毛病了,...

Java:控制反转(IoC)与依赖注入(DI)

很长一段时间里,我对控制反转和依赖注入这两个概念很模糊,闭上眼睛想一想,总有一种眩晕的感觉。但为了成为一名优秀的Java工程师,我花了一周的时间,彻底把它们搞清楚了。01、紧耦合在我们编码的过程中,通常都需要两个或者更多的类通过彼此的合作来实现业务逻辑,也就是说,某个对象需要获取与其合作对象的引用,如果这个获取的过程需要自己实现,代码的耦合度就会高,维护起来的成本就比较高。我们来通过实战模拟一下。假如老王是少林寺的主持,他想让小二和尚去扫达摩院的地,代码可以这样实现。小二类的代码如下所示:public class Xiaoer {    public void saodi() {        System.out.println("小二我在扫达摩院的地");    }}老王类的代码如下所示:public class Laowang {&n...

温故而知新,重温 Java 7 的那些“新”特性

2009年4月20日,Java的亲生父亲Sun被养父Oracle以74亿美元收购,这在当时可是一件天大的事。有不少同学都担心Java的前途,我当时傻不啦叽地也很担心:自己刚学会如何通过记事本编写Java代码,然后通过cmd打印HelloWorld呢,这一下难道白学了?但其实这种担心是多余的,因为Java并不会陪葬,毕竟行业内有太多基于Java的软件系统在运行,Java牵扯了太多人的饭碗。10年过去了,Java果然没有陪葬,我仍然坚守在Java的阵线上。2011年7月7日,代号「海豚(Dolphin)」的Java7首次推出,这也是Java历史上一次非常重要的版本更新。同时推出了非常多实用的新特性,比如说创建泛型实例时自动类型推断、switch-case语句支持字符串类型、新增try-with-resources语句等等。这么多年过去了,Java7的“新”特性显然都变成老古董了——它们似乎也不需要我再赘述了,但好像不是这样的。前几天我发了一篇文章,用到了其中一个新特性,竟然有同学表示从来没见过这个新特性,特意在交流群里@我,要我说清楚怎么回事...

Java:前程似锦的 NIO 2.0

Java之所以能够霸占编程语言的榜首,其强大、丰富的类库功不可没,几乎所有的编程问题都能在其中找到解决方案。但在早期的版本当中,输入输出(I/O)流并不那么令开发者感到愉快:1)JDK1.4之前的I/O没有缓冲区的概念、不支持正则表达式、支持的字符集编码有限等等;2)JDK1.4的时候引入了非阻塞I/O,也就是NIO1.0,但遍历目录很困难,不支持文件系统的非阻塞操作等等。为了突破这些限制,JDK1.7的时候引入了新的NIO,也就是本篇文章的主角——NIO2.0。01、基石:PathPath既可以表示一个目录,也可以表示一个文件,就像File那样——当然了,Path就是用来取代File的。1)可以通过Paths.get()创建一个Path对象,此时Path并没有真正在物理磁盘上创建;参数既可以是一个文件名,也可以是一个目录名;绝对路径或者相对路径均可。2)可以通过Files.notExists()确认Path(目录或者文件)是否已经存在。3)可以通过Files.createDirectory()创建目录,此时目录已经在物理磁盘上创建成功,...

Java 代码界 3% 的王者?看我是如何解错这 5 道题的

前些日子,阿里妹(妹子出题也这么难)发表了一篇文章《悬赏征集!5道题征集代码界前3%的超级王者》——看到这个标题,我内心非常非常激动,因为终于可以证明自己技术很牛逼了。但遗憾的是,凭借8年的Java开发经验,我发现这五道题自己全解错了!惨痛的教训再次证明,我是那被秒杀的97%的工程师之一。不过,好歹我这人脸皮特别厚,虽然全都做错了,但还是敢于坦然地面对自己。01、原始类型的float第一题是这样的,代码如下:public class FloatPrimitiveTest {    public static void main(String[] args) {        float a = 1.0f - 0.9f;        fl...

我竟然不再抗拒 Java 的类加载机制了

很长一段时间里,我对Java的类加载机制都非常的抗拒,因为我觉得太难理解了。但为了成为一名优秀的Java工程师,我决定硬着头皮研究一下。01、字节码在聊Java类加载机制之前,需要先了解一下Java字节码,因为它和类加载机制息息相关。计算机只认识0和1,所以任何语言编写的程序都需要编译成机器码才能被计算机理解,然后执行,Java也不例外。Java在诞生的时候喊出了一个非常牛逼的口号:“WriteOnce,RunAnywhere”,为了达成这个目的,Sun公司发布了许多可以在不同平台(Windows、Linux)上运行的Java虚拟机(JVM)——负责载入和执行Java编译后的字节码。到底Java字节码是什么样子,我们借助一段简单的代码来看一看。源码如下:package com.cmower.java_demo;public class Test {    public static void main(String[] ...
首页上一页...563564565566567...下一页尾页