爪哇

雇用 Top 3%自由Java开发人员

托塔尔是面向顶级Java开发人员,工程师,程序员,编码人员,架构师和顾问的市场。顶尖公司和初创企业选择Toptal Java自由职业者来执行其关键任务软件项目。

无风险试用,仅在满意时付款。

客户评价 托塔尔 Java Developers4.4 / 5.0截至2021年3月3日,平均814条评论

受到领先品牌和初创企业的信任

雇用自由Java开发人员和工程师

凯利·安·马丁内斯(Kelly Ann Martines)

自由职业Java开发人员

美国自2018年5月18日起在Toptal担任自由Java开发人员

Kelly拥有12年的软件工程师工作经验,主要致力于C ++,C和Java。她'除了并发系统(包括多线程系统,集群或航空电子系统中的嵌入式系统网络)以外,S。还在桌面应用程序上工作。

展示更多

拉德克·奥斯特罗夫斯基(Radek Ostrowski)

自由职业Java开发人员

澳大利亚自2014年7月25日起在Toptal担任自由Java开发人员

Radek是一位经过认证的Toptal区块链工程师,对以太坊和智能合约特别感兴趣。在法定世界中,他在大数据/机器学习项目方面经验丰富。他是两个不同的国际IBM Apache Spark竞赛的三重冠军,是PlayStation 4的共同创造者'后端,是成功的黑客马拉松比赛的竞争对手,并在澳大利亚,波兰和塞尔维亚的会议上担任演讲嘉宾。

展示更多

里兹万·里兹维(Rizwan Rizvi)

自由职业Java开发人员

美国自2018年5月21日起在Toptal担任自由Java开发人员

Rizwan以通过清晰的思维,创新的方法并增强组织不同部分之间的沟通来克服复杂的挑战而享有盛誉。在他的整个职业生涯中,他优化了分散的IT专业人员团队的工作,并始终在具有挑战性的环境中交付了有利可图的项目。

展示更多

詹姆斯·索斯

自由职业Java开发人员

美国自2018年8月8日起在Toptal担任自由Java开发人员

James在提供解决问题难题的技术解决方案方面拥有很长的职业生涯。软件工程是他的技能,他始终致力于学习不断提高工作质量。他过去的雇主和同事珍视James的能力,因为他能够快速理解问题领域,清晰,开放的交流以及提供及时,井井有条的技术解决方案。

展示更多

克劳迪奥·奥尔达纳(Claudio Aldana)

自由职业Java开发人员

美国自2018年6月15日起在Toptal担任自由Java开发人员

Claudio是一位经验丰富的IT专家,专注于业务成果以及扎实的工程背景。他'的应用数据科学可优化客户满意度,产品个性化和客户流失率。 Claudio还是获得SharePoint认证的专家,并且与知名的Microsoft客户合作,帮助他们最大程度地提高安全性,性能和可用性。

展示更多

丹·科兹洛夫斯基(Dan Kozlowski)

自由职业Java开发人员

美国自2019年7月8日起在Toptal担任自由Java开发人员

Dan从事技术工作已有20年,并曾与许多大型公司(如Oracle和Accenture)合作,并拥有一些初创公司和他自己的业务。最近,他的技术重点一直放在电子商务和全栈Web开发以及开发运营上。在他的职业生涯中,他有很多机会为客户设计和提供大规模解决方案,而且始终能够亲身体验该技术。

展示更多

基思·埃文(Keith Ewen)

自由职业Java开发人员

美国自2019年2月16日起在Toptal担任自由Java开发人员

Keith在过去20多年的IT行业中拥有近40年的经验,使用Oracle数据库和Oracle eBusiness Suite进行设计和开发。他'还在Oracle开放世界和Oracle应用程序用户组会议上发表了演讲。基思(Keith)做出了个人贡献,并管理着多达10种资源的在岸/离岸团队。基思非常注重细节,始终提供优质的产品。

展示更多

维亚切斯拉夫·珍尼连科

自由职业Java开发人员

乌克兰自2019年4月29日起在Toptal担任自由Java开发人员

Viacheslav在数据科学和软件工程领域拥有5年的经验。他对从原始数据中获得的见解充满热情,并喜欢将其转换为创造卓越的商业价值。他的主要专长是Python,并具有Java和C ++的生产经验。他应用了先进的机器学习技术,例如计算机视觉,NLP,产品推荐系统,网络数据和经典数据科学,以解决数据繁重的项目。

展示更多

