目录

前言

1:基本规范

1.1:命名规范

1.2:修饰符规范

1.3 :强制约定

1.4:异常处理

1.5:不允许任何未经预先定义的常量值直接出现在代码中

1.6:对Long或者long赋值时,数值后必须加大写字母L

1.7:在 if/else/for/while/do 语句中必须使用大括号,即使只有一行代 码。禁止采用单行编码方式。

1.8:单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则

1.9:使用equals对比数值时,应将数值放在equals前面,避免潜在的空指针异常

2.0:获取当前毫秒数应使用统一范式代码

2.1创建集合时,必须指定泛型

2.2禁止在foreach 循环里进行集合元素的 remove/add 操作

2:并发处理

2.1禁止在代码里自行创建线程进行异步操作,应使用线程池

2.2SimpleDateFormat使用,锁的使用

3:事务处理

4:接口规范

5:代码分层

6: 日志处理

7:数据库规范

7.1:建表规范

7.2:索引规范

7.3:SQL规范

8:版本规范

9: 代码性能

9.1 代码性能

9.2:可读性


前言

 ● 本规范基于jdk1.8进行编制,文档内出现的某些类可能在低版本jdk不存在● 数据库规范基于MYSQL数据库,ORACLE数据库

1:基本规范

1.1:命名规范

● 类名必须使用驼峰式风格,首字母大写,但以下情形例外:DO / BO / DTO / VO / AO / PO / UID等○ 正例:MarcoPolo / UserDO / XmlService / TcpUdpDeal / serialVersionUID○ 反例:macroPolo / UserDo / XMLService / TCPUDPDeal / TAPromotion● 方法名、参数名、成员变量、局部变量强制统一使用驼峰式风格进行命名,首字母小写○ 正例:localValue / getHttpMessage() / inputUserId○ 反例:LocalValue / GetHttpMessage() / InputUserId● 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字长○ 正例:MAX_STOCK_COUNT○ 反例:MAXCOUNT● 代码中的命名严禁使用拼音与英文混合的方式,更不允许直接使用中文的方式○ 正例:alibaba / taobao / youku / hangzhou 等国际通用的名称,可视同英文○ 反例:DaZhePromotion [打折] / getPingfenByName() [评分] / int 某变量 = 3● POJO类中布尔类型的属性禁止加 is 前缀,否则部分框架解析会引起序列化错误○ 正例:deleted○ 反例:isDeleted● 包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式○ 正例:com.petrochina.ai.util○ 反例:com.PetroChina.ai.util● 杜绝完全不规范的缩写,避免望文不知义○ 反例:AbstractClass“缩写”命名成 AbsClass;condition“缩写”命名成 condi,此类随 意缩写严重降低了代码的可阅读性● 接口名不要加Interface后缀,接口的实现类统一加Impl后缀○ 正例:CacheService  CacheServiceImpl○ 反例:CacheServiceInterface  CacheService

1.2:修饰符规范

● 接口中的方法不要加任何修饰符号           ○ 正例:void commit();○ 反例:public void commit();● 枚举类需带上 Enum 后缀,枚举成员名称需要全大写,单词间用下划线隔开○ 正例:枚举名字为ProcessStatusEnum的成员名称:SUCCESS / UNKNOWN_REASON● 方法命名规则:○ Service/DAO层方法命名规则■ 获取单个对象的方法用get做前缀■ 获取多个对象的方法用list做前缀,复数形式结尾如:listObjects■ 获取统计值的方法用count做前缀■ 插入的方法用save/insert做前缀■ 删除的方法用remove/delete做前缀■ 修改的方法用update做前缀● 领域模型命名规则:○ 数据库实体类:xxxPO,类中的属性和数据库字段严格一一映射○ 数据对象: xxxDO, 类中的属性可以和数据库字段一一映射,可以是PO的子集○ 数据传输对象:xxxDTO,包括controller层返回给前端的对象,和外部系统交互的对象○ 业务对象:xxxBO,该对象可包含多个PO或DO,作为业务层返回结果给controller使用

1.3 :强制约定

