我是靠谱客的博主 老迟到哈密瓜,最近开发中收集的这篇文章主要介绍《Java开发 - 第1部分 基础篇》第1章 JAVA 概述,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.1 Java简介

 Java语言的定义

Java是一种简单的,跨平台的,面向对象的,分布式的,解释的,健壮的,安全的,结构的,中立的,可移植的,性能很优异的,多线程的,动态的语言。

 Java 语言的特点

语法简单,面向对向,稳定,与平台无关,多线程。

 Java与平台无关(最大的优势)

软件的运行不因操作系统、处理器的变化导致无法运行或运行异常的情况。

注意:为什么是与平台无关?

java 可以在平台之上提供一个java运行环境(java Runntime Environment ,JRE) JRE 由 java 虚拟机 、类库及核心文件组成; java虚拟机的核心是所谓的字节码指令,即可以被java虚拟机直接识别并执行 的一种由1,0 组成的序列代码;java针对不同的平台提供的java虚拟机的字节码指令都是相同的。

1.2 Java发展史

1.2.1编程语言类型

第一代语言:
 打孔机 - 纯机器语言

第二代语言:
 汇编语言

第三代语言:
 C、Pascal、Fortran面向过程的语言
 C++面向过程面向对象
 Java跨平台的纯面向对象的语言
 .NET跨语言的平台

Java语言是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java语言本身的面向对象、分布式、体系结构中立、可移植、高性能、多线程、多态性以及跨平台的特点,使其成为当前最流行的网络编程语言之一。Java是一种面向Internet的编程语言。

1.2.2 Java语言的发展史

Oak:Java的前身,1991年出现,1994年将Oak语言更名为Java。James Gosling:詹姆斯·高斯林,Java的主设计者,由他和他的同事们共同研发。Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言。

1995年5月23日,Java语言诞生;
1996年1月,第一个JDK-JDK1.0诞生;
1996年4月,10个最主要的操作系统供应商申明将在其产品中嵌入JAVA技术;
1996年9月,约8.3万个网页应用了JAVA技术来制作;
1997年2月18日,JDK1.1发布;
1997年4月2日,JavaOne会议召开,参与者逾一万人,创当时全球同类会议规模之纪录;
1997年9月,JavaDeveloperConnection社区成员超过十万;
1998年2月,JDK1.1被下载超过2,000,000次;
1998年12月8日,JAVA2企业平台J2EE发布;
1999年6月,SUN公司发布Java的三个版本:标准版、企业版和微型版;
2000年5月8日,JDK1.3发布;
2000年5月29日,JDK1.4发布;
2001年6月5日,NOKIA宣布,到2003年将出售1亿部支持Java的手机;
2001年9月24日,J2EE1.3发布;
2002年2月26日,J2SE1.4发布,自此Java的计算能力有了大幅提升;
2004年9月30日18:00PM,J2SE1.5发布,成为Java语言发展史上的又一里程碑。为了表示该版本的重要性,J2SE1.5更名为Java SE 5.0;
2005年6月,JavaOne大会召开,SUN公司公开Java SE 6。此时,Java的各种版本已经更名,以取消其中的数字“2”:J2EE更名为Java EE,J2SE更名为Java SE,J2ME更名为Java ME;
2006年12月,SUN公司发布JRE6.0;
2009年4月7日Google App Engine开始支持Java;
2009年04月20日,甲骨文74亿美元收购Sun。取得Java的版权;
2010年11月,由于甲骨文对于Java社区的不友善,因此Apache扬言将退出JCP;
2011年7月28日,甲骨文发布Java 7.0的正式版;
2014年3月19日,甲骨文公司发布Java 8.0的正式版。

1.3 Java语言的产生

 网络与计算环境的催生

