一读小说 » 都市言情 » 蓝星文娱:从微末崛起的娱乐大亨 » 第十九章:面试题/网络并发编程/中间件/内存模型《Java编程与面试》

第十九章:面试题/网络并发编程/中间件/内存模型《Java编程与面试》

    本期主题:

    《Java编程与面试2024》的面试题篇,网络及并发编程篇,中间件篇,内存模型篇。

    ……

    【《Java编程与面试2024》第1至8篇的核心8问。】

    1、2024年10道直指Java核心的面试题!

    2、常见的Java网络编程问题,有哪些?

    3、在Java中,中间件是什么?具体有哪些?

    4、在Java中,常见的消息中间件有哪些?它们各自的特点和使用场景是什么?

    5、在Java编程中,应用程序和系统软件有什么区别?

    6、常见的Java并发编程问题,有哪些?又有什么解决办法呢?

    7、解决Java并发编程的关键字有哪些?它们各自的使用方式及注意事项又是什么?

    8、怎样理解Java的内存模型呢?

    ……

    第1篇【2024年10道直指Java核心的面试题】

    在2024年,Java基础知识的面试题,可能仍然会围绕一些核心概念和特性展开。

    以下是一些常见的Java基础知识面试题:

    1、Java的基本数据类型有哪些?

    包括整型(byte,short,int,long)、浮点型(float,double)、字符型(char)和布尔型(boolean)。

    …

    2、解释一下Java中的访问修饰符?

    Java中有四种访问修饰符:public、protected、private和默认(无修饰符)。

    它们决定了类、方法和变量的访问权限。

    …

    3、Java中的构造器(Constructor)是什么?

    构造器是一种特殊的方法,用于初始化新创建的对象。

    它与类名相同,没有返回类型。

    …

    4、解释一下Java中的封装、继承和多态?

    1)封装隐藏对象的属性和实现细节,仅对外提供公共访问方式;

    2)继承允许一个类(子类)继承另一个类(父类)的属性和方法;

    3)多态是同一个接口可以有多种实现方式或同一个方法在不同对象上可以有不同表现。

    …

    5、Java中的异常处理机制是怎样的?

    Java通过try-catch-finally块来处理异常,try块包含可能抛出异常的代码,catch块用于捕获并处理异常,finally块无论是否发生异常都会执行。

    …

    6、Java中的集合框架包含哪些主要接口和类?

    主要接口包括List、Set、Map等。

    常见类有ArrayList、LinkedList、HashSet、HashMap等。

    …

    7、Java中的泛型是什么?它有什么作用?

    泛型是一种参数化类型,它允许在定义类、接口和方法时使用类型参数。

    它的主要作用是提供编译时的类型检查,减少类型转换错误,并提高代码的重用性。

    …

    8、==和equals的区别是什么?

    ==用于比较两个基本数据类型的值是否相等,或者比较两个对象的引用,是否指向同一内存地址。

    而equals是Object类的一个方法,用于比较两个对象的内容是否相等。

    对于自定义对象,通常需要重写equals方法以实现特定的比较逻辑。

    …

    9、Java中的线程生命周期是怎样的?

    Java中的线程有五种状态:

    1)新建(NEW);

    2)就绪(RUNNABLE);

    3)阻塞(BLOCKED);

    4)等待(WAITING)和超时等待(TIMED_WAITING);

    5)终止(TERMINATED)。

    …

    10、Java中的同步和异步有什么区别?

    同步操作按照顺序执行,前一个操作完成后,后一个操作才会开始。

    而异步操作,则是多个操作可以同时进行,不需要等待前一个操作完成。

    ……

    第2篇【常见的Java网络编程问题,有哪些?】

    我们常见的Java网络编程问题,一共有7种:

    1、Socket连接问题;

    2、内存管理问题;

    3、线程管理问题;

    4、I/O操作问题;

    5、安全性问题;

    6、协议和格式问题;

    7、可扩展性和可维护性问题。

    在Java中进行网络编程时,我们可能会遇到一系列问题。

    这些问题可能涉及网络连接、数据传输、性能优化、安全性等多个方面。

    我归纳了一下,我们常见的Java网络编程问题一共有7种…

    即Socket连接问题、内存管理问题、线程管理问题、I/O操作问题、安全性问题、协议和格式问题,以及可扩展性和可维护性问题。

    以下,就是7种常见的Java网络编程问题的具体内容:

    1)Socket连接问题

    连接超时:

    当网络不稳定或目标主机不可达时,Socket连接可能会超时。

    解决方法是,设置合适的连接超时时间,并使用try-catch语句,来捕获连接异常。

    连接中断:

    在网络不稳定的情况下,Socket连接可能会中断。

    可以使用心跳机制,或添加重连机制,以确保连接的稳定性。

    2)内存管理问题

    内存泄漏:

    如果应用程序中存在内存泄漏,会导致性能下降。

    应避免对象的过度创建和销毁,使用对象池或缓存重用对象。

    并注意解除对象之间的引用,以避免循环引用导致的内存泄漏。

    频繁的垃圾回收:

    频繁创建和销毁对象,会增加垃圾回收的负担。

    优化数据结构和集合类的使用,可以减少内存占用和提高性能。

    3)线程管理问题

    并发性能:

    Java的线程机制,使得并发编程变得容易,但也可能导致性能问题。

    应避免在锁内部执行耗时操作,以减少锁的占用时间。

    同时,应合理划分任务,以提高并发性能。

    4)I/O操作问题

    阻塞I/O:

    传统的阻塞I/O,可能导致线程在等待数据时被挂起,从而降低性能。

    可以使用非阻塞I/O,或异步I/O来提高性能。

    数据传输错误:

    在网络传输过程中,数据可能会出现丢失、乱序或损坏等问题。

    应使用合适的协议和校验机制,来确保数据的完整性和正确性。

    5)安全性问题

    数据加密:

    Java应用程序中的重要数据,需要加密来保护其机密性和完整性。

    应使用加密技术,来确保数据在传输和存储过程中的安全性。

    防火墙和网络安全:

    防火墙可以保护应用程序,免受未经授权的访问和攻击。

    应配置适当的防火墙规则,并使用网络安全技术(如入侵检测系统、安全套接字层等)来增强应用程序的安全性。

    6)协议和格式问题

    协议选择:

    根据应用场景和需求,选择合适的通信协议(如HTTP、FTP、WebSocket等)。

    数据格式:

    确保发送和接收的数据格式正确,避免格式不匹配,或解析错误等问题。

    7)可扩展性和可维护性问题

    代码结构:

    随着网络编程的复杂性增加,代码结构可能变得难以维护。

    应遵循良好的编程实践和设计原则(如SOLID原则)…

    以保持代码的可读性和可维护性。

    模块化:

    将网络编程相关的代码,进行模块化处理,便于代码的复用和扩展。

    总结:

    我们要解决以上这7种常见问题,那么就需要深入地去理解,Java网络编程的相关知识和技术。

    同时,也要结合具体的应用场景和需求,去进行综合考虑和优化。

    ……

    第3篇【在Java中,中间件是什么?具体有哪些?】

    在Java中,中间件是一种独立的系统软件或服务程序。

    它介于应用程序和系统软件之间,起着连接、协调、通信和管理的功能。

    中间件的出现,主要是为了简化分布式应用的开发、部署和管理。

    Java中有6种常见的中间件类型,即消息中间件、RPC中间件、数据库中间件、缓存中间件、应用服务器中间件、API网关中间件。

    Java中,常见的中间件类型有以下6种:

    1)消息中间件

    这类中间件,用于在不同应用或系统之间传递消息。

    常见的Java消息中间件有ActiveMQ、RabbitMQ、Kafka等等。

    它们可以实现异步通信,提高系统的可伸缩性和可靠性。

    2)RPC中间件

    RPC(远程过程调用)中间件,允许程序调用,在远程机器上运行的函数或方法…

    就像调用本地函数一样。

    在Java中,Dubbo和gRPC是流行的RPC中间件。

    3)数据库中间件

    这类中间件,用于管理数据库连接、优化数据库查询、实现读写分离、负载均衡等功能。

    常见的Java数据库中间件有ShardingSphere、MyBatisPlus等等。

    4)缓存中间件

    缓存中间件,可以提高系统的响应速度和吞吐量,减轻数据库的压力。

    在Java中,Redis和Memcached是常用的缓存中间件。

    5)应用服务器中间件

    应用服务器中间件,提供了一系列的服务,如事务管理、安全性、负载均衡等,以支持应用程序的运行。

    Tomcat和Jetty是Java中常见的应用服务器中间件。

    6)API网关中间件

    API网关,是微服务架构中的关键组件…

    它用于管理API的路由、安全、监控等功能。在Java中,SpringCloudGateway和Zuul是常用的API网关中间件。

    总结:

    这些中间件各有特色,我们可以根据具体的应用场景和需求,选择适合的中间件。

    同时,随着技术的发展,新的中间件类型和解决方案,也在不断地涌现出来。

    ……

    第4篇【在Java中,常见的消息中间件有哪些?它们各自的特点和使用场景是什么?】

    在Java中,常见的消息中间件主要有5种,即ActiveMQ、RabbitMQ、ApacheKafka、IBMMQ、AmazonSQS。

    这5种消息中间件的特点,及使用场景如下:

    1)ActiveMQ

    特点:

    ActiveMQ是Apache基金会开发的开源消息中间件。

    它支持JMS(JavaMessageService)规范,具备多种集群模式和高可用机制。

    它提供了丰富的API和工具,支持多种消息协议和传输方式。

    使用场景:

    ActiveMQ适用于构建分布式系统,进行消息传递和异步通信。

    它常用于大型电商平台、金融系统,以及电信领域的订单处理、支付通知、消息服务等场景。

    2)RabbitMQ

    特点:

    RabbitMQ使用AMQP(高级消息队列协议)作为核心通信协议…

    它支持多种编程语言和协议,如MQTT、STOMP等。

    它提供了可靠的消息传递机制,灵活的路由功能,以及丰富的消息队列管理选项。

    使用场景:

    RabbitMQ适用于需要高效、可靠消息传递的场景…

    如实时数据处理、事件驱动架构、微服务之间的通信等等。

    它常用于物联网、在线支付和实时通信等领域。

    3)ApacheKafka

    特点:

    Kafka是一个分布式事件流平台,设计用于处理实时数据流。

    它提供了高吞吐量、持久性和容错性,支持消息的发布和订阅,并提供了强大的数据流处理功能。

    使用场景:

    Kafka适用于构建大数据处理、实时分析、日志收集等系统。

    它常用于金融风控、用户行为分析、物联网数据处理等场景…

    因为它,可以处理大规模的数据流和实时事件。

    4)IBMMQ

    IBMMQ,也被称为IBM消息队列。

    它是一个久经考验的消息传递解决方案,特别适用于混合云和多云环境。

    它具备高性能和高度安全性,并能提供近乎实时的洞察。

    特点:

    (1)高度安全性

    通过TLS安全通信、身份访问管理、消息级安全性等功能来确保数据安全。

    (2)多类型消息传递

    支持消息队列、事件或PubSub以及进行交易,能连接不同的系统。

    (3)强大的技术支持

    拥有专用的IBMMQ团队,以及大型用户社区,为其提供技术支持。

    使用场景:

    IBMMQ的使用场景是多样的…

    无论是专用数据中心、跨混合云或多云环境;

    还是在企业边缘,连接应用程序和微服务,IBMMQ都能发挥价值。

    它特别适合,需要保护企业,免受不正确数据和应用程序错误影响的场景…

    因为,它可以通过一次性消息传递,来确保数据的准确性。

    5)AmazonSQS

    AmazonSQS(AmazonSimpleQueueService),即Amazon简单队列服务。

    它是一个完全托管的消息队列服务。

    它简化了分布式应用程序的构建,特别是在AWS云环境中,帮助开发者实现消息的可靠传递和异步处理。

    特点:

    (1)可靠性

    SQS始终可用且非常可靠,可以跨代码的各个区域发送消息。

    (2)可扩展性

    用户可以专注于构建应用程序或系统,而无需担心基础设施。

    SQS会根据需求自动扩展或缩小。

    (3)异步处理

    在流量过大或意外波动时,可以排队消息并断开组件,使系统更加健壮。

    使用场景:

    AmazonSQS的使用场景,主要集中于,需要在多个服务或应用程序之间,发送、接收和保留文本消息的场景。

    它特别适用于,需要将应用或系统的各个部分链接在一起的场景…

    这些部分,可能位于不同的计算机中心,或是全球各地。

    通过使用SQS,用户可以轻松地,在分布式系统的各个组件之间移动数据…

    而不会丢失消息,也不需要各个组件,始终处于可用状态。

    总结:

    以上这5种消息中间件,各自具有独特的特点和优势,适用于不同的使用场景。

    我们在选择消息中间件时,需要根据具体需求、系统环境、性能要求等因素进行综合评估。

    同时,随着技术的发展和业务的变化,可能还会出现新的消息中间件解决方案…

    因此,需要及时关注行业动态,以及技术发展趋势。

    ……

    第5篇【在Java编程中,应用程序和系统软件有什么区别?】

    在Java编程中,应用程序和系统软件,在功能、目标和使用场景等方面,有着显著的区别。

    首先,从“功能”角度来看…

    应用程序是为了满足特定业务需求或用户需求而编写的软件。

    它们直接面向用户或业务逻辑,提供特定的功能和服务。

    例如,一个电商网站、一个在线支付系统或一个企业级管理系统,都可以被视为应用程序。

    而系统软件,则是为计算机或操作系统提供基础服务的软件。

    它管理计算机硬件和应用程序,确保它们能够正常、高效地运行。

    在Java编程中,系统软件可能包括Java虚拟机(JVM)、操作系统内核、数据库管理系统等。

    其次,从“目标”角度来看…

    应用程序的目标是,满足特定的业务需求或用户需求,提供给用户友好的界面,及便捷的操作方式。

    而系统软件的目标,则是提供稳定、可靠的系统运行环境,优化资源分配,确保计算机硬件和应用程序,能够正常工作。

    最后,从“使用场景”角度来看…

    应用程序,通常是由软件开发人员,根据具体业务需求进行定制开发的。

    而系统软件,则是计算机系统中的基础设施,通常是预先安装和配置的,无需用户或应用程序开发者,去进行过多的干预。

    总结:

    应用程序和系统软件,在Java编程中,各自扮演着不同的角色…

    它们之间相互协作,共同构成了完整的软件系统。

    具体来说…

    应用程序,负责实现具体的业务逻辑和用户界面;

    而系统软件,则提供基础服务和运行环境支持。

    ……

    第6篇【常见的Java并发编程问题,有哪些?又有什么解决办法呢?】

    Java的并发编程确实存在着多种问题,常见的有6个…

    即死锁、活锁、资源竞争、饥饿、数据竞争,以及线程安全问题。

    这6个问题如果处理不当的话,则可能会导致程序性能下降,响应延迟,甚至系统崩溃……

    关于这以上6问题的解决办法,具体策略如下:

    1、死锁

    死锁通常发生在,两个或更多的线程,无限期地等待一个资源…

    而该资源,又被另一个线程持有,后者也在等待被其他线程持有的资源。

    解决死锁的3个策略:

    1)确保资源按照一致的顺序被请求;

    2)使用锁超时,检测死锁并恢复;

    3)避免嵌套锁。

    2、活锁

    活锁发生在,所有线程都在积极地,尝试解决问题…

    但由于某些条件,没有一个线程能够成功。

    解决活锁的一种方法是:引入一个仲裁者。

    例如,一个专门的线程或进程,来协调其他线程的活动。

    3、资源竞争

    当多个线程试图,同时访问同一资源时,就可能发生资源竞争。

    这个问题,通常可以通过使用“同步机制”(如synchronized关键字或Lock接口)来解决…

    以确保,一次只有一个线程,可以访问资源。

    4、饥饿

    饥饿是当某个线程,由于某些原因,而无法获得所需的资源…

    而导致它无法继续执行的问题。

    避免饥饿的2个方法:

    1)确保所有线程,都有公平访问资源的机会;

    2)为关键任务,设置更高的优先级。

    5、数据竞争

    当两个或更多的线程,在没有适当同步的情况下…

    就访问和修改共享数据时,而可能发生的数据竞争问题。

    解决数据竞争的2个办法:

    1)通过使用volatile关键字;

    2)通过原子变量和锁来避免。

    6、线程安全

    线程安全,是指多线程环境下,代码能够正确无误地运行。

    实现线程安全的2个法办:

    1)使用同步机制,来确保对共享数据的访问,是原子性的;

    2)避免共享可变状态。

    总结:

    每个并发问题,都有其独特的解决策略。

    因此在实际编程中,需要根据具体情况选择最合适的方法。

    同时,理解Java的内存模型,以及synchronized、volatile、Lock等关键字的使用方式,也是解决并发问题的关键。

    ……

    第7篇【解决Java并发编程的关键字有哪些?它们各自的使用方式及注意事项又是什么?】

    在Java并发编程中,有一些关键字和技术点,是非常重要的。

    其中常见的有4个,即synchronized,volatile,wait和notify/notifyAll,ReentrantLock。

    以下,就是上面4种关键字及其使用方式和注意事项的具体内容:

    1、synchronized

    synchronized是Java中,用于解决多线程同步问题的关键字,它可以用于方法或代码块。

    当一个线程,进入一个对象的synchronized方法或代码块时,它获取该对象的监视器锁…

    其它线程,则无法进入该对象的synchronized方法或代码块,直到第一个线程退出。

    使用方式:

    publicsynchronizedvoidsynchronizedMethod{

    //...

    }

    publicvoidanotherMethod{

    synchronized(this){

    //...

    }

    }

    使用synchronized的3个注意事项:

    1)避免在持有锁时,执行耗时操作,以免其他线程长时间等待;

    2)锁尽量细粒度,避免过度同步;

    3)注意死锁的可能性,确保锁的获取和释放顺序一致。

    2、volatile

    volatile是Java中的一个关键字,用于修饰变量。

    被volatile修饰的变量,可以保证在多线程环境下,该变量的可见性和有序性。

    使用方式:

    publicvolatileintvolatileVar=0;

    使用volatile的2个注意事项:

    1)volatile不保证原子性,对于复合操作(如i++),仍然需要额外的同步措施。

    2)volatile不能替代synchronized,它只能解决可见性和有序性问题,不能解决互斥问题。

    3、wait和notify/notifyAll

    这三个方法是Java对象中的方法,通常与synchronized关键字一起使用,用于实现线程间的通信。

    使用方式:

    synchronized(lock){

    while(conditionNotMet){

    lock.wait;

    }

    //执行操作...

    lock.notifyAll;

    }

    使用wait和notify/notifyAll三个方法的3个注意事项:

    1)必须在synchronized块或方法中,使用这三个方法,否则会抛出IllegalMonitorStateException。

    2)wait会释放当前线程持有的锁,notify或notifyAll会唤醒在等待该对象的线程。

    3)注意避免虚假唤醒(spuriouswakeup),通常使用循环检查条件是否满足。

    4、ReentrantLock

    ReentrantLock是Java中,用于实现互斥锁的一个类…

    相比synchronized,它提供了更多的功能,如可中断的获取锁、尝试获取锁等。

    使用方式:

    ReentrantLocklock=newReentrantLock;

    lock.lock;

    try{

    //...

    }finally{

    lock.unlock;

    }

    使用ReentrantLock的2个注意事项:

    1)使用ReentrantLock时,必须在finally块中释放锁…

    以确保即使发生异常,也能正确释放锁。

    2)避免死锁,确保锁的获取和释放顺序一致。

    总结:

    以上就是Java并发编程中,一些关键字的使用方式和注意事项啦。

    当然,除了这些关键字,Java还提供了许多其他的并发工具和类…

    如Semaphore、CountDownLatch、CyclicBarrier等等。

    我们可以根据具体需求,去选择最合适的关键词和技术去实现开发需求。

    ……

    第8篇【怎样理解Java的内存模型呢?】

    Java的内存模型,就是Java虚拟机(JVM)在内存中存储和管理数据的方式。

    这涉及到了Java程序在运行时,是如何进行分配、使用和回收内存的。

    理解了Java的内存模型,对于编写高效、安全的并发程序至关重要。

    下面,就让我们从三个方面,定义及内核、三特性、,来具体了解下Java内存模型吧!

    一、定义及内核

    Java内存模型,定义了变量(包括实例字段、静态字段和数组元素)之间的关系…

    以及这些变量,在内存中的存储和访问方式。

    在Java中,所有变量都存储在内存中,但编译器、运行库、处理器或系统缓存…

    可能具有,在变量指定的内存位置存储,或取出变量值的特权。

    这种特权,允许编译器和缓存优化性能,但也可能导致内存可见性问题。

    Java内存模型,是通过一系列规则和保证,来解决这些问题的,以确保在多线程环境下对内存访问的安全性。

    二、三特性

    Java内存模型,主要包括三个特性:原子性、可见性和有序性。

    1、原子性

    指一个操作或者多个操作,要么全部执行,并且在执行的过程中,不会被任何因素打断…

    要么就全部不执行。

    Java内存模型,通过一些同步原语(如synchronized和volatile关键字)来保证原子性。

    例如,volatile关键字不保证原子性,但对于单个volatile变量的读/写操作是原子的。

    2、可见性

    指当一个线程修改了共享变量的值,其它线程能够立即看到修改后的值。

    Java内存模型,通过volatile关键字和内存屏障等方式来保证可见性。

    volatile变量,可以确保每次读取都直接从主存中获取,而不是从线程的本地缓存中读取。

    3、有序性

    指程序执行的顺序,按照代码的先后顺序执行。

    Java内存模型,允许编译器和处理器对指令进行重排序以提高性能…

    但这种重排序,必须遵守一定的规则,以确保程序的正确执行。

    三、6种五大内存区域

    Java内存模型,还定义了6种内存区域,即程序计数器、Java虚拟机栈、本地方法栈、堆、方法区和直接内存。

    在以上6种内存区域里,除了直接内存以外,就是Java内存模型的5个主要组成部分啦。

    这些区域,有各自的用途和特点,用于存储和管理Java程序,在运行时的各种数据。

    Java内存模型的五大内存区域:

    1、程序计数器(ProgramCounterRegister)

    这是一块较小的内存空间,可以看作是当前线程,所执行的字节码的行号指示器。

    每个线程,都有一个独立的程序计数器,线程私有的内存区域。

    虚拟机中的字节码解释器,通过改变计数器的值,来获取下一条代码指令…

    如分支、循环、跳转、异常处理、线程恢复等操作都依赖此计数器。

    2、Java虚拟机栈(JavaVirtualMachineStacks)

    也是线程私有的,与线程的生命周期相同。

    每个方法在执行的同时,都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链表、方法出口等信息。

    虚拟机栈,描述的是Java方法执行的内存模型。

    3、本地方法栈(NativeMethodStacks)

    与虚拟机栈,所发挥的作用非常相似…

    但主要区别在于:

    虚拟机栈,执行的是Java(字节码)服务;

    而本地方法栈,则执行的是虚拟机使用到的本地(Native)方法。

    4、Java堆(JavaHeap)

    这是Java虚拟机,所管理的内存中最大的一块,是被所有线程共享的一块内存区域。

    此内存区域的唯一目的,就是存放对象实例,几乎所有的对象实例,都在这里分配内存。

    堆也是垃圾收集器管理的主要区域。

    5、方法区(MethodArea)

    也称为永久代(在Java8之前),是各个线程共享的内存区域。

    它主要用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    根据Java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

    需要注意的是:

    Java8及以后的版本中,方法区被元空间(Metaspace)所替代。

    元空间,使用的是本地内存,因此理论上只要不超出本地内存,元空间的大小是没有限制的。

    这样的改变、主要是为了解决永久代内存溢出的问题。

    总结:

    在以上这五个区域中,程序计数器、Java虚拟机栈和本地方法栈是线程私有的…

    而Java堆和方法区是线程共享的。

    这种设计,有助于线程间的数据隔离和共享,从而提高了Java程序的并发性能。

    此外…

    虽然上述五个区域是Java内存模型的主要组成部分,但还有一块直接内存(DirectMemory)区域也需要注意。

    直接内存,并不是Java虚拟机运行时数据区的一部分…

    但也被频繁地使用,而且也可能导致OutOfMemoryError异常出现。

    透彻地理解Java内存模型,就需要掌握其基本概念、特性和规则,以及如何在编写并发程序时应用这些知识和技术。

    通过深入学习和实践,我们可以编写出高效、安全的并发程序,充分利用Java提供的强大并发功能。

    总而言之,理解Java内存模型的这些内存区域对于编写高效、安全的Java程序至关重要。

    ……

    以上,就是今天的分享啦!

    希望,对你的求职面试,编程工作有那么一点点、一丢丢、一戳戳地帮助哈~

    喜欢我分享的,就一键三连于我,可好?!