● IDE的标黄警告必须全部处理,禁止提交包含警告提示的代码● 提交代码时必须进行代码格式化,非格式化的代码不允许提交● 禁止在业务类中定义和使用内部类● 禁止将所有的业务都写在一个类里,一个类应处理单一业务● 禁止使用过时的类或方法● 所有的覆写方法,必须加@Override 注解● 禁止类中import无用的包,IDEA可以通过勾选Optimize imports on the fly选项自动剔除无用的包● 禁止在 POJO 类中,同时存在对应属性 xxx 的 isXxx()和 getXxx()方法● 重载方法必须按照顺序放在一起,同理,如果存在多个构造方法也遵从此规则● 不用的代码块及时删除,禁止注释多行代码,如果某些代码今后可能会重新启用,应采用版本管理,例如在类名或者方法名后加版本号;而事实上大多数开发场景,注释掉的代码95%的情况下不会重新启用,所以应及时删除,避免代码过于臃肿且可读性差。● 单行注释使用//,注释的双斜线与注释内容之间有且仅有一个空格;多行注释使用/* */● 关于 hashCode 和 equals 的处理,遵循如下规则○ 只要重写equals,就必须重写hashCode○ 向set集合中放业务对象时,必须重写该对象的equals和hashCode方法○ 同理,如果map的key是业务对象,也必须重写该对象的equals和hashCode方法● 单个方法的总行数不得超过80行,如果代码过长可以利用IDE的方法提取快捷键○ IDEA: Ctrl+Alt+M○ Eclipse: Alt+Shift+M● 当拼接的字符串数目超过5个时,禁止使用+进行拼接,应使用Stringbuilder,如果需要保证线程安全,则需使用Stringbuffer● 使用try..catch时,在catch块里捕获的异常要么进行业务处理,要么利用日志框架进行log记录,要么向上抛出由调用方处理,禁止吞掉异常,什么都不做。○ 反例:try {...} catch (Exception e) { System.out.println("xxxx");}

1.4:异常处理

● 禁止在finally 块中使用 return,finally 块中的 return 返回后方法结束执行,不会再执行 try 块中的 return 语句● 如果使用到资源对象或者流对象,必须在finally块中对其进行关闭● 关于基本数据类型与包装数据类型的使用标准如下○ 所有的POJO类属性使用包装数据类型○ RPC方法的返回值和参数使用包装数据类型○ 所有的局部变量使用基本数据类型○ 正例:public class BusinessBO { // 禁止使用boolean定义 private Integer count; // 禁止使用int定义private Boolean deleted;}

1.5:不允许任何未经预先定义的常量值直接出现在代码中

           ○ 正例:
private static final String KEY_PREFIX = "petro_cnpc#id_";
...String key = KEY_PREFIX + tradeId;
cache.put(key, value);○ 反例:
String key = "petro_cnpc#id_" + tradeId;cache.put(key, value);

1.6:对Long或者long赋值时,数值后必须加大写字母L

 ○ 正例:
long count = 2L;○ 反例:
long count = 2;long number = 2l; // 如果是小写l,很容易和数字1混淆

1.7:在 if/else/for/while/do 语句中必须使用大括号,即使只有一行代             码。禁止采用单行编码方式。

 ○ 正例:
if (condition) { statements;}○ 反例:
if (condition) statements;if (condition) statements;

1.8:单行字符数限制不超过 120 个,超出需要换行,换行时遵循如下原则

            ○ 运算符与下文一起换行○ 方法调用的点符号与下文一起换行○ 方法调用中的多个参数需要换行时,在逗号后进行○ 在括号前不要换行○ 正例:StringBuffer sb = new StringBuffer(); sb.append("zi").append("xin").append("huang") .append("huang").append("huang");

1.9:使用equals对比数值时,应将数值放在equals前面,避免潜在的空指针异常

○ 正例:
"test".equals(object);Objects.equals("test",object); // 建议使用jdk1.7引入的Objects工具类○ 反例:
object.equals("test");

2.0:获取当前毫秒数应使用统一范式代码

○ 正例:
long now = System.currentTimeMillis();○ 反例:
long now = new Date().getTime();

2.1创建集合时,必须指定泛型

○ 正例:
List<String> list = new ArrayList<>();○ 反例:
List list = new ArrayList();

2.2禁止在foreach 循环里进行集合元素的 remove/add 操作

  ○ 正例:
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) { String item = iterator.next(); if (删除元素的条件) { iterator.remove(); }
}○ 反例:
for (String item : list) { if ("1".equals(item)) { list.remove(item); }
}

2:并发处理

2.1禁止在代码里自行创建线程进行异步操作,应使用线程池