在经历了以大型机为代表的集中计算模式和以PC机为代表的分散计算模式之后,互联网的出现使得计算模式进入了网络计算时代。网络计算模式的一个特点是计算机是异构的,即计算机的类型和操作系统是不一样的,例如SUN工作站的硬件是SPARC体系,软件是UNIX中的Solaris操作系统,而PC机的硬件是INTEL体系,操作系统是windows或者是Linux;网络计算模式的另一个特点是代码的网络迁移特性,这迫切需要一种跨平台的编程语言,使得程序能够在网络中的各种计算机上能够正常运行。

 面向对象、健壮性、易用性
在面向对象的思想引入到编程语言之后,C语言就被改造成为面向对象的C++语言,得到了广泛的应用。但是C++语言必须兼容C语言,因此C++语言是面向过程和面向对象混合的语言。其复杂的内存管理,指针操作使得C++语言的易用性下降,同时程序的健壮性受到人为因素的影响很大。Java号称完全的面向对象的编程语言,充分吸取了C++语言的优点,采用了程序员所熟悉的C和C++语言的许多语法,同时又去掉了C语言中指针、内存申请和释放等影响程序健壮性的部分以及复杂的多重继承特性。

Java语言设计者的思想就是设计一个面向对象的、跨平台的、易用性强、分布式的高效语言。因此,其被设计为半编译半解释型语言。程序编译解释执行均由Java虚拟机(Java Virtual MachineJava, JVM)管理,由于程序执行编译执行不再依靠本地编译器,使得Java语言编写的程序能够做到跨平台。Java语言号称一切均为对象,但是创建对象就意味着耗时耗内存,因此为了兼顾效率,其仍旧支持基本的数据类型;关于易用性和健壮性其抛弃了C++支持的指针,而是采用一种受限的指针,称之为引用,来进行管理,使得语言的易用性更强;另外,Java抛弃了C++多重继承,而是采用单继承和接口的方式替代复杂的多重继承。

1.4 Java的三个体系

我们对Java三大体系JavaEE、JavaSE、JavaME的区别做一个简单的介绍。

Java SE(Java 2 Platform Standard Edition)标准版【J2SE】
JavaSE以前称为J2SE.它允许开发和部署在桌面、服务器、嵌入式环境和实施环境中使用的Java应用程序。JavaSE 包括支持Java Web服务开发的类,并为Java Platform,Enterprise Edition(Java EE)提供基础。支持面向桌面级应用(如Windows下的应用程序)的Java平台,提供了完整的Java核心API,此版本以前称为J2SE,是其它两者的基础。

Java ME(Java 2 Platform Micro Edition)小型版、微型版【J2ME】
Java ME为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME包括灵活的用户界面、健壮的安全模式、许多内置的网络协议以及对于动态下载的连网和离线应用程序的丰富支持。基于Java ME规范的应用程序只需要编写一次,就可以用于许多设备,而且可以利用每个设备的本级功能。此版本以前称为J2ME。

Java EE(Java 2 Platform Enterprise Edition)企业版【J2EE】

这个版本以前被称为J2EE.企业版本帮助开发和部署可移植、健壮、可伸缩切安全的服务端Java应用。Java EE是在JavaSE的基础上构建的他提供Web 服务、组建模型、管理和通信API.可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和web2.0应用程序。该技术体系中包含的技术如:Servlet 、Jsp等,主要针对于Web应用程序开发。版本以前称为J2EE。
2005年6月,JavaOne大会召开,SUN公司公开Java SE 6。此时,Java的各种版本已经更名以取消其中的数字"2"。从此J2EE更名为Java EE,J2SE更名为Java SE,J2ME更名为Java ME。
无论是Java SE,Java EE还是Java ME,ORACLE都提供了对应的开发包。其中Java SE的开发包叫做JDK。Java EE以及Java ME的开发包是对JDK的封装,精简或者扩展,被叫做SDK。

三种技术的关系:

在这里插入图片描述

图1

在这里插入图片描述

图2

1.5 Java的工作原理

 Java虚拟机(JVM)
