资讯专栏INFORMATION COLUMN

重拾 Java 基础

ideaa / 2791人阅读

摘要:阿里开始招实习,同学问我要不要去申请阿里的实习,我说不去,个人对阿里的印象不好。记得去年阿里给我发了邮件,我很认真地回复,然后他不理我了。

引言

最近好久没有遇到技术瓶颈了,思考得自然少了,每天都是重复性的工作。

阿里开始招实习,同学问我要不要去申请阿里的实习,我说不去,个人对阿里的印象不好。

记得去年阿里给我发了邮件,我很认真地回复,然后他不理我了。(最起码的尊重都没有,就算我菜你起码回复我一下啊?)

这种不尊重人的公司感觉去了也不快乐,当程序员最重要的就是快乐,不快乐写什么代码?

电话面

同学很友好地分享了他的阿里电话面经验。

问的都是看功底的问题,和开发经验无关(估计写上个几年代码不写框架应该也不知道这个)。

Java中的HashMaptransientvolatileHTTP301/302、生产者消费者算法。

HashMap都问烂了,问的是HashMap的底层原理,我知道你们自己写过JDK,请不要再问我HashMap里的put操作是怎么实现的了!

问源码的真的很讨厌,有什么意义吗?看过的就能答上,没看过的就答不上。

基础学习 transient

这并不是第一次听到transient这个词了,之前也用过,当我们使用YunzhiService进行综合查询时,我们会在实体中构造不映射到数据表的属性用于查询。

对于这些不映射为数据表字段的属性,我们使用@Transient注解。

Java中被transient修饰又是什么意思呢?

为什么要有transientStackOverflow的解释通俗易懂。

The transient keyword in Java is used to indicate that a field should not be part of the serialization (which means saved, like to a file) process.

Java中的transient关键字,意味着该字段不参与序列化,意味着不被保存,例如输出到文件中。

序列化?fastjson应该用到了这个关键字。

厉害厉害,fastjson开发团队基本功扎实。

volatile

这个关键字也不知道怎么能给大家通俗的讲出来,还是从实际的小例子出发吧?

大家回忆一下我们之前的单例模式,单例模式很常用,这个是必须要会的。

这是有问题的懒汉模式,多线程的时候就不能保持单例了。

public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
修正之前的问题

纠正一下之前博客中的一个问题,之前这样写虽然也能实现,但是效率极低,因为每次getInstance的时候都会被synchronized阻塞。

public class Singleton {

    private static Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

为了效率,不能在方法上加锁,所以需要在新建单例的时候加锁,保证只要只有一个单例被new出来。

看起来是没问题的,因为我们想当然的以为,一个线程new出来的Singleton,赋值给instance,然后另一个线程获取到的instance就一定不是空。实际上呢?

CPU结构

让我们来看Youtube上的一张图:

CPU内部结构中,thread-1thread-2运行在不同的核心上,每个核心有一个local cache,两个线程执行时,会将变量从shared cache读取到local cache

所以thread-1flag内容改变了,但是thread-2获取的flag还是从local cache中获取的,所以还是true

直到,thread-1flag更新到shared cache,然后再更新到thread-2local cachethread-2才知道flag变了。

所以我们的单例也一样,线程A新建了单例,然后其他线程再获取的时候,不一定是线程A所创建的单例对象。

拯救世界

volatile来拯救世界了。

private static volatile Singleton instance;

volatile做了两件事,强制将local cache写入到shared cache,同时使其他核心中的local cache对该数据的缓存无效。

所以,完整的单例应该是这样:

public class Singleton {

    private static volatile Singleton instance;