● 禁止使用Executors创建线程池,而是通过 ThreadPoolExecutor 的方式○ Executors创建的线程池是无界任务队列,在高并发下有耗尽系统资源的风险○ 一个正确创建线程池的案例:
// 这里创建了一个核心线程数是10,最大线程数是20,任务等待队列100的线程池
// 线程池内的线程应有自己的命名,在这里是mine-threadPool-xxx
// 如果任务队列超负载,则抛出异常,由任务调用方进行补偿处理
// ThreadPoolExecutor的其余构造方法请见源码
ThreadPoolExecutor threadPoolExecutor =
new ThreadPoolExecutor(10, 20, 30,TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100), r -> { Thread t = new Thread(r);
t.setName("mine-threadPool-" + t.getId()); return t; },(r, e) -> { throw new RejectedExecutionException(); });

2.2SimpleDateFormat使用,锁的使用

● SimpleDateFormat线程不安全,禁止在单例对象(spring的bean默认都是单例的)的属性中定义SimpleDateFormat,或者将SimpleDateFormat定义成static属性。○ 可以在方法体内部去定义,但是这样会频繁创建对象导致性能下降○ 最理想的方案是使用ThreadLocal○ jdk8可以用DateTimeFormatter替代SimpleDateFormat● 高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就不要锁整个方法体;能用对象锁,就不要用类锁。○ 使用synchronized时尤其需要注意锁住的资源到底是什么○ synchronized用在实例方法上,锁住的是对象,不建议这样加锁○ synchronized用在静态方法上,锁住的是类,不建议这样加锁○ 尽量使用Lock锁, 避免使用synchronized■ 尽管synchronized在jdk1.6之后经过优化已经基本不存在性能问题,但是如果阻塞时间过久,synchronized仍然会升级成重量级锁,极大影响系统性能■ synchronized在代码层面对锁的控制不够灵活■ Lock锁使用标准范式:// 范式一:使用lock()阻塞获取资源
Lock lock = new ReentrantLock();lock.lock(); try{ ...} finally{ lock.unlock();}
// 范式二:使用tryLock()阻塞式获取资源,但是增加最大等待时间,推荐
Lock lock = new ReentrantLock();if (lock.tryLock(long timeout, TimeUnit unit)) { try{ ... } finally{ lock.unlock(); }}
// 范式三:使用tryLock()非阻塞式获取资源,获取不到则走else逻辑
Lock lock = new ReentrantLock();if (lock.tryLock()) { try{ ... } finally{ lock.unlock(); }} else { ...}● 业务预估如果每次访问冲突概率小于 20%,应使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于 3 次。典型的乐观锁是数据库的version字段版本控制以及Lock锁的tryLock方法● 使用ThreadLocal时,线程执行完逻辑之后,必须执行ThreadLocal.remove()方法,否则会造成内存泄漏● 使用CompletableFuture提交异步任务时,必须指定线程池,禁止用默认的线程池,使用get方法获取异步任务的执行结果时必须指定最大等待时间,禁止一直阻塞等待● 对容器有同步要求时,禁止使用HashTable和Vector,应使用JUC包下的ConcurrentHashMap和ConcurrentLinkedDeque等高并发容器替代

3:事务处理

● 禁止将一大长串业务代码包装成事务,应仅包含可回滚的代码○ 事务方法内部应只包含数据库的INSERT,UPDATE, DELETE操作,相关逻辑校验和查询应放在事务外部● 能不使用分布式事务就不使用分布式事务,分布式服务之间的一致性可利用补偿机制实现● 禁止在类上直接标注@Transactional,需要针对每一个方法作精准区分● 在事务方法内使用try..catch需谨慎,如需使用,需要显式抛出异常并指定rollbackFor,避免事务失效导致无法回滚● 禁止使用this.xxx()方式调用事务方法,事务方法必须存在于事务层中,由上层业务进行调用。this.xxx()形式调用会使事务失效

4:接口规范

● 所有提供给前端的http接口应使用restful风格并遵循restful架构规范● HTTP请求类型应按照以下四类作为区分:○ GET  获取资源○ POST  新建资源○ PUT  更新资源○ DELETE  删除资源○ 如某些前端框架不支持发送PUT和DELETE请求,则需严格区分GET和POST,避免所有请求都用POST● 接口名称不允许出现动词,应使用资源名词的单数或者复数形式,如:○ 获取商品详情:GET  /product/{id}○ 获取商品列表: GET /products○ 添加商品: POST  /product○ 修改商品:PUT  /product/{id}○ 删除商品:DELETE  /product/{id}● 接口返回必须指定http状态码:○ 200 :业务处理成功○ 500 :  服务端业务异常或运行时异常○ 404 :  资源不存在○ 403 :没有权限访问资源○ 503 :服务不可用,可能发生在系统限流或熔断时