Java虚拟机是软件模拟的计算机,可以在任何处理器上(无论是在计算机中还是在其它电子设备中)安全并且兼容的执行保存在.class文件中的字节码。java虚拟机的”机器码”保存在.class文件中,有时也可以称之为字节码文件。java程序的跨平台主要是指字节码文件可以在任何具有Java虚拟机的计算机或者电子设备上运行,Java虚拟机中的Java解释器(java命令)负责将字节码文件解释成为特定的机器码进行运行.但是, Java虚拟机的建立需要针对不同的软硬件平台做专门的实现,既要考虑处理器的型号,也要考虑操作系统的种类。对于不同的平台,就有不同的虚拟机。目前的主流操作系统UNIX、Linux、windows和部分实时操作系统上都有Java虚拟机的实现。

在这里插入图片描述

图3

JVM是一个”桥梁“,是一个”中间件“,是实现跨平台的关键,Java代码首先被编译成字节码文件,再由JVM将字节码文件翻译成机器语言,从而达到运行Java程序的目的。

注意:编译的结果不是生成机器码,而是生成字节码,字节码不能直接运行,必须通过JVM翻译成机器码才能运行。不同平台下编译生成的字节码是一样的,但是由JVM翻译成的机器码却不一样。

所以,运行Java程序必须有JVM的支持,因为编译的结果不是机器码,必须要经过JVM的再次翻译才能执行。即使你将Java程序打包成可执行文件(例如 .exe),仍然需要JVM的支持。

注意:跨平台的是Java程序,不是JVM。JVM是用C/C++开发的,是编译后的机器码,不能跨平台,不同平台下需要安装不同版本的JVM。

在这里插入图片描述

图4

Java虚拟机内存被划分为:
栈区(stack):
每个线程执行每个方法的时候都会在栈中申请一个栈帧,每个栈帧包括局部变量区和操作数栈,主要存放Java程序运行时所需的局部变量、方法的参数、对象的引用以及中间运算结果等数据。

堆区(heap):
所有通过new创建的对象的内存都在堆中分配。

代码区(code segment 区):
主要存放Java的代码

方法区(data segment 区):
存放了要加载的类信息(属性)、静态变量、final类型的常量(字符串常量)等。

 内存自动回收管理系统(Garbage collection)
在Java运行环境中,始终存在着一个系统级的线程,专门跟踪内存的使用情况,定期检测出不再使用的内存,并进行自动回收,避免了内存的泄露,也减轻了程序员的工作量。(详细请参考Orcale JVM规范)

 代码安全性检查机制
字节码的执行需要经过三个步骤,首先由类装载器(class loader)负责把类文件(.class文件)加载到JVM中,在此过程需检验该类文件是否符合类文件规范;其次字节码校验器(bytecode verifier)检查该类文件的代码中是否存在着某些非法操作,例如applet程序中写本机文件系统的操作;如果字节码校验器检验通过,由java解释器负责把该类文件解释成为机器码进行执行。JVM采用的是”沙箱”运行模式,即把Java程序的代码和数据都限制在一定内存空间里执行,不允许程序访问该内存空间外的内存,如果是applet程序,还不允许访问客户端机器的文件系统。

好了,现在来总结下。JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。Java Runtime Environment(JRE)是运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。JVM是Java Virtual Machine(Java虚拟机)的缩写,是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。

在这里插入图片描述

图5

所以,当你需要开发一个java程序时,你需要的是jdk,但如果需要运行一个java程序,就需要jre了。让人迷惑的是,当你下载并安装jdk之后,会发现在jdk文件夹内部和外部同时存在jre文件夹(证明了jdk包含jre),下面我们来说说其中的原因:

内部jre:当你开发java程序时,需要用到一些javac之类的命令,就会调用jdk(java开发 工具)内部的jre;

外部jre:当你只需要运行一个java程序而不是开发时,就会调用外部的jre;
那么为什么要分两个呢?公用一个不就行了吗,还节省了资源。其实分为两个jre,更多的是为了提高性能和效率,打开两个jre的文件夹,对比一下会发现:

外部jre中,在其client文件夹里面,有个jvm.dll;内部jre中,多了个server文件夹,其中也有个jvm.dll文件,主要是两个vm的区别,使得内外部jre有不同的分工,并且能在各自的分工上做到最好(提高各自的效率和性能)。

在这里插入图片描述

图6

【链接】https://docs.oracle.com/javase/8/docs/

1.6 JRE和JDK的关系

 JRE(Java Runtime Environment)

Java运行时环境。为Java应用程序的运行提供支持,主要包括以下内容:
1)JVM(Java virtual Machine)java虚拟机
2)Java类核心库

 JDK(Java Development Kit)

Java开发包。帮助完成Java应用程序的开发,主要包括以 下内容:
1)java工具集(帮助开发java程序)
2)JRE

在这里插入图片描述

图 7

在这里插入图片描述

图 8

1.7 Java在各领域中的应用

从Java的应用领域来分,Java语言的应用方向主要表现在以下几个方面:
企业级应用:主要指复杂的大企业的软件系统、各种类型的网站。Java的安全机制以及它的跨平台的优势,使它在分布式系统领域开发中有广泛应用。应用领域包括金融、电信、交通、电子商务等。

Android平台应用:Android应用程序使用Java语言编写。Android开发水平的高低很大程度上取决于Java语言核心能力是否扎实。

移动领域应用:主要表现在消费和嵌入式领域,是指在各种小型设备上的应用,包括手机、PDA、机顶盒、汽车通信设备等。

1.8 Java语言的特性

1、简单性(简洁有效、易学)
Java丢弃了C++中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java语言不使用指针,而是引用。并提供了自动的废料收集,使得程序员不必为内存管理而担忧。

2、面向对象(强制面向对象)
Java语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制。
Java语言全面支持动态绑定,而C++语言只对虚函数使用动态绑定。

3、分布式处理(适合分布式计算)
Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库。
Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。

4、健壮性(鲁棒性,防患于未然)
Java吸收了C/C++语言的优点,但去掉了其影响程序健壮性的部分(如指针、内存的申请与释放等),提供了一个相对安全的内存管理和访问机制。
Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。

5、结构中立(是一种中性结构)
Java程序(后缀为java的文件)在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件),然后可以在实现这个Java平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。

6、跨平台(可移植性)
通过Java语言编写的应用程序在不同的系统平台上都可以运行。“Write once , Run Anywhere”
原理:只要在需要运行 java 应用程序的操作系统上,先安装一个Java虚拟机 (JVM Java Virtual Machine) 即可。由JVM来负责Java程序在该系统中的运行。
Java系统本身也具有很强的可移植性,Java编译器是用Java实现的,Java的运行环境是用ANSI C实现的。

7、解释型(解释性)
Java程序在Java平台上被编译为字节码格式,然后可以在实现这个Java平台的任何系统中运行。在运行时,Java平台中的Java解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。

8、高性能(具有较好的性能)
与那些解释型的高级脚本语言相比,Java的确是高性能的。

9、多线程(具有多线程处理能力)
Java语言支持多个线程的同时执行,并提供多线程之间的同步机制。

10、安全性(具有较高的安全性)
Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击。

11、动态(是一种动态语言)
Java程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java中的类有一个运行时刻的表示,能进行运行时刻的类型检查。

1.9 Java与C/C++的比较

 全局变量
Java程序不能定义程序的全局变量,而类中的公共、静态变量就相当于这个类的全局变量。这样就使全局变量封装在类中,保证了安全性,而在C/C++语言中,由于不加封装的全局变量往往会由于使用不当而造成系统的崩溃。

 条件转移指令
C/C++语言中用goto语句实现无条件跳转,而Java语言没有goto语句,通过例外处理语句try、catch、finally来取代之,提高了程序的可读性,也增强了程序的鲁棒性。

 指针
指针是C/C++语言中最灵活,但也是最容易出错的数据类型。用指针进行内存操作往往造成不可预知的错误,而且,通过指针对内存地址进行显示类型转换后,可以类的私有成员,破坏了安全性。在Java中,程序员不能进行任何指针操作,同时java中的数组是通过类来实现的,很好的解决了数组越界这一C/C++语言中不做检查的缺点。

 内存管理