亚历克斯·冈萨雷斯(Alex Gonzalez)

自由职业Java开发人员

美国自2019年2月25日起在Toptal担任自由Java开发人员

Alex在开发软件(尤其是Web和移动应用程序)方面拥有十多年的经验。他领导了包括AT在内的公司的互动项目的开发&T,EMC,Legendary Pictures,Hewlett Packard,Foundation Capital,UCLA,Anaheim Ducks和LA18 Television。他开发的应用程序已在TechCrunch和iPod广告中出现。 Alex毕业于加利福尼亚大学伯克利分校,获得了应用数学学位。

展示更多

乔治·利纳特

自由职业Java开发人员

美国自2018年10月2日起在Toptal担任自由Java开发人员

乔治(George)是一位软件工程师,可以按时且在预算范围内构建您想要的产品。他参与了多个行业的项目,从大众汽车集团基于云的汽车经销商管理系统到微软的CosmosDb资源管理器。乔治还是一位经验丰富的面试官,接受了将近100次面试,并且在数据结构和算法方面拥有深厚的背景。

展示更多

肯·霍夫曼

自由职业Java开发人员

美国自2018年7月20日起在Toptal担任自由Java开发人员

Ken拥有20多年的独立承包商经验,为他的客户提供应用程序开发服务。在过去的12年中,他在.NET平台上开发了应用程序。他提供增值解决方案并完成项目直至完成的动机使他赢得了客户的尊重,并建立了长期的合作关系。

展示更多

立即注册以查看更多个人资料。

开始招聘

招聘指南

雇用优秀Java开发人员的指南

掌握Java并非易事。它广泛的类库包含各种功能和细微差别,其中许多功能和细微差别在普通开发人员中就消失了。掌握该语言的人可以对您的团队产生重大的积极影响'的生产力和您的系统上'的表现。以下是一些有针对性的问题,可帮助您确定语言的真正主人。

阅读招聘指南

爪哇招聘资源

信任飞行员
托塔尔 in the press

...使公司能够快速组建对特定项目具有适当技能的团队。

尽管对编码人员的需求不断增加,但托普塔尔(Toptal)却以几乎常春藤联盟级别的审查而自豪。

我们的客户
构建一个跨平台的应用程序以供全球使用
蒂埃里·雅基切维奇(Thierry Jakicevic)
构建一个跨平台的应用程序以供全球使用
1
2
3
为游戏创建一个应用
科纳·肯尼(Conor Kenney)
为游戏创建一个应用
1
2
3
引领数字化转型
埃尔玛·普拉泽(Elmar Platzer)
引领数字化转型
1
2
3
感言

Tripcents会'没有Toptal就不存在。 Toptal Projects使我们能够与产品经理,首席开发人员和高级设计师一起快速发展我们的基础。在短短60天内,我们从概念发展到了Alpha。速度,知识,专业知识和灵活性是首屈一指的。 Toptal团队与Tripcents的任何内部团队成员一样都是Tripcents的一部分。他们像其他所有人一样做出了贡献并获得了开发的所有权。我们将继续使用Toptal。首先,它们是我们的秘密武器。

布兰特利·佩斯(Brantley Pace),首席执行官& Co-Founder

Tripcents

我对Toptal的经验感到非常满意。我要与之合作的专业人员在几个小时内就与我通了电话。与他讨论我的项目后,我知道他是我想要的候选人。我立即雇用了他,他不花时间去参加我的项目,甚至通过添加一些可以改善我们整体外观的出色设计元素来加倍努力。

保罗·芬利(Paul Fenley),董事

邓恩& Associates

与我配对的开发人员令人难以置信-聪明,有驱动力和反应灵敏。过去很难找到质量工程师和顾问。现在不是't.

瑞安·洛克菲勒(Ryan Rockefeller),首席执行官

拉迪厄斯

托塔尔立即了解我们的项目需求。从第一天起,我们就与一位来自阿根廷的杰出自由职业者相匹配,这位自由职业者专注于我们的行业,与我们的团队无缝融合,了解我们的愿景,并取得了一流的成绩。 Toptal使与优秀的开发人员和程序员的联系变得非常容易。

联合创始人Jason Kulik

ProHatch

作为一家资源有限的小公司,我们可以'不能犯下代价高昂的错误。 Toptal为我们提供了一个经验丰富的程序员,他能够扎实地工作并立即开始做出贡献。这是一次很棒的经历,我们'd再次心跳重复。