5:代码分层

● 代码工程应至少具有以下四层结构:○ DAO层:数据访问层,负责和数据库的交互○ Service层:数据服务层,该层处理事务回滚以及封装外部接口调用等。○ Manager层:业务服务层,该层执行具体业务逻辑○ Web层:该层负责处理前端数据交互,负责参数校验■ web层可抽离出controller层和api层■ controller层负责和前端交互,api层负责为外部系统提供接口● 各层的业务类必须加层名后缀,如: xxxService,xxxDAO,xxxController,禁止不加后缀单独命名● DAO层和Service层的方法禁止返回map,需要把map封装成PO或者DO对象

6: 日志处理

● 代码里绝对禁止使用System.out.print记录日志,必须使用日志框架。● 应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一○ 方式一:类上加@Slf4j注解○ 方式二:
import org.slf4j.Logger;import org.slf4j.LoggerFactory;private static final Logger logger = LoggerFactory.getLogger(Abc.class);
● 生产环境日志文件至少保存 15 天,需根据日志级别对日志文件进行区分记录:○ info级别:  记录业务日志,包括业务异常也用info记录○ warn级别:记录可能导致系统运行异常的各种警告信息○ error级别:记录系统错误日志,包括各种运行时异常堆栈以及影响系统正常运行的错误信息● 日志文件命名方式:appName_logType_logName.log○ appName: 应用名称○ logType:日志类型,如 stats/monitor/access 等○ logName:日志描述● 对 trace/debug/info 级别的日志输出,禁止采用字符串拼接方式输出日志。○ 正例:
logger.info("Processing trade with id: {} and symbol : {} ", id, symbol);○ 反例:
logger.info("Processing trade with id: " + id + " and symbol: " + symbol);
● 异常日志必须记录异常堆栈信息○ 正例:
logger.error(e.getMessage(), e);logger.error("system error", e);○ 反例:
logger.error("system error");logger.error(e.getMessage());
● 生产环境禁止输出debug日志,有选择地输出info日志,禁止在info日志中随意打印各种无关信息,如果需要debug信息,则可以这么写:if (logger.isDebugEnabled()) {logger.debug("Processing trade with id:{}",id);
}

7:数据库规范

7.1:建表规范

● 所有表必须具备3个字段: id, created_time, modified_time○ id: 主键,bigint unsigned 类型,不得随意更改名称,采用自增序列,禁止采用uuid作为主键○ created_time: 记录创建时间,datetime类型○ modified_time:记录修改时间,datetime类型● 表名、字段名必须使用小写字母或数字,但是禁止以数字开头。单词之间用下划线分隔○ 正例: petro_admin,rdc_config○ 反例: PetroAdmin,rdcConfig● 表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint○ 说明:任何字段如果为非负数,必须是 unsigned○ 正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除● 小数类型为 decimal,禁止使用 float 和 double○ float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不 正确的结果● 如果存储的字符串长度几乎相等,使用 char 定长字符串类型● varchar类型长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。● 禁止使用外键,表之间的关联关系采用代码进行维护● 时间类型应使用datetime类型,禁止使用varchar

7.2:索引规范

● 频繁被查询的且区分度较高的字段应该建立索引;多表join的关联字段应该建立索引; 排序字段应该建立索引● 索引命名规则:○ 主键索引:  id○ 唯一索引:uk_字段名○ 普通索引:idx_字段名○ 联合索引:  idx_字段名1_字段名2● 业务上具有唯一特性的字段组合,需要建立唯一索引,大幅增加查询速度● 禁止在区分度低的字段上建立索引,如性别,类型,是否删除等● 建立联合索引时,区分度高的字段处于左侧● 每张表的索引数量不得超过6个

7.3:SQL规范

● 禁止使SELECT * 查询,只查询需要的字段● 代码里所有的sql关键字必须全大写,如 SELECT,FROM,COUNT● 统计记录数使用COUNT(*),不要使用 COUNT(列名)或 COUNT(常量)来替代 COUNT(*)● SQL语句写好后,需要查询执行计划,如果查询计划显示该条SQL需要执行全表扫描,则不合格,可以通过加索 引或者优化SQL来解决○ 很多全表扫描是由于SQL不规范导致的索引失效进而引起全表扫描○ 典型的造成索引失效的案例就是在索引字段上使用函数,以及 like '%%'● 禁止使用where进行多表关联查询,应当使用join○ join关联的字段需要建立索引○ 禁止超过3个表进行关联查询● 操作生产环境数据库时,每条查询语句必须加上LIMIT 指定查询出的最大行数,一般不超过20行