在C语言中,程序员使用库函数malloc()和free()来分配和释放内存,C++语言中则是运算符new和delete。再次释放已经释放的内存块或者释放未被分配的内存块,会造成系统的崩溃,而忘记释放不再使用的内存块也会逐渐耗尽系统资源。在Java中,所有的数据结构都是对象,通过运算符new分配内存并得到对象的使用权。无用内存回收机制保证了系统资源的完整,避免了内存管理不周而引起的系统崩溃。

 数据类型的一致性
在C/C++语言中,不同的平台上,编译器对简单的数据类型如int、float等分别分配不同的字节数。例如:int在IBM PC上为16位,在VAX-11上就为32位,导致了代码数据的不可移植。在Java中,对数据类型的位数分配总是固定的,而不管是在任何的计算机平台上。因此就保证了Java数据的平台无关性和可移植性。

 类型转换
在C/C++语言中,可以通过指针进行任意的类型转换,不安全因素大大增加。而在java语言中系统要对对象的处理进行严格的相容性检查,防止不安全的转换。

 头文件
在C/C++语言中使用头文件声明类的原型和全局变量及库函数等,在大的系统中,维护这些头文件是非常困难的。Java不支持头文件,类成员的类型和访问权限都封装在一个类中,运行时系统对访问进行控制,防止非法的访问。同时,Java中用import语句与其它类进行通信,以便访问其它类的对象。

 结构和联合
C/C++语言中用结构和联合来表示一定的数据结构,但是由于其成员均为公有的,安全性上存在问题。Java不支持结构和联合,通过类把数据结构及对该数据的操作都封装在类里面。

 预处理
C/C++语言中有宏定义,而用宏定义实现的代码往往影响程序的可读性,而Java不支持宏定义。

1.10 Java编程规范

1.Java语言程序示例
Java程序分为Java application(Java应用程序)和 Java applet(Java小应用程序)两种。文件的代码中引用了系统所提供的额外的类,通过import语句引入。其中类库”java.lang”会在每个Java文件中默认导入。

public class HelloWorld{
    public static void  main(String[] args){
        System.out.println("hello world!");
    }
}

注意:java文件的名字必须与class的名字一致!<.font>

程序分析:

1.编写java源代码程序,文件扩展名为.java
2.通过javac对代码进行编译,生成字节码文件(即class文件,虚拟机能看懂的文件)
3.通过java对class文件进行运行。执行时不需要加.class后缀名。
4.java的应用程序入口是main()方法。
5.java语言严格区分大小写。
6.一个源文件只有一个public类,且这个类必须和文件名同名,其他类个数不限。

编译:
$ javac HelloWorld.java
执行:
$ java HelloWorld
在这里插入图片描述

在这里插入图片描述

其中的javap属于反编译,还可以自动添加一个构造函数,至于具体是干什么的,可以查看帮助或者百度。

Main方法是一个特殊的方法,是程序执行的入口,一个java程序从main方法开始执行。Java虚拟机在执行java程序之前会事先分配一个主线程,然后在主线程里执行main方法,所有也会把main方法叫作主线程。
在这里插入图片描述

图9

在这里插入图片描述

图10

2.Java源程序规范结构

package语句; //该部分至多只有一句,必须放在源程序的第一句
  import语句; /*该部分可以有若干import语句或者没有,必须放在所有的类定义之前*/
  public classDefinition; //公共类定义部分,至多只有一个公共类的定义
       //java语言规定该java源程序的文件名必须与该公共类名完全一致
  classDefinition; //类定义部分,可以有0个或者多个类定义
  interfaceDefinition; //接口定义部分,可以有0个或者多个接口定义
