精华内容
下载资源
问答
  • 点击上方“后端技术精选”,选择“置顶公众号”技术文章第一时间送达!作者:不学无数的程序员juejin.im/post/5da6eee2f265da5bb977d65c学习...
        

    点击上方“后端技术精选”,选择“置顶公众号”

    技术文章第一时间送达!

    作者:不学无数的程序员

    juejin.im/post/5da6eee2f265da5bb977d65c

    学习东西要知行合一,如果只是知道理论而没实践过,那么掌握的也不会特别扎实,估计过几天就会忘记,接下来我们一起实践来学习Spring事务的传播属性。

    传播属性

    传播属性定义的是当一个事务方法碰到另一个事务方法时的处理行为,一共有七种行为,定义如下

    640?wx_fmt=png

    其实只看概念的话已经很直截了当了说明了每个传播性的作用,此时我们再用具体的例子演示一下每个传播性属性下的行为。

    此次演示我们使用的是H2数据库,这个数据库是作用在内存里面的,所以对于我们演示事务效果来说正好,无需我们在进行其他的配置了,我们新建一个表。将下面语句放在schema.sql文件里面即可,SpringBoot程序在启动的时候就会自动为我们在内存里面建立这样的一个表。

    CREATE TABLE FOO (ID INT IDENTITY, BAR VARCHAR(64));
    

    演示之前我们会定义两个类FooService和BarService。我们使用BarService里面的方法进行调用FooService中的方法。

    环境准备

    在进行事务演示之前,其实可以分为以下几种情况,根据排列组合,我们可以得出以下八种情况

    • 调用者:有无事务

    • 调用者:是否有异常

    • 被调用者:有无事务(这个是通过传播属性进行控制的)所以并不在排列组合中

    • 被调用者:是否有异常

    640?wx_fmt=png

    异常类

    其中的RollbackException是我们自己定义的一个异常类

    @Service
    public class BarServiceImpl implements BarService{
        @Autowired
        private FooService fooService;
    
         // PROPAGATION_REQUIRED演示 无事务
        @Override
        public void testRequiredNoTransactional() throws RollbackException {
            fooService.testRequiredTransactional();
        }
    }
    

    调用者

    在BarService中定义两个方法,一个是带着事务的,一个是不带事务的

    // 有事务
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void hasTransactional() throws RollbackException {
    
    }
    
    // 无事务
    @Override
    public void noTransactional() throws RollbackException {
    
    }
    

    接下来我们就根据俄上面定义的八种情况进行事务传播属性的学习。

    PROPAGATION_REQUIRED

    在此传播属性下,被调用方是否新建事务取决去调用者是否带着事务。

    想要了解这个传播属性的特性,其实我们演示上面八种情况的两个例子就够了

    640?wx_fmt=png

    • 第一种情况我们在被调用者抛出异常的情况下,如果查询不到插入的数据,那么就说明被调用者在调用者没有事务的情况下自己新建了事务。

    • 第二种情况我们在调用者抛出异常的情况下,如果查询不到插入的数据,那么就说明被调用者在调用者有事务的情况下就加入当前事务了。

    我们先来看一下被调用者的类的方法例子。

    @Service
    public class FooServiceImpl implements FooService {
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        // REQUIRED传播属性-被调用者有异常抛出
        @Override
        @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
        public void testRequiredHasException() throws RollbackException {
            jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ("+Global.REQUIRED_HAS_EXCEPTION+")");
            throw new RollbackException();
        }
    
        // REQUIRED传播属性-被调用者无异常抛出
        @Override
        @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
        public void testRequiredNoException() throws RollbackException {
            jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ("+Global.REQUIRED_NO_EXCEPTION+")");
        }
    }
    

    接下来我们看一下调用者方法的例子

    @Service
    public class BarServiceImpl implements BarService{
        @Autowired
        private FooService fooService;
    
        // 有事务
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void hasTransactional() throws RollbackException {
            // 调用者有事务,抛异常  被调用者无异常
            fooService.testRequiredNoException();
            throw new RollbackException();
        }
    
        // 无事务
        @Override
        public void noTransactional() throws RollbackException {
            // 调用者无事务,不抛异常  被调用者有异常
            fooService.testRequiredHasException();
        }
    }
    

    此时我们在程序调用时进行查询

    String noException = Global.REQUIRED_NO_EXCEPTION;
    String hasException = Global.REQUIRED_HAS_EXCEPTION;
    
    try {
        barService.noTransactional();
    }catch (Exception e){
        log.info("第一种情况 {}",
                jdbcTemplate
                        .queryForObject("SELECT COUNT(*) FROM FOO WHERE BAR='"+hasException+"'", Long.class));
    }
    
    try {
        barService.hasTransactional();
    }catch (Exception e){
        log.info("第二种情况 {}",
                jdbcTemplate
                        .queryForObject("SELECT COUNT(*) FROM FOO WHERE BAR='"+noException+"'", Long.class));
    }
    

    查看打印出来的日志

    2019-10-16 13:02:04.142  INFO 11869 --- [           main] c.e.t.t.TransactionApplication           : 第一种情况 0
    2019-10-16 13:02:04.143  INFO 11869 --- [           main] c.e.t.t.TransactionApplication           : 第二种情况 0
    

    我们看到我们都没有查到相应的数据,说明数据都回滚了。此时我们应该就理解了那句话支持当前事务,如果没有就新建事务。

    PROPAGATION_SUPPORTS

    被调用者是否有事务,完全依赖于调用者,调用者有事务则有事务,调用者没事务则没事务。

    接下来我们还是用上面的两个例子进行演示

    640?wx_fmt=png

    • 第一种情况:被调用者抛出异常的情况下,如果仍能查询到数据,说明事务没有回滚,说明被调用者没有事务

    • 第二种情况:调用者抛出异常情况下,如果查不到数据,说明两个方法在一个事务中

    接下来仍然是例子演示

    被调用者,只是将@Transactional注解中的propagation属性更换为了Propagation.SUPPORTS

    // SUPPORTS传播属性-被调用者有异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void testSupportsHasException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.SUPPORTS_HAS_EXCEPTION+"')");
        throw new RollbackException();
    }
    
    // SUPPORTS传播属性-被调用者无异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.SUPPORTS)
    public void testSupportsNoException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.SUPPORTS_NO_EXCEPTION+"')");
    }
    

    调用者和上面的例子调用一样,我们直接查看执行效果

    2019-10-16 13:50:27.738  INFO 12174 --- [           main] c.e.t.t.TransactionApplication           : 第一种情况 1
    2019-10-16 13:50:27.741  INFO 12174 --- [           main] c.e.t.t.TransactionApplication           : 第二种情况 0
    

    我们看到了在第一种情况下查到了数据,说明在第一种情况下被调用者是没有事务的。此时我们应该就理解了这句话 支持当前事务,如果没有就不以事务的方式运行。

    PROPAGATION_MANDATORY

    依然是这两个例子进行演示

    640?wx_fmt=png

    • 第一种情况:因为调用者没有事务,所以此传播属性下应该是抛异常的

    • 第二种情况:被调用者的事务和调用者事务是同样的

    接下来是被调用者的代码例子

    // MANDATORY传播属性-被调用者有异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
    public void testMandatoryHasException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.SUPPORTS_HAS_EXCEPTION+"')");
        throw new RollbackException();
    }
    
    // MANDATORY传播属性-被调用者无异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.MANDATORY)
    public void testMandatoryNoException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.SUPPORTS_NO_EXCEPTION+"')");
    }
    

    调用者和上面的例子调用一样,我们直接查看执行效果

    2019-10-16 13:58:39.178 ERROR 12317 --- [           main] c.e.t.t.TransactionApplication           : org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
    2019-10-16 13:58:39.276  INFO 12317 --- [           main] c.e.t.t.TransactionApplication           : 第一种情况 0
    2019-10-16 13:58:39.281  INFO 12317 --- [           main] c.e.t.t.TransactionApplication           : 第二种情况 0
    

    我们发现和我们推测一样,说明被调用者是不会自己新建事务的,此时我们应该就理解了这句话支持当前事务,如果当前没事务就抛异常。

    PROPAGATION_REQUIRES_NEW

    此传播属性下,无论调用者是否有事务,被调用者都会新建一个事务

    640?wx_fmt=png

    • 第一种情况:调用者无事务,被调用者会新建事务,所以查不到数据

    • 第二种情况:调用者有事务,被调用者会新建一个事务,所以调用者抛异常影响不到被调用者,所以能查到数据

    接下来我们演示代码。

    被调用者

    // REQUIRES_NEW传播属性-被调用者有异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void testRequiresNewHasException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.REQUIRES_NEW_HAS_EXCEPTION+"')");
        throw new RollbackException();
    }
    
    // REQUIRES_NEW传播属性-被调用者无异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
    public void testRequiresNewNoException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.REQUIRES_NEW_NO_EXCEPTION+"')");
    }
    

    调用者的例子和上面的相同,我们直接来看执行情况

    2019-10-16 16:29:20.296  INFO 15553 --- [           main] c.e.t.t.TransactionApplication           : 第一种情况 0
    2019-10-16 16:29:20.298  INFO 15553 --- [           main] c.e.t.t.TransactionApplication           : 第二种情况 1
    

    我们发现和我们的推论是一样的,说明调用者的事务和被调用者的事务完全无关。此时我们应该就理解这句话了无论当前是否有事务,都会新起一个事务。

    PROPAGATION_NOT_SUPPORTED

    无论调用者是否有事务,被调用者都不以事务的方法运行

    同样是这两个例子

    640?wx_fmt=png

    • 第一种情况:被调用者都不会有事务,那么在抛异常之后就能查到相应的数据

    • 第二种情况:在调用者有事务的情况下,被调用者也会在无事务环境下运行,所以我们依然能查到数据

    接下来验证我们的猜测

    // NOT_SUPPORTED传播属性-被调用者有异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void testNotSupportHasException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.NOT_SUPPORTS_HAS_EXCEPTION+"')");
        throw new RollbackException();
    }
    
    // NOT_SUPPORTED传播属性-被调用者无异常抛出
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public void testNotSupportNoException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.NOT_SUPPORTS_NO_EXCEPTION+"')");
    }
    

    然后查看执行结果

    2019-10-16 16:38:35.065  INFO 15739 --- [           main] c.e.t.t.TransactionApplication           : 第一种情况 1
    2019-10-16 16:38:35.067  INFO 15739 --- [           main] c.e.t.t.TransactionApplication           : 第二种情况 1
    

    我们可以看到在最后两种情况都查到了数据,根据演示效果应该可以理解这句话了,不支持事务,如果当前存在事务,就将此事务挂起不以事务方式运行。

    PROPAGATION_NEVER

    调用者有事务,被调用者就会抛出异常

    640?wx_fmt=png

    这个就不演示,相信大家看到这里应该都会明白在第一种情况下我们是能够查到数据的。在第二种情况下由于调用者带着事务,所以会抛异常。

    PROPAGATION_NESTED

    此传播属性下,被调用者的事务是调用者的事务的子集。

    我们重点说一下NESTED的传播属性的特性

    640?wx_fmt=png

    关于什么是嵌套事务的关系,我们用下面三个例子能够进行演示。

    640?wx_fmt=png

    • 第一种情况:如果查不到数据,则说明在调用者无事务情况下,被调用者会新起一个事务

    • 第二种情况:如果查不到数据,说明外层事务能够影响内层事务

    • 第三种情况:如果查到数据,说明内层事务不影响外层事务

    接下来我们编写具体的代码

    // NESTED传播属性-回滚事务
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
    public void testNestedHasException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.NESTED_HAS_EXCEPTION+"')");
       // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        throw new RollbackException();
    }
    
    // NESTED传播属性-不回滚事务
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NESTED)
    public void testNestedNoException() throws RollbackException {
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.NESTED_NO_EXCEPTION+"')");
    }
    

    然后接下来的调用者也会有点区别

    @Override
    @Transactional()
    public void hasTransactionalNoException() throws RollbackException {
        // NESTED传播属性 - 调用者有事务,不抛异常  被调用者有异常
        jdbcTemplate.execute("INSERT INTO FOO (BAR) VALUES ('"+Global.NESTED_HAS_EXCEPTION_TWO+"')");
        fooService.testNestedHasException();
    }
    

    然后执行效果

    2019-10-16 18:01:06.387  INFO 17172 --- [           main] c.e.t.t.TransactionApplication           : 第一种情况 0
    2019-10-16 18:01:06.389  INFO 17172 --- [           main] c.e.t.t.TransactionApplication           : 第二种情况 0
    2019-10-16 18:01:06.390  INFO 17172 --- [           main] c.e.t.t.TransactionApplication           : 第三种情况 1
    

    可以看出来嵌套事务的本质就是外层会影响内层,内层不影响外层。而REQUIRES_NEW则是互不影响。

    总结

    到现在我们已经全部分析完了七种传播属性,从写这篇文章开始到结束其中也碰到过一些坑,有些是不自己实践一遍是根本不知道的,所以我还是建议读者看完这篇文章以后自己进行实践,演示各种情况,只有这样才能够烂熟于心。

    Github地址

    https://github.com/modouxiansheng/Doraemon

    推荐阅读(点击即可跳转阅读)

    1. 

    2. 

    3. 

    4. 

    5. 

    640?wx_fmt=png

    展开全文
  •  idea:产品设计喵一个想法。  人员配置:  攻城狮:前端后端服务器齐撸  产品设计:设计原型/UI效果图(界面/交互)齐撸]  流程分析:  1.产品设计喵反复打磨自己的想法,明确要做什么样的产品,让...

    app开发

      idea:产品设计喵有一个想法。

      人员配置:

      攻城狮:前端后端服务器齐撸

      产品设计:设计原型/UI效果图(界面/交互)齐撸]

      流程分析:

      1.产品设计喵反复打磨自己的想法,明确要做什么样的产品,让产品要和市面上现有产品实现差异化或者超越。最好能一句话说明产品能为为什么用户解决什么情景下的什么问题。

      攻城狮可以get产品愿景。

      2. 产品设计喵确定功能list。按重要程度排序。

      攻城狮可以get一份功能list,把关功能实现情况,提前做一些开发准备工作。

      3.产品设计喵制作原型。(界面,交互的构思表达)

      攻城狮可以把关你的功能是否在原型中体现,是否符合功能优先级,交互效果是否能够实现,是否更适合交互效果和界面展现方式。

      4.产品设计喵制作UI设计效果图并切图(遵守相应平台规范,有的规范可以无视有的需要遵守,尽量UI元素都保持独立性)

      攻城狮get效果图,可以提效果图意见。

      效果图确定话的攻城狮告诉你他那边你需要提供什么UI元素,你从你效果图上获得相应元素给攻城狮即可。元素大小需根据适配提供不同比例大小。

      5.攻城狮开发。

      6.团队测试修改bug。

      测试点各自不一样相互配合~

      7.以上流程迭代数次直至团队满意再上架appstore ~

      钱:

      自费做得话,用花费时间×个人时薪。

      时间:

      因人而异。

      最大的难点:

      产品是否满足了你定位的群体的需求,这些1234期间需要找可能的目标用户询问或者如果自己就是其中一个用户,自己站在用户角度反省。所以你随时可能在1234都会改变主意。

      第二大难点:

      团队人多的话,人多口杂,大家都有想法,需求优先级排序需要求同存异。

      其次的难点:

      因为信息不对称,需要及时沟通,通知攻城师需求变更,界面变化,交互变化。其他的很多细节就不详细说了。认识太多杭州APP开发的公司,技术已经没有难点,关键还是产品的设计。

    转载于:https://www.cnblogs.com/proginn/p/5596723.html

    展开全文
  • 后端服务器,移动互联网后端,经典Windows界面开发,移动互联网端界面开发,跨平台界面开发,图形分析,系统架构,应用设计,还有现在最为流行的分布架构等一些新的技术领域。 这么牛的语言,你是不是想知道怎样...

    背景

    随着互联网及互联网+深入蓬勃的发展,经过40余年的时间洗礼,C/C++俨然已成为一门贵族语言,出色的性能使之成为高级语言中的性能王者。而在今天,它又扮演着什么样重要的角色呢?请往下看:

    后端服务器,移动互联网后端,经典Windows界面开发,移动互联网端界面开发,跨平台界面开发,图形分析,系统架构,应用设计,还有现在最为流行的分布架构等一些新的技术领域。

     这么牛的语言,你是不是想知道怎样学习和掌握它呢?接下来请看经过我们整理过C/C++工程师必备知识的思维导图。

    初学者看到这么密集的知识点,是不是有点眼晕呢?的确,C/C++是一门知识面覆盖很广的学科。想学好C/C++的你并不需要慌张,内容虽多,但依然有法可依。只要有足够的耐心和毅力,加上正确的学习方法,就不怕你学不好C/C++。

    既然如此,C/C++开发到底需要学些什么呢,又应该怎么学呢?接下来一起来看看如何从零基础学习C/C++开发,快速进入牛人之列,掌握这门贵族语言。

    一、初级入门阶段

    在入门之初,首先要做的是通过C/C++语言的学习培养编程思维和动手能力,深刻理解面向过程和面向对象的思想方法。这个阶段你需要学习:

    ① C语言

    数据类型、变量、内存布局、指针基础;

    字符串、一维数组、二维数组;

    一级指针,二级指针,三级指针,N级指针概念,指针数组和数组指针;

    结构体、文件的使用;

    动态库的封装和设计;

    函数指针回调函数。

     

    ② C++语言

    面向对象编程思想;

    类的封装,构造和析构、静态成员、对象管理;

    类的构造(有参构造函数、无参构造、拷贝构造、默认构造函数)和析构;

    对象动态管理、友元函数、友元类、操作符重载;

    C++编译器对象管理模型分析;

    类对象的动态管理(new/delete);

    友元函数和友元类;

    运算符重载(一元运算符、二元运算符、运算符重载难点、项目开发中的运算符重载);

    类的继承、多继承及其二义性、虚继承;

    多态(概念、意义、原理剖析、多态案例);

    虚函数、纯虚函数、抽象类(面向抽象类编程思想案例);

    函数模板、类模板,模板的继承;

    C++类型转换;

    C++输入输出流(标准I/O 文件I/O 字符流I/O);

    C++异常处理(异常机制、异常类型、异常变量、异常层次结构、标准异常库);

    ③ 常见常用的IDE开发工具

    诸如Windows平台VC系列:VC++6.0(比较古老) ;Visual Studio2013, Visual Studio2015;Mac平台的XCode系列,还有CodeBlock,另附一些高级编辑器Notepad++, EditPlus,UE等一些开发工具的常用设置和一些常见快捷键的使用。

    此阶段的学习难度系数不大,掌握这些内容之后,可以做些简单的小项目。当然了如果你想用这些技能找工作的话确实是比较困难的。这时你还应该在加把劲进一步学习第二阶段。

    推荐一下自己的linuxC/C++交流群:973961276!整理了一些个人觉得比较好的学习书籍、视频资料以及大厂面经视频共享在群文件里面,有需要的小伙伴可以自行添加哦!~

    学习编程是个枯燥的过程,所以在学习理论知识感觉到无趣以至于坚持不下去的时候可以自己动手写几个实用的小项目或者功能,这种成就感正是学习编程的意义所在,而这会让你继续保持对编程的热情。下面这个GIF是我刚写的一个塔防小游戏,给初学编程的朋友参考一下,如果需要源码的话可以进群获取哦

    二、C/C++开发进阶

    这一阶段的目标才是达到C/C++软件工程师开发行业的基本要求,这个阶段是我们走向C/C++开发的进阶之路,更是一个让自己找份薪水比较体面的工作的筹码。

    如果在此部分遇到不懂的或者没有见过的知识点和名词,可先将本文收藏,供以后细细研读。

    那么这个阶段,我们又应该掌握什么呢,继续往下看: 

    ①    C++进阶之STL

    STL = Standard Template Library,即标准模板库。这是提高开发效率的极品工具。通过学习此阶段,应掌握泛型编程技巧,理解容器类在C++语言中的应用模式,以及熟练掌握全部STL类的使用方法。

    ②    C++进阶之设计模式

    决定一个项目成败最重要的因素是项目总体的设计,通过本阶段的学习,可掌握面向对象编程中重要的一环,是编码前建模的技巧所在。单例模式;工厂模式;代理模式;迭代模式等,这些都是你要掌握的哦。

    ③    C++进阶之数据结构基础

    这是所有编程语言中最应该学习的部分,程序组成的基础之一。

    顺序存储、链式存储、循环链表;

    双向链表、栈(顺序和链式)、队列(顺序和链式);

    栈的应用、树基本概念及遍历、二叉树;

    排序算法、并归算法、选择、插入、快速、希尔。

    以上这些内容你知道吗?

    ④    C++进阶之UI界面开发

    掌握QT类库构架,图形界面开发模型;

    掌握QT开发技巧,消息机制,图形处理;

    掌握QT网络编程,UDP,TCP使用方式;

    掌握QT文件处理方式,序列化;

    掌握QT在windows,linux,ios,android不同平台下的移植技术。

    ⑤    C++进阶之Unix/Linux网络服务器

    掌握Unix/Linux平台开发方式;

    熟练使用系统调用;

    熟练Unix/Linux内存管理,进程,线程调度;

    熟悉网络服务器开发方式,熟练编写TCP,UCP网络服务程序;

    掌握同步/异步IO模型在网络编程中的使用方式。

    ⑥ C++进阶之数据库开发

    掌握SQL语言的实用技巧。Oracle,MySQL数据库的使用方式。

    如果你能熟练掌握以上列出的技能,具备解决复杂问题和技术难点的能力,而且你能独立开发一些比较复杂的功能模块,那么很荣幸地告诉你,你已经达到中级水平,薪资过万对你来说简直是小菜一碟。

    三、C++开发高级 

    读到此处的你,相信你有更高的目标。即是当下炙手可热的全栈开发工程师,既晓前端,又通后台。快速定位问题,解决问题对他们来说已是小菜一碟,就是人们常说的神秘大牛,只在公司技术攻关的时候才会才看到他们的身影。

    ①此阶段软件开发工作所需的知识和技能相对较难,高级软件工程师编码熟练度和规范性需要达到一定要求;

    ②具备一定的项目能力(包括调试能力、文档编写能力、测试能力等)和综合技术素质(包括对软件生命周期的理解、对设计模式的理解、必备的行业知识和经验等);.

    ③了解主流的后台技术和前后端协作方式,能从全局角度理解项目的整个生命周期。

    如果你能熟练掌握以上三个阶段的知识技能,那么你就可以满足C++开发行业的高级需求。

    零声学院:一切只为渴望更优秀的你

    C/C++在近40年的发展历程中,一直以来都被猎头作为竞相角逐的弄潮儿。零声学院的课程从市场需求,技术潮流出发,将企业需要掌握的技术做了系统性的整合。同时,在课程的设计上充分考虑到大部分学员零基础的情况,各模块相互衔接,逐步升级,让学员在学习过程中能更好地过渡和理解吸收。

    展开全文
  • 今天中午在逛简书的时候发现一些大厂也会问Object对象里面什么方法(也算是一个知识点吧),Object我还没去认真复习过,于是这篇主要看看Object对象什么要注意的地方~那么接下来就开始吧,如果文章错误的地方请...

    前言

    之前花了点之间时间去搞多线程的基础知识了,难呀难呀难呀….打算写一篇线程池的就暂时将多线程系列停止了…

    今天中午在逛简书的时候发现一些大厂也会问Object对象里面有什么方法(也算是一个知识点吧),Object我还没去认真复习过,于是这篇主要看看Object对象有什么要注意的地方~

    那么接下来就开始吧,如果文章有错误的地方请大家多多包涵,不吝在评论区指正哦~

    一、Object对象简介

    声明:本文都是使用JDK1.8

    我们学Java的知道,Java是一门面向对象的语言。无论在Java中出现什么,都可以认为它是对象(除了八大基本数据类型。当然了,八大基本数据类型也能装箱成为对象):

    • 而Object就是这些对象的最高级别的,所有的Java对象都隐式地继承了Object对象(不用显示写extends继承)
    • 所有的Java对象都拥有Object默认的方法

    那么我们看看Object有什么方法:

    4c94d52383b0227988831942724aa084.png

    其实就可以归纳成几个:

    • registerNatives()【底层实现、不研究】
    • hashCode()
    • equals(Object obj)
    • clone()
    • toString()
    • notify()
    • notifyAll()
    • wait(long timeout)【还有重载了两个】
    • finalize()

    Object一共有11个方法,其中一个为底层的实现registerNatives(),其中两个wait()和wait(long timeout, int nanos)重载方法。

    • 所以我们真正需要看的就是8个方法

    还有一个属性

    d65de5e2f56543e6f728211393b8ed28.png

    二、equals和hashCode方法

    equals和hashCode方法可以说是面试的重点题了,配合着String可以说在面试题中哪都有它们的存在

    首先,我们来看看equals和hashCode在Object中原生的实现吧:

    hashCode:

    public native int hashCode();

    equals:

     public boolean equals(Object obj) { return (this == obj); }

    看上去都非常简单:

    • hashCode()由native方法底层实现了。
    • equals()就直接==判断是否相等了。

    想要更加清晰它们究竟是做什么的,我们来读读它的注释:

    57c2da901b99b17b2316918cfdfe4ef3.png
    244f3214c1ebbafc5a15eb709c34b86b.png

    根据注释我们可以总结以下的要点

    • 重写equals()方法,就必须重写hashCode()的方法
    • equals()方法默认是比较对象的地址,使用的是==等值运算符
    • hashCode()方法对底层是散列表的对象有提升性能的功能
    • 同一个对象(如果该对象没有被修改):那么重复调用hashCode()那么返回的int是相同的!
    • hashCode()方法默认是由对象的地址转换而来的
    • equals()方法还有5个默认的原则:
    • 自反性--->调用equals()返回的是true,无论这两个对象谁调用equals()都好,返回的都是true
    • 一致性--->只要对象没有被修改,那么多次调用还是返回对应的结果!
    • 传递性--->x.equals(y)和y.equals(z)都返回true,那么可以得出:x.equals(z)返回true
    • 对称性--->x.equals(y)和y.equals(x)结果应该是相等的。
    • 传入的参数为null,返回的是false

    为啥说hashCode()以散列表为底层带来性能的提升是很容易理解的。我们再来回顾一下HashMap的插入:

    aef75e32073a294f414a68f368199e7b.png

    如果hash值都不相等,那么可以直接判断该key是不相等的了!

    2.1equals和hashCode方法重写

    equals()方法默认是比较对象的地址,使用的是==等值运算符。但是按我们正常开发来说,比较的是对象地址是没有意义的

    • 一般地,如果我们有两个Address对象,只要这两个对象的省号、城市号、街道号相等,我们就认为这两个对象相等了!
    a2e9fdc219afca310fdbf890fa8be9f6.png

    2.2String实现的equals和hashCode方法

    我们在初学的时候可能就听过了:String已经实现了equals和hashCode方法了。

    • 这也就是为什么,我们可以直接使用String.equals()来判断两个字符串是否相等!

    下面我们就来看看它的实现吧:

    0161a3c55012a56cddfd0a68b9ea0e84.png
    ebb9aeb5216aea8c40dc59eeff248f8e.png

    三、toString方法

    接下来我们看看toString方法,也十分简单:

    a7cc7ac400713317e34eec7505ca0dcd.png

    toString方法主要是用来标识该对象的:

    05d9def3a98b365ad9c0edf25c3a4faf.png

    从上面的结果我们都可以看出来:得出的结果我们并不能看到什么东西~

    于是我们一般都重写toString(),那么打印出的结果就很方便我们调试了

     @Override public String toString() { return "Address{" + "provinceNo=" + provinceNo + 
    展开全文
  • 今天中午在逛简书的时候发现一些大厂也会问Object对象里面什么方法(也算是一个知识点吧),Object我还没去认真复习过,于是这篇主要看看Object对象什么要注意的地方~那么接下来就开始吧,如果文章错误的地方请...
  • 他们有那么忙吗? 各种各样的APP、微信小程序充斥着我们的生活,可是谁知道做一个APP,微信小程序,少则2个月,多则半年,需要有多… 后来我终于知道了问题的答案。 正常的开发流程是这样的: 原型(合格的原型)-...
  • 很多同学都在学习WEB,我们忍不住会去想web前端开发现在如此火爆,那么web前端开发都要学些什么知识呢?WEB开发前途吗?web多久能入门? Web前端工程师是协调前端工程师、后端程序员实现网站页面活程序的界面...
  • 写在前面:在日常开发过程中,人做前端开发,人负责后端开发。接口的主要作用就是连接前后台。但是,由于前端和后端开发的速度可能不一样,尤其是后端开发好了,但前端还未开发。这种时候我们需要做接口测试吗?...
  • java和前端哪个学?

    2021-01-19 16:06:04
    java和前端哪个难学? 不是同一样东西,无法比较。 Java 和 JavaScript 哪个难学? 前端 和 后端 哪个难学?...理解了也没有那么难吧。 我大学的学的第一门语言是 C 和 C++ 单纯就语言难说,刚开始接触 C++
  • 不是同一样东西,无法比较。Java 和 JavaScript 哪个难学?前端 和 后端 哪个难学?问Java 和 前端哪个难学, 就像在问牛排和中餐哪个好吃一样。Java 是门编程语言,前端是一个领域不...理解了也没有那么难吧。我大学...
  • 昨天有个群友去知乎一面,回来在群里抱怨知乎一面有多难,小编让群友把面试题分享了出来,让大家看看真有那么难吗? 文章中所有面试题和答案小编都为大家整理了:戳这里免费领取,暗号:CSDN,还有更多大厂面试专题...
  • 回首望去几年前的博客还是那么稚嫩。 <ul><li>回首这几年:</li></ul> 从一个javaer接触前端转向全栈。 从前端到后端到运维,经历了几次前后端架构的演变,踩了无数的坑,度过无数眠的夜...
  • 我自己也这样的趋势,当接触了更全面的研发流程之后,就很保持对 UI 细节以及曾经追求的极致用户体验的关注度了。这或许也恰恰说明,对于某些类型的产品或某些阶段的产品来说,UI 细节没那么重要。而对于重视...
  • Spring Boot 支持 Https 有那么难吗? jwt-demo Spring Security 结合 Jwt 实现无状态登录 docker-jib 别用 Dockerfile 部署 Spring Boot 啦!松哥教你两步搞定! 松哥简介 大家好,我是江南一点雨,管理学...
  • 如果赶上一个语言火的时候,您想不赚钱都,android ,苹果,大数据,python我们没有赶上第一批,现在go语言您还想错过吗? 现在go语言已经在大公司开始使用,在做服务这块慢慢已经走上热点,现在go语言视频很少...
  • 点右上角 Star,点亮你的头像,开源你的贡献,爱你 ! 推荐选择在线 wiki阅读(目录),内容与Github同源,解决 Github 访问速度慢的问题。 :gift::gift::gift: 号外号外,送你九年编程经验!推荐 JAVA核心...
  • 由于HTML5技术非常新,国内很多开发者在实践过程中经常遇到非常多的困难,例如如何入门与解决BUG等常见问题,都很找到解答问题的中文资源。因此,开发者们亟需一本能够带领他们入门的HTML5书籍。 2011年也是移动...

空空如也

空空如也

1 2 3
收藏数 49
精华内容 19
关键字:

后端有那么难吗