8:版本规范

● 每个代码工程应该至少具有以下分支:○ master分支: 生产环境分支○ hotfix分支: 生产环境的热修复分支,用于修复验证生产环境的bug○ develop分支:开发分支,开发人员提交代码的主分支○ test分支:测试分支,测试人员用于测试的分支● 开发人员禁止直接向develop分支提交代码,应根据需求或者人员作为区分,从develop分支拉取子分支进行开    发,开发完成的代码完成自测后,提交合并请求,由相关代码审核人员审核通过之后,才能进入develop分支, 各开发人员每天应至少从develop分支合并一次代码到自己开发所在的子分支,以便及时处理潜在的代码冲突● 代码版本命名规范:○ 遵循:【v + 主版本号.子版本号.修订版本号.日期_版本阶段 】命名规则○ 新建立的工程版本号应从1.0.0开始○ 日期和版本阶段非必填,以下几个版本名称都是符合要求的
v1.0.2v1.0.2.20220501v1.0.2.20220501_RELEASEv1.0.2_RELEASEv1.0.2_BETA● 每次在生产环境发布master分支之前,必须对master分支的代码打tag,tag命名规范: 【v + 主版本号.子版本号.修订版本号】

9: 代码性能

9.1 代码性能

● 选择合理的集合遍历方式,特别是集合数据比较大时○ 使用entrySet遍历Map类集合KV,而不是keySet方式进行遍历○ 使用iterator遍历LinkedList,使用for遍历ArrayList● 初始化ArraryList和HashMap时,如果能预估集合的元素数量,那么最好指定元素数量,因为ArraryList和 HashMap每次动态扩容时都是比较耗费性能的// 这个例子演示初始化一个元素容量为50的listList<String> list = new ArrayList<>(50);
// 这个例子演示初始化一个元素容量为50的map
// map扩容因子默认0.75,故初始容量需要大于50/0.75 = 66.6666Map<String,Object> map = new HashMap<>(67);
● 使用parallelStream替代Stream○ 多核cpu服务器下parallelStream并行流比Stream串行流性能提升较大● 在for循环里对数据库的进行操作需要极其慎重,这种操作有时候完全可以通过优化sql的方式避免● 合理使用线程池,线程池的线程数量并不是越多越好,过多的线程数量会造成cpu上下文切换的开销过大,一般线程池的最大线程数设置为cpu核心数的2-3倍即可● 应用池化技术,如数据库连接池,Http连接池,但是连接池使用应遵循以下规范:○ 从连接池中获取连接必须指定超时时间,不可永久等待○ 连接池中的连接使用完毕之后必须及时放回池中,有些池化框架需要手写代码归还连接○ 连接池的连接数量不可随意指定,应从硬件方面和性能测试结果方向综合考量● 所有对资源的访问,应设置最大等待时间,如http访问,数据库访问,锁竞争,避免资源一直获取不到导致线程持久阻塞● 利用spring的@bean单例创建方式去管理代码里需要复用的自定义对象,避免重复new创建增加开销

9.2:可读性

● 重复的代码需要抽离出公用方法,避免采用复制粘贴的方式;一般代码行数超过10行并且重复引用次数大于2次就需要做方法抽离● 每一个类开头上都应有注释,标注该类的作用,每一个public方法上也应该有注释,标明该方法的入参和出参含义以及方法● Optional的频繁使用会降低代码的可读性,尽管代码写起来很优雅,在一般情况下,可以用if的形式替代Optional,让代码易于维护● if..else控制语句不要超过3层嵌套,会大大增加代码阅读的复杂度,可以通过如下方式进行优化:if (...) { return;}
● 方法内部对于一个完整的业务流程,应增加详尽的注释并标明步骤编号, 每一步骤业务代码写完之后,另起一行,如:// 1. xxxxx....// 1.1 xxxserviceA();// 2. xxxserviceB();● 使用map和枚举类替换冗长的if语句判断,如以下代码会使得代码极度臃肿:if (type == 1) { return "A";} else if (type == 2) { return "B";} else if (type == 3) { return "C";} .......