校长Stuart Pocknee

特定于站点的软件解决方案

我们使用Toptal聘请了具有丰富Amazon Web Services经验的开发人员。我们采访了四位候选人,其中一位非常适合我们的要求。这个过程是快速而有效的。

AbnerGuzmánRivera,首席技术官兼首席科学家

照片Kharma

Sergio是一位很棒的开发人员。一流,响应迅速,高效地完成了工作。

丹尼斯·鲍德温(Dennis Baldwin),首席技术专家兼联合创始人

PriceBlink

与Marcin合作是一件快乐的事。他有能力,专业,灵活并且非常快速地了解需要什么以及如何实现它。

首席技术官AndréFischer

开机自检

我们需要一个可以立即开始我们项目的专家工程师。 Simanas的工作超出了我们的期望。无需采访和追逐专家开发人员,这可以节省大量时间,并且使每个人都对我们选择平台以使用更强大的语言感到更放心。 Toptal使该过程变得轻松便捷。现在,Toptal是我们寻求专家级帮助的第一位。

Web开发高级副总裁Derek Minor

网络世界媒体集团

托塔尔'的开发人员和架构师非常专业并且易于使用。他们生产的解决方案价格公道,质量一流,减少了我们的发布时间。再次感谢您,Toptal。

杰里米·韦塞尔斯(Jeremy Wessels),首席执行官

科尼奥西

我们在Toptal方面拥有丰富的经验。他们将我们与适合我们应用程序的完美开发人员配对,使过程非常容易。超出初始时间范围也很容易,而且我们能够在整个项目中保留相同的承包商。我们绝对推荐使用Toptal来快速,无缝地找到高素质的人才。

首席技术官Ryan Morrissey

应用商业技术有限公司

I'我对Toptal印象深刻。我们的开发人员每天与我交流,并且是一个非常强大的编码器。他'是一位真正的专业人士,他的工作非常出色。 Toptal的5星。

Pietro Casoar,首席执行官

罗宁游乐有限公司

与Toptal的合作经验非常丰富。在使用它们之前,我花了很多时间采访其他自由职业者,'找不到我需要的东西。与Toptal接触后,他们在短短几天内就使我成为了理想的开发人员。开发商我'与他合作不仅提供了高质量的代码,而且还就我没有的东西提出了建议 't thought of. It'对我来说很清楚,阿毛里知道他在做什么。强烈推荐!

首席执行官郑志强

Bulavard,Inc.

作为Toptal合格的前端开发人员,我还经营自己的咨询业务。当客户来找我帮助填补他们团队中的关键角色时,Toptal是我唯一推荐的地方。托塔尔'整个候选人池是最好的。 Toptal是我最物有所值的'我们发现了将近五年的专业在线工作。

首席技术官Ethan Brooks

朗格茨专利&商标工程有限公司

在Higgle中'早期,我们需要及时以合理的价格获得一流的开发人员。托帕特交付!

拉拉·阿尔达格(Lara Aldag),首席执行官

闲聊

托塔尔使寻找候选人变得异常容易,使您放心,他们具备应聘技巧。我绝对会向任何寻求高技能开发人员的人推荐他们的服务。

数据经理Michael Gluckman

Mxit

托塔尔能够迅速将我们的项目与最佳开发者匹配的能力实在是太棒了。开发人员已成为我们团队的一员,他们每个人所表现出的专业承诺水平令我感到惊讶。对于那些希望与最好的工程师进行远程工作的人员,Toptal就是您的最佳选择。

创始人Laurent Alis

Livepress

托塔尔使寻找合格的工程师变得轻而易举。我们需要一个经验丰富的ASP.NET MVC架构师来指导我们的启动应用程序的开发,Toptal在不到一周的时间内为我们找到了三个不错的候选人。做出选择后,工程师立即上线并开始运作。这比必须自己发现和审核候选人要快得多,容易得多。

联合创始人Jeff Kelly

协调解决方案

我们需要在Scala中进行一些短期工作,Toptal在24小时内找到了我们一个出色的开发人员。这根本不可能通过任何其他平台来实现。

弗兰科·阿尔达(Franco Arda),联合创始人

WhatAdsWork.com

托塔尔为正在快速发展和规模化的企业提供不妥协的解决方案。我们每个工程师'通过Toptal签约的ve已迅速融入我们的团队,并以最高的质量水准保持他们的工作,同时保持了飞速的发展速度。

格雷格·金博尔(Greg Kimball),联合创始人