例如一个java源程序可以是如下结构,该源程序命名为HelloWorldApp.java:
   package javawork.helloworld; /*把编译生成的所有.class文件放到包javawork.helloworld中*/
   import java.awt.*;  //告诉编译器本程序中用到系统的AWT包
   import javawork.newcentury; /*告诉编译器本程序中用到用户自定义的包javawork.newcentury*/
   public class HelloWorldApp{......} /*公共类HelloWorldApp的定义,名字与文件名相同*/
   class TheFirstClass{......} //第一个普通类TheFirstClass的定义
   class TheSecondClass{......} //第二个普通类TheSecondClass的定义
              ...... //其它普通类的定义
   interface TheFirstInterface{......} /*第一个接口TheFirstInterface的定义*/
              ...... //其它接口定义

【注】
 package语句
包在实际的实现过程中是与文件系统相对应的,例如javawork.helloworld所对应的目录是path/javawork/helloworld,而path是在编译该源程序时指定的。比如在命令行中编译上述HelloWorldApp.java文件时,可以在命令行中敲入”javac -d f:/javaproject HelloWorldApp.java”,则编译生成的HelloWorldApp.class文件将放在目录f:/javaproject/javawork/helloworld/目录下面,此时f:/javaprojcet相当于path。但是如果在编译时不指定path,则生成的.class文件将放在编译时命令行所在的当前目录下面。比如在命令行目录f:/javaproject下敲入编译命令”javac HelloWorldApp.java”,则生成的HelloWorldApp.class文件将放在目录f:/javaproject下面,此时的package语句相当于没起作用。

 import语句
如果在源程序中用到了除java.lang这个包以外的类,无论是系统的类还是自己定义的包中的类,都必须用import语句标识,以通知编译器在编译时找到相应的类文件。
 源文件的命名规则
如果在源程序中包含有公共类的定义,则该源文件名必须与该公共类的名字完全一致,字母的大小写都必须一样。这是java语言的一个严格的规定,如果不遵守,在编译时就会出错。因此,在一个Java源程序中至多只能有一个公共类的定义。如果源程序中不包含公共类的定义,则该文件名可以任意取名。如果在一个源程序中有多个类定义和接口定义,则在编译时将为每个类生成一个.class文件。(每个接口编译后也生成.class文件)

【注:编程建议】

a. 包名
包名是全小写的名词,中间可以由点分隔开,例如:java.awt.event 。
b. 类名
有意的标识符表示, 规范的书写驼峰命名法, 例如 class Collections
c. 接口
有意的标识符表示,命名规则与类名相同,例如interface Collection
d. 方法名
有意的标识符表示,通常首字母小写,推荐驼峰命名法,并且表示有意以的动词
e. 变量名
有意的标识符表示,通常为首字小写,并且为名词
f. 常量名
基本数据类型的常量名为全大写,如果是由多个单词构成,可以用下划线隔开,例如:int YEAR, int WEEK_OF_MONTH;如果是对象类型的常量,则是大小写混合,由大写字母把单词隔开。

【注:Java注释】
单行注释: 从”//”开始到本行结束的内容都是注释,
多行注释:在”/“和”/”之间的所有内容都是注释,
文档注释:在注释方面java提供一种C/C++所不具有的文档注释方式。其核心思想是当程序员编完程序以后,可以通过JDK提供的javadoc命令,生成所编程序的API文档,而该文档中的内容主要就是从文档注释中提取的。该API文档以HTML文件的形式出现,与java帮助文档的风格与形式完全一致。凡是在”/**”和”*/”之间的内容都是文档注释。例如下面的DocTest.java文件:

/* 类注释 / 
public class DocTest{ 
    /* 变量注释*/ 
  public int i; 
  /* 方法注释 */ 
   public void count( ) {} 
} 

运行”javadoc -d ./doc DocTest.java”,就在当前目下的doc目录中生成了介绍类DocTest的index.html等文件。

最后

以上就是老迟到哈密瓜为你收集整理的《Java开发 - 第1部分 基础篇》第1章 JAVA 概述的全部内容,希望文章能够帮你解决《Java开发 - 第1部分 基础篇》第1章 JAVA 概述所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部