统一JAVA软件开发规范相关推荐

  1. java 软件开发面试宝典

    一. Java 基础部分........................................................................................ ...

  2. python软件开发规范

    软件开发规范 什么是软件开发规范? 好的设计项目目录结构,就和编码风格一样,是每个程序员都有的风格,但是在流水化标准化作业过程中,个性和风格是 不被鼓励的.如果你去维护一个非常不好读的项目,虽然实现逻 ...

  3. *Java软件开发面试知识整理*

    Java软件开发面试知识整理 围绕以下几点回答问题:是什么.为什么.什么时候用.项目实现.解决什么问题.遇到的困难 谈谈你对Java和C的理解? Java: 面向对象.Unicode:可以跨平台(JV ...

  4. 《Java软件开发综合实训》实训大纲

    <Java软件开发综合实训>实训大纲 课程代码:   适用专业:计算机科学与技术 执 笔 人:   审 核 人: 学分学时:2学分32学时   制(修)订时间:2017.3 一.课程定位 ...

  5. java培训分享:java软件开发可以用哪些软件?

    从事java相关工作的小伙伴应该都有一个习惯,那就是运用软件的方便来达到高效率工作,本期小编为大家介绍的java培训教程就是关于"java软件开发可以用哪些软件?"的内容,来看看下 ...

  6. eclipse java代码某一行需要修改注释_看看这些Java代码开发规范吧!你好,我好,大家好!...

    作为一名开发人员,当你接手他人的项目时,且当你阅读他人的代码时,是有没有遇到脑袋充血,感觉Java要把你"送走"的感觉呢?我们在用Java开发技术进行开发前,一定要牢牢恪守Java ...

  7. 学习Java软件开发该从何入手

    21世纪科技飞速发展的时代,软件行业进军国内以来,发展潜力巨大,一点一点的从生活中渗透到企业运行中,Java软件开发无处不在,因此企业对Java软件开发工程师的需求非常大,就目前而言,想要学习Java ...

  8. 我是如何从通信成功转型为 Java 软件开发工程师的?

    十年寒窗苦读,无论是谁,都希望能够拥有一个好的未来,但是在面临职业生涯的抉择时,会有不少人会为曾经的选择而后悔,不过在为时不晚的情况下,大家更多的还是会转型.在本文中,作者将分享其从传统的通信行业融入 ...

  9. 开课吧:Java软件开发的优点有哪些?​

    众所周知Java语言因为其简单且安全性高等优点,越来越受到青睐,那么在使用Java开发语言进行软件开发的时候,具体有哪些优点呢? Java开发工程师需要了解的基础知识 Java软件开发的优点包括以下这 ...

最新文章

  1. python编程试题定位列表元素的函数是_笨办法学Python 习题 34: 访问列表的元素
  2. linux系统vim程序编译器,Linux学习:vim程序编辑器
  3. 简易数字频率计(verilog HDL设计)(2020维护版本)
  4. [原创]Paros工具培训介绍
  5. js复制数据IE,FF..浏览器兼容
  6. Java方法的静态绑定与动态绑定讲解
  7. opengl AUX_RGBImageRec
  8. 扩展WCF的消息分发行为
  9. AGAGA XOOORRR CodeForces - 1516B
  10. flask项目源码_源码解读:Flask上下文与代理模式
  11. 【原创】一点点雕虫小技脚本
  12. openstack运维实战系列(一)之keystone用户建立
  13. 【翻译】Windows下文件的命名
  14. 【洛谷搬运】NOIP2018 退役记
  15. 每天坚持“踮脚尖”,时间久了,身体会收获什么?每天踮多久?
  16. 分布式事务实现原理【BAT 面试题宝库附详尽答案解析】
  17. 关于单相变频电源及变频电路部分介绍
  18. 数据库学习之sql语句基础
  19. ScyllaDB 1.2 国内安装更新源发布
  20. 字节跳动面试真题:阿里P7级别面试经验总结,满满干货指导

热门文章

  1. HBuilder页面不小心删除了或者改掉了
  2. mac运行ps特别慢_的Photoshop在Mac上运行速度慢|优化Mac上的Photoshop
  3. 怎么在html中加入特效文字,如何使用HTML5+css3实现粒子效果文字动画特效(附完整代码)...
  4. PS一键生成鎏金字特效插件(糖果滤镜Skin Eye Candy)
  5. aimesh r6400 开_适合家用的路由器有哪些?
  6. 美术加:想要画好人物头像,头骨结构先吃透~
  7. 清明节到来,微信公众号图文排版有哪些使用技巧?
  8. 使用Motrix解决浏览器下载速度慢的问题
  9. mysql变量环境配置文件_Day44 Mysql环境变量、配置文件(2)
  10. oracle并行查询结果不唯一,Oracle并行查询出错