nifti.com

如何通过Toptal雇用Java开发人员

1

与我们的一位行业专家交谈

Toptal工程总监将与您合作,以了解您的目标,技术需求和团队动力。
2

与手工挑选的人才一起工作

在几天之内,我们'将向您介绍适合您的项目的Java开发人员。平均比赛时间不超过24小时。
3

合适的,有保证的

与您的新Java开发人员一起试用(仅在满意时付款),以确保他们'在开始订婚之前重新选择合适的衣服。

常见问题

  • Toptal Java开发人员有何不同?

    在Toptal,我们彻底筛选了Java开发人员,以确保我们只与具有最高才能的人才相匹配。每年申请加入Toptal网络的100,000多人中,晋级的比例不到3%。您将与工程专家(从不聘请一般招聘人员或人力资源代表)合作,以了解您的目标,技术需求和团队动力。最终结果:专家审核了我们网络中的人才,并根据您的业务需求进行了定制匹配。 现在开始。

  • 我可以通过Toptal在不到48小时内雇用Java开发人员吗?

    根据可用性和进度的快慢,您可以在注册后48小时内开始与Java开发人员合作。 现在开始。

  • Toptal Java开发人员的无风险试用期是多少?

    我们确保您与Java开发人员之间的每次互动都以长达两周的试用期开始。这意味着您有时间确认参与将成功。如果您对结果完全满意,我们将为您收取时间费用,并继续为您服务。如果您不完全满意,则不会向您收费。从那里,我们可以分开,也可以为您提供另一位更合适的专家,我们将与他一起开始第二次无风险的试验。 现在开始。

分享
爪哇

如何聘请优秀的Java开发人员

挑战

今天,据报道,Java首次发布已经有20年了, 最需要的语言技能,而且差距很大(PHP排名第二,是亚军)。

由于Java应用程序的使用如此普遍,因此在简历中列出Java的开发人员并不缺乏。但是,与任何技术一样,人们都知道Java,然后 真的 懂Java。那么,如何确定真正的Java开发专家呢?

像生活中的许多技能一样,Java精通需要时间和好奇心来充分利用其功能。因此,如我们的帖子所述 寻找精英,有效的招聘流程需要评估候选人的许多方面,而不仅仅是技术知识;驱动力,完整性和创造力之类的属性对软件开发者而言同样重要。然后,可以用一些问题(例如此处提出的问题)来扩充评估候选人的维度的能力,以帮助确定真正的高素质Java专家。

评估基金会

我们从一些问题开始,这些问题可以帮助评估候选人对某些基本Java范例和概念的理解深度。

问:什么是匿名类?您何时,为什么以及如何使用它们?提供一个例子。

Anonymous classes are in-line expressions, often single-use classes for convenience, that help make your code more concise. The following example instantiates a new ActionListener to handle events associated with a button:

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        /* do something in response to button action event */
    }
});

这是有道理的,因为该类没有在其他地方使用,也不需要名称。但是,例如,如果将匿名类传递给注册方法,则可能需要跟踪其引用,以便以后可以取消注册。让我们扩展上面的示例以说明这一点:

ActionListener listener = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        /* do something in response to button action event */
    };
button.addActionListener(listener);

/* some time later... */

button.removeActionListener(listener);

问:什么是抽象类?您何时,为什么以及如何使用它们?提供一个例子。

抽象类 对于定义具体子类必须实现的抽象模板方法很有用。因此,保证所有具体的子类都遵循它们继承的抽象类中的抽象方法所指定的API。这有点类似于Java的方式 界面 为实现它的所有类指定一个API。

常见用例是存在一类具有共同行为的对象(例如,所有形状都有一个区域),但是计算或执行这些功能的细节因一个对象而异。例如:

 public abstract class Shape {
     public abstract double area();
 }
 
 public class Circle extends Shape {
     private double radius;
     
     public Circle(double radius) {
         this.radius = radius;
     }
     public double area() { return Math.PI * Math.pow(this.radius,2); }
 }
 
 public class Rectangle extends Shape {
     private double width, height;
     
     public Rectangle(double width, double height) {
         this.width = width;
         this.height = height;
     }
     public double area() { return this.width * this.height; }
 }

有两点值得注意:

  • 抽象类不能直接实例化。只有它们的具体子类是可实例化的。
  • 即使没有抽象方法,也可以将类声明为抽象类。这将阻止该类被实例化。例如,这在类层次结构中的基类没有抽象方法但本身不打算实例化的情况下很有用。

问:比较并对比检查和未检查的异常。提供示例。

未经检查的异常 是例外 不是 considered to be recoverable. Java doesn’t force you to catch or handle these because they indicate abnormal, unexpected problems with your code such as NullPointerException, ArithmeticExceptionIndexOutOfBoundsException. That is, these are problems you need to fix or prevent. Unchecked exceptions all derive from RuntimeException.

检查异常 是例外 被认为是可恢复的。必须将检查异常明确指定为方法API的一部分;也就是说,可能引发一个或多个已检查异常的方法必须在其方法声明中列出那些潜在的异常(Java编译器实际上会强制执行此操作)。

在调用引发异常的方法时,调用者必须要么处理(即捕获)这些异常,要么必须自己抛出异常。例如,如果某个方法引发了一个已检查的异常,则调用方可能决定忽略该错误并继续(吞下该错误),向用户显示一个对话框,或者重新引发该异常,以使更高一级的调用链中的方法可以处理该错误(在在这种情况下,它还必须声明它抛出了已检查的异常)。

例如:

public void readFile(File file) throws IOException, MyReadFileException {
    try {
        FileInputStream fis = new FileInputStream(file);
    } catch(FileNotFoundException e) {
        // We catch the FileNotFoundException and instead throw an IOException,
        // so we don't include FileNotFoundException in our "throws" clause above. 
        throw new IOException();
    }
    
    if (somethingBadHappened) {
        // We explicitly throw our own MyReadFileException here,
        // so we do include it in our "throws" clause above.
        throw new MyReadFileException();
    }
}

检查异常 clearly communicate and enforcing handling of error conditions. However, it can also be a pain for developers to continually need to include try/catch blocks to handle all known exceptions from the methods that they call. Although numerous checked exceptions are certainly permissible in Java, things can get a bit unwieldly. For example:

public void sillyMethod() throws DataFormatException, InterruptedException, 
	IOException, SQLException, TimeoutException, ParseException {
...
}

因此,有 激烈的辩论 例如,多年以来,在编写库时是使用检查的还是未检查的异常。就像许多此类辩论一样,事实是,确实没有一种千篇一律的,全面的正确答案。可检查的异常和未检查的异常各有其优点和缺点,因此,决定使用哪种异常在很大程度上取决于情况和上下文。

问:描述泛型,并提供Java中泛型方法和类的示例。

爪哇 仿制药 使程序员能够使用单个方法或类声明来指定可应用于多种不同数据类型的功能。泛型还提供了编译时类型安全性,使Java编程专家可以在编译时捕获无效类型。

例如,这里是一个 通用方法 that uses <E> as the placeholder for a generic type:

public <E> void printArray( E[] inputArray ) {
    // Display array elements              
    for ( E element : inputArray ) {        
        System.out.printf( "%s ", element );
    }
    System.out.println();
}

然后可以使用各种类型的数组调用上述方法,并适当地处理它们。例如。:

// invoke generic printArray method with a Double array
Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4 };
printArray(doubleArray);

// invoke generic printArray method with a Character array
Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };
printArray(charArray);

但是,有时您可能想要限制允许传递给泛型类型参数的类型的种类。例如,对数字进行操作的方法可能只希望接受Number或其子类的实例。这是通过使用 有界类型参数, which list the type parameter’s name followed by the extends keyword. For example:

// determines the largest of three Comparable objects
public static <T extends Comparable<T>> T maximum(T x, T y, T z) {                      
  T max = x; // assume x is initially the largest       
  if ( y.compareTo( max ) > 0 ) {
     max = y; // y is the largest so far
  }
  if ( z.compareTo( max ) > 0 ) {
     max = z; // z is the largest now                 
  }
  return max; // returns the largest object   
}

与泛型方法一样, 通用类 可以具有一个或多个用逗号分隔的类型参数。例如:

public class Cell<T> {
  private T val;

  public void set(T val) { this.val = val; }

  public T get() { return val; }

  public static void main(String[] args) {
     Cell<Integer> integerCell = new Box<Integer>();
     Cell<String> stringCell = new Box<String>();
    
     integerCell.add(new Integer(10));
     stringCell.add(new String("Hello World"));

     System.out.printf("Integer Value :%d\n\n", integerCell.get());
     System.out.printf("String Value :%s\n", stringCell.get());
  }
}

问:什么是多重继承?它有哪些潜在问题?为什么Java传统上不支持它?随着Java 8的发布,这有何变化?

多重继承 是某些面向对象的计算机编程语言的功能,其中对象或类可以从多个父对象或父类继承特征和功能。它不同于单一继承,在单一继承中,一个对象或类只能从一个特定的对象或类继承。

在Java 8之前,Java仅支持单继承。我们将在短期内讨论Java 8对多重继承的准支持,但是首先让我们了解多重继承会导致什么问题,以及为什么在Java中如此避免它。

反对多重继承的主要论点是它可能带来的复杂性和潜在的歧义。最典型的例子是通常提到的“钻石问题”,其中B类和C类继承自A类,而D类继承自B类和C类。如果A中存在一个B和C都具有的方法,则会产生歧义。覆盖。如果D没有覆盖它,则它继承该方法的哪个版本;否则,它将继承该方法的哪个版本。是B还是C?

Let’s consider a simple example. A university has people who are affiliated with it. Some are students, some are faculty members, some are administrators, and so on. So a simple inheritance scheme might have different types of people in different roles, all of whom inherit from one common “Person” class. The Person class could define an abstract getRole() method which would then be overridden by its subclasses to return the correct role type, i.e.:

但是,现在如果我们要模拟助教(TA)的角色会发生什么?通常,TA是 两个都 研究生 a faculty member. This yields the classic diamond problem of multiple inheritance and the resulting ambiguity regarding the TA’s getRole() method:

(顺便提一下,请注意上面继承图的菱形,这就是为什么将其称为“钻石问题”。)

Which getRole() implementation should the TA inherit? That of the Faculty Member or that of the Grad Student? The simple answer might be to have the TA class override the getRole() method and return newly-defined role called “TA”. But that answer is also imperfect as it would hide the fact that a TA is, in fact, both a faculty member and a grad student. There are multiple design approaches and patterns for addressing this type of situation without multiple inheritance, which is why some languages (Java being one of them) have made the decision to simply steer clear of multiple inheritance.

但是,Java 8通过允许在接口上指定默认方法而引入了一种对多继承的准支持的形式(在Java 8之前,接口上仅允许方法签名而不是方法定义)。自Java 允许单个类实现多个接口(而单个类只能扩展单个父类),因此Java 8中接口中方法定义的余量首次在Java中引入了菱形问题的可能性。

例如,如果A,B和C是接口,则B和C可以分别为A的抽象方法提供不同的实现,从而对实现B和C的任何D类造成菱形问题。D类都必须重新实现该方法(其主体可以简单地将调用转发给超级实现之一),否则歧义性将被拒绝为编译错误。

美食家Java

在这里,我们提出了一些更高级的概念和高级Java程序员可能会熟悉的问题。

问:如何使用外部条件变量可靠地退出线程?

Sometimes developers want to terminate a thread when an external condition becomes true. Consider the following example of a bus thread that continues to drive indefinitely until the pleaseStop variable becomes true.

boolean pleaseStop = false; // The bus pull cord.

public void pleaseStopTheBus() {
    pleaseStop = true;
}

public void startTheBus() {
    new Thread("bus") {
        public void run() {
            // Infinitely drive the bus.
            while (!pleaseStop) {
                // Take some time driving to the next stop.
            }
            pleaseStop = false; // Reset pull cord.
        }
    }.start();
}

似乎很简单。但是,Java不能保证在线程边界之间隐式地进行变量同步,因此不能保证该线程可靠地退出,这会给经验不足的Java开发人员带来很多麻烦。

要使上述代码正常工作,将需要同步线程,如下所示:

volatile boolean pleaseStop = false; // The bus pull cord.
Object driver = new Object(); // We can synchronize on any Java object.

public void pleaseStopTheBus() {
	// Here in "thread 1", synchronize on the driver object
    synchronized (driver) {
        pleaseStop = true;
    }
}

public void startTheBus() {
    new Thread("bus") {
        public void run() {
            // Infinitely drive the bus.
            while (true) {
				// And here in "thread 2", also synchronize on the driver object
                synchronized (driver) {
                    if (pleaseStop) {
                        pleaseStop = false; // Reset pull cord.
                        return; // Bus stopped.
                    }
                }
                // Take some time driving to the next stop.
            }
        }
    }.start();
}

Q: How can null be problematic and how can you avoid its pitfalls?

For one thing, null is often ambiguous. It might be used to indicate success or failure. Or it might be used to indicate absence of a value. Or it might actually be a valid value in some contexts.