    private Singleton() {

    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
真正的单例

上面的讲解只是为了让大家了解Javavolatile的作用,实际的单例并不这样实现,而是使用私有静态内部类实现懒汉模式,当访问getInstance方法时,才加载Holder类,实例化单例。

public class Singleton {

    private static class Holder {
        private static Singleton instance = new Singleton();
    }

    private Singleton() {

    }

    public static Singleton getInstance() {
        return Holder.instance;
    }
}

呼,长出了一口气,两个晚上了,总算把volatile自己学会然后讲明白了,这个应该是发生的概率很小很小,我为了让volatile的验证让大家都看到,使用JDK自带的线程池,模拟实际的多线程环境,分别执行自己的测试代码,但还是没出现问题。

HTTP 301/302

去火狐开发者文档看看:

301 Moved Permanently

永久重定向,请求的资源已经被移动到了由Location头部指定的url上,搜索引擎会根据该响应修正。

HTTP升级到HTTPS时应该能用到。

302 Found

临时重定向,请求的资源被暂时的移动到了由Location头部指定的url上。浏览器会重定向到这个url,但是搜索引擎不会对该资源的链接进行更新。

可能会在某个后台服务瘫痪的时候再转给别的后台服务器时用到?

生产者消费者

至于最后的生产者消费者算法问题,我觉得意义不大,毕竟操作系统的课本出自位河北工业大学操作系统教师之手。

JDK中有阻塞队列,用的就是生产者消费者模型。用到的时候再说吧。

总结

每个人都是优秀的人,每个人都值得尊敬。

软件生而自由,不受世俗污染,不受凡尘打扰,我祝愿每一位软件工程师都能生活在自由、快乐之中。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73963.html

相关文章

  • 后台 - 收藏集 - 掘金

    摘要:探究系统登录验证码的实现后端掘金验证码生成类手把手教程后端博客系统第一章掘金转眼间时间就从月份到现在的十一月份了。提供了与标准不同的工作方式我的后端书架后端掘金我的后端书架月前本书架主要针对后端开发与架构。 Spring Boot干货系列总纲 | 掘金技术征文 - 掘金原本地址:Spring Boot干货系列总纲博客地址:http://tengj.top/ 前言 博主16年认识Spin...

    CrazyCodes 评论0 收藏0
  • Spring Security

    摘要:框架具有轻便,开源的优点,所以本译见构建用户管理微服务五使用令牌和来实现身份验证往期译见系列文章在账号分享中持续连载,敬请查看在往期译见系列的文章中,我们已经建立了业务逻辑数据访问层和前端控制器但是忽略了对身份进行验证。 重拾后端之Spring Boot(四):使用JWT和Spring Security保护REST API 重拾后端之Spring Boot(一):REST API的搭建...

    keelii 评论0 收藏0
  • 重拾Java Network Programming(二)InetAddress

    摘要:前言今天,我将梳理在网络编程中很重要的一个类以及其相关的类。这类主机通常不需要外部互联网服务,仅有主机间相互通讯的需求。可以通过该接口获取所有本地地址,并根据这些地址创建。在这里我们使用阻塞队列实现主线程和打印线程之间的通信。 前言 今天,我将梳理在Java网络编程中很重要的一个类InetAddress以及其相关的类NetworkInterface。在这篇文章中将会涉及: InetA...

    daryl 评论0 收藏0
  • CSS魔法堂:重拾Border之——更广阔的遐想

    摘要:也就是说我们操作的几何公式中的未知变量,而具体的画图操作则由渲染引擎处理,而不是我们苦苦哀求设计师帮忙。 前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-top-left/right-radius的水平半径之和大于元素宽度时,实际值会按比...

    lily_wang 评论0 收藏0
  • 架构~微服务

    摘要:接下来继续介绍三种架构模式,分别是查询分离模式微服务模式多级缓存模式。分布式应用程序可以基于实现诸如数据发布订阅负载均衡命名服务分布式协调通知集群管理选举分布式锁和分布式队列等功能。 SpringCloud 分布式配置 SpringCloud 分布式配置 史上最简单的 SpringCloud 教程 | 第九篇: 服务链路追踪 (Spring Cloud Sleuth) 史上最简单的 S...

    xinhaip 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<