And even if one knows the meaning of null in a particular context, it can still cause trouble if the hapless developer forgets to check for it before de-referencing it, thereby triggering a NullPointerException.

避免这些问题的最常见,最有效的技术之一是 使用有意义的非空默认值. In other words, simply avoid using null to the extent that you can. Avoid setting variables to null 和 avoid returning null from methods whenever possible (e.g., return an empty list rather than null).

此外,截至 JDK 8, Java has introduced support for the Optional<T> class (or if you’re using an earlier version of Java, you can use the Optional<T> class in the 番石榴库. Optional<T> represents and wraps absence and presence with a value. While Optional adds a bit more 仪式 to your code, by forcing you to unwrap the Optional to obtain the non-null value, it avoids what might otherwise result in a NullPointerException.

问:什么是“装箱”,应注意哪些问题?

爪哇’s primitive types are long, int, short, float, double, char, 经过teboolean. Often it’s desirable to store primitive values as objects in various data structures that only accept objects such as ArrayList, HashMap, etc. So Java introduced the concept of “boxing” which boxes up primitives into object class equivalents, e.g., Integer for int, Float for float, and Boolean for boolean. Of course, as objects, they incur the overhead of object allocation, memory bloat and method calls, but they do achieve their purpose at some expense.

“自动装箱”是编译器将原语自动转换为装箱的对象,反之亦然。这只是一个方便,例如:

ArrayList<Integer> ints = new ArrayList<Integer>();

// Autoboxing.  Compiler automatically converts "35" into a boxed Integer.
ints.add(35); 

// So the above is equivalent to:  ints.add(new Integer(35));

尽管它们具有便利性,但是装箱的对象因引入过时的bug而臭名昭著,特别是对于经验不足的Java开发人员而言。

一方面,请考虑以下几点:

System.out.println(new Integer(5) == new Integer(5));   // false

在上面的代码行中,我们正在比较 身份 的 two Integer objects. Since each new Integer(5) creates a new object, one new Integer(5) 将要 not equal another new Integer(5).

但是,以下似乎莫名其妙的区别更加令人困扰:

System.out.println(Integer.valueOf(127) == Integer.valueOf(127));   // true
System.out.println(Integer.valueOf(128) == Integer.valueOf(128));   // false

Huh? How can one of those be true 和 the other be false? That doesn’t seem to make any sense. Indeed, the answer is quite subtle.

正如一个容易忽视的解释 笔记 in the Javadoc for the Integer class, the valueOf() method method caches Integer objects for values in the range -128 to 127, inclusive, and may cache other values outside of this range as well. Therefore, the Integer object returned by one call to Integer.valueOf(127) 将要 match the Integer object returned by another call to Integer.valueOf(127), since it is cached. But outside the range -128 to 127, Integer.valueOf() calls, even for the same value, will not necessarily return the same Integer object (since they are not necessarily cached).

还需要注意的是,使用盒装对象进行计算所花费的时间可能比使用基元花费大约6倍,这可以通过以下基准测试代码来证明:

void sum() {
	Long sum = 0L; // Swap "Long" for "long" and speed dramatically improves.
	for (long i = 0; i <= Integer.MAX_VALUE; i++) {
		sum += i;
	}
}

Executing the above code with sum declared as Long took 6547ms whereas the same code with sum declared as long (i.e., the primitive type) took only 1138ms.

问:什么是类型擦除?

在语言中添加泛型并非没有问题。 Java泛型的一个特别棘手的问题是 类型擦除.

例如,请考虑以下代码片段:

List<String> a = new ArrayList<String>();
List<Integer> b = new ArrayList<Integer>();
return a.getClass() == b.getClass();  // returns true??!!

This should presumably return false since ab 是 different class types (i.e., ArrayList<String> vs. ArrayList<Integer>), yet it returns true. Why?

罪魁祸首是类型擦除。上面的代码通过所有Java编译器验证后,编译器 擦除 the StringInteger types in the above example, to maintain backward compatibility with older JDKs. The above code is therefore converted to the following by the Java compiler:

List a = new ArrayList();
List b = new ArrayList();
return a.getClass() == b.getClass();  // returns true (understandably)

And thus, in the compiled code, ab 是 both simply untyped ArrayList objects, and the fact that one was an ArrayList<String> 和 the other was an ArrayList<Integer> is lost. Although in practice type erasure-related issues rarely cause problems for developers, it is an important issue to be aware of and can in certain cases lead to really gnarly bugs.

问:描述观察者模式以及如何在Java中使用它。提供一个例子。

观察者模式 让对象注册以在观察到的对象发生更改时从其接收通知。 Java内置了对 Observable 类和 Observer interface.

这是一个Observable实现的简单示例:

public class Exhibitionist {
	MyObservable myObservable = new MyObservable();

	public Exhibitionist() {}

	public java.util.Observable getObservable() {
		return myObservable;
	}

	private void trigger(String condition) {
		myObservable.invalidate();
		myObservable.notifyObservers(condition);
	}

	private class MyObservable extends java.util.Observable {
		private void invalidate() {
			setChanged();
		}
	}
}

这是一个相应的观察者示例:

public class Voyeur implements Observer {

	public Voyeur(Exhibitionist exhibitionist) {
		// Register ourselves as interested in the Exhibitionist.
		exhibitionist.getObservable().addObserver(this);
	}
	
	@Override
	public void update(Observable o, Object arg) {
		// Called when the observable notifies its observers.
		System.out.println(arg.toString());
	}
}

使用此方法有两个缺点:

  1. 这 observed class must extend Observable 和 thus prevents it from extending a more desirable class (refer to our earlier discussion of 多重继承)
  2. Observed and observer classes are tightly coupled causing potential for NullPointerException’s if you are not careful.

To circumvent the first issue, an advanced developer can use a proxy (delegate) Observable object instead of extending it. To address the second issue, one can use a loosely coupled publish-subscribe pattern. For example, you might use Google’s Guava Library EventBus 对象连接到中间人的系统。

问:描述Java中的强引用,软引用和弱引用。您何时,为什么以及如何使用它们?

在Java中,当您分配新对象并将其引用(简称为指针)分配给变量时, 强大的参考 默认情况下创建;例如。:

String name = new String(); // Strong reference

但是,可以在Java中另外指定两个参考强度: SoftReferenceWeakReference。 (实际上,Java中还有一种附加的参考强度,即所谓的 PhantomReference. 但是,它很少使用,以至于即使经验丰富且敬业的Java开发人员也很可能不熟悉它,因此我们在此处的讨论中将其省略。)

为什么需要软引用和弱引用,什么时候有用?

爪哇的垃圾回收器(GC)是一个后台进程,可定期运行以从应用程序的内存堆中释放“死”对象(没有强引用的对象)。尽管GC有时会给人以魔幻般的黑匣子的印象,但它毕竟不是那么神奇。有时您需要帮助它以防止内存耗尽。

更具体地说,GC不会释放从一系列高度引用的对象中可以高度访问的对象。这简单的意思是,如果GC仍然认为需要某个对象,则将其搁置,这通常是您想要的(即,您不希望您需要在GC启动时突然消失的对象)。

但是有时强引用过强,软引用和弱引用可以派上用场。具体来说:

  • SoftReference 垃圾回收器会根据内存需求酌情清除对象。软引用最常用于实现对内存敏感的缓存。
  • WeakReference 对象不会阻止其参照对象被定型化,定型化然后再回收。弱引用最常用于实现规范化的映射。

包起来

爪哇继续作为一种占主导地位的流行语言而生存并蓬勃发展。但是,正如经过如此多次迭代的软件开发和应用程序开发中的任何一种语言所期望的那样,它具有许多并非所有开发人员都熟悉的细微差别和微妙之处。此外,Java功能的广度不断增长,需要大量的经验才能充分体会。因此,那些精通该语言的人可能会对您的开发团队的生产力以及系统的性能,可伸缩性和稳定性产生重大的积极影响。

本文提出的问题和技巧可能对识别真正的Java大师很有帮助。我们希望您在寻求高级Java开发人员中的精英人士时,将它们作为“从谷壳中解脱出来”的有用基础。但是,重要的是要记住,当您寻求聘用Java程序员时,这些工具仅作为要纳入整体招聘工具箱和策略的更大范围的工具。

(最后一点:如果您对Java感兴趣的是以Android为中心的移动应用程序,我们建议您阅读我们的 内幕人士Android面试指南 as well.)

热门Toptal Java出版物

带有JWT for REST API的Spring Security

经过 欧拉姆·戈达兹(Ioram Gordadze)

Haxe评论:Haxe 4的功能和优点

经过 凯文·布洛赫(Kevin Bloch)

信心十足的构建:JUnit测试指南

经过 尼基尔·班萨尔(Nikhil Bansal)

顶级Java开发人员需求量很大。

开始招聘