首页 文章 精选 留言 我的

精选列表

搜索[快速],共10000篇文章
优秀的个人博客,低调大师

白盒测试快速入门1-简介

什么是白盒测试? 白盒测试被定义​​为测试软件解决方案的内部结构,设计和编码。在这种类型的测试中,代码对测试人员是可见的。它主要侧重于通过应用程序验证输入和输出的流程,改进设计和可用性,加强安全性。白盒测试也称为透明盒测试,开箱测试,结构测试,基于代码的测试和玻璃盒测试。它通常由开发人员执行。 它是软件测试“盒子测试”方法的两个部分之一。其对应的黑盒测试涉及从外部或最终用户类型的角度进行测试。另一方面,白盒测试基于应用程序的内部工作,并围绕内部测试。 由于透视框概念,使用了术语“WhiteBox”。透明框或WhiteBox名称表示能够透过软件的外壳(或“盒子”)进入其内部工作。同样,“黑匣子测试”中的“黑匣子”表示无法看到软件的内部工作方式,因此只能测试最终用户体验。 白盒测试中验证什么? 白盒测试涉及测试以下软件代码: 内部安全漏洞 编码过程中的路径损坏或结构不良 特定输入流 预期输出 条件循环 单独测试每个语句,对象和函数 测试可以在系统,集成和单元级别的软件开发中完成。白盒测试的基本目标之一是验证应用程序的工作流程。它涉及针对预期或期望的输出测试一系列预定义输入。 如果视频无法访问,请单击此处 如何进行白盒测试? 步骤1)理解源代码 测试人员经常做的第一件事就是学习并理解应用程序的源代码。由于白盒测试涉及测试应用程序的内部工作,因此测试人员必须非常了解他们正在测试的应用程序中使用的编程语言。此外,测试人员必须高度了解安全编码实践。安全性通常是测试软件的主要目标之一。 步骤2)创建测试用例并执行 白盒测试的第二个基本步骤涉及测试应用程序的源代码以获得正确的流程和结构。一种方法是编写更多代码来测试应用程序的源代码。测试人员将针对应用程序中的每个过程或一系列过程开发少量测试。此方法要求测试人员必须熟悉代码,并且通常由开发人员完成。 白盒测试示例 考虑以下代码 WhiteBox测试的目标是验证代码中的所有决策分支,循环和语句。 要运用上面代码中的语句,WhiteBox测试用例就是 a = 1,b = 1 a= -1,b = -3 白盒测试技术 主要的白盒测试技术是代码覆盖率分析。有自动化工具可用于执行代码覆盖率分析。以下是一些覆盖分析技术 语句覆盖: - 至少对代码中的每个可能的语句进行一次测试。 分支覆盖 - 此技术检查软件应用程序的每个可能路径(if-else和其他条件循环)。 除此之外,还有许多覆盖类型,例如条件覆盖,多条件覆盖,路径覆盖,功能覆盖等。每种技术都有其自身的优点,并尝试测试(覆盖)软件代码的所有部分。使用Statement和Branch覆盖,您通常可以获得80-90%的代码覆盖率,这已足够。 白盒测试的类型 白盒测试包含几种用于评估应用程序,代码块或特定软件包的可用性的测试类型。下面列出了 - 单元测试 它通常是在应用程序上完成的第一种类型的测试。在开发时,对每个单元或代码块执行单元测试。单元测试基本上由程序员完成。作为一名软件开发人员,您需要开发几行代码,一个函数或一个对象,并在软件开发生命周期早期继续进行单元测试以帮助识别大多数错误之前对其进行测试以确保其正常工作。在这个阶段确定的错误更便宜,易于修复。 内存泄漏测试 内存泄漏是运行速度较慢的应用程序的主要原因。如果您的软件应用程序运行缓慢,那么在检测内存泄漏方面经验丰富的QA专家非常重要。 除此之外,一些测试类型是黑盒和白盒测试的一部分。它们列出如下 白盒渗透测试 在此测试中,测试人员/开发人员拥有应用程序源代码,详细网络信息,涉及的IP地址以及运行应用程序的所有服务器信息的完整信息。目的是从多个角度攻击代码以暴露安全威胁 白盒Mutation测试: Mutation测试通常用于发现用于扩展软件解决方案的最佳编码技术。 参考资料 python测试开发项目实战-目录 python工具书籍下载-持续更新 python 3.7极速入门教程 - 目录 本文涉及的python测试开发库 谢谢点赞! 本文相关海量书籍下载 白盒测试工具 比如 pytest nose unittest doctest Veracode EclEmma RCUNIT NUnit JSUnit JUnit CppUnit gtest 白盒测试的优点 通过查找隐藏错误来优化代码。 白盒测试案例可以轻松实现自动化。 由于通常涵盖所有代码路径,因此测试更加彻底。 即使GUI不可用,也可以在SDLC中尽早开始测试。 WhiteBox测试的缺点 白盒测试可能非常复杂且昂贵。 通常执行白盒测试用例的开发人员会厌恶它。开发人员测试的白盒测试不详细可能导致生产错误。 白盒测试需要专业资源,并对编程和实现有详细的了解。 白盒测试非常耗时,更大的编程应用程序需要时间来完全测试。 小结 白盒测试可能非常复杂。所涉及的复杂性与正在测试的应用程序有很大关系。执行单个简单操作的小型应用程序可以在几分钟内进行白盒测试,而较大的编程应用程序需要数天,数周甚至更长时间才能完全测试。 白盒测试应该在软件应用程序上进行,因为软件应用程序在编写后会在每次修改后再次开发。

优秀的个人博客,低调大师

一文MyBatis-Plus快速入门

一、依赖及配置 使用下面的SQL创建数据库与添加数据 DROP TABLE IF EXISTS user; CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) ); DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com'); 1、在idea中创建一个SpringBoot项目,在pom.xml中添需要的依赖 添加MyBatis-Plus、mysql连接驱动、lombok的依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.0.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> 2、配置数据库连接 application.yml spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/mp username: root password: 1234 3、在启动类中添加注解 ==@MapperScan== 扫描Mapper接口包 @SpringBootApplication @MapperScan("com.jikedaquan.study.mp.mapper") public class MpApplication { public static void main(String[] args) { SpringApplication.run(MpApplication.class, args); } } 4、编写实体类,使用lombok @Data public class User { private Long id; private String name; private Integer age; private String email; } 5、编写UserMapper接口 UserMapper接口继承MyBatis-Plus提供的BaseMapper接口即可拥有CRUD的方法,泛型中填写操作的实体类,这里为User public interface UserMapper extends BaseMapper<User> { } 6、测试查询数据 @RunWith(SpringRunner.class) @SpringBootTest public class MpApplicationTests { @Autowired private UserMapper userMapper; @Test public void contextLoads() { List<User> userList = userMapper.selectList(null);//条件为null时查询所有数据 userList.forEach(System.out::println); } } 二、日志配置 配置日志到控制台输出 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 三、主键生成策略 MyBatis-Plus提供了多种主键生成策略以应对不同的场景 策略 说明 AUTO 数据库ID自增 NONE 该类型为未设置主键类型 INPUT 用户输入ID,该类型可以通过自己注册自动填充插件进行填充 ID_WORKER 全局唯一ID (idWorker) UUID 全局唯一ID (UUID) ID_WORKER_STR 字符串全局唯一ID (idWorker 的字符串表示) 1、注解控制主键生成策略 在实体类的主键字段上添加注解(自增时注意配合数据库设置) @Data public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email; } 2、全局配置控制主键生成策略 application.yml mybatis-plus: global-config: db-config: id-type: id_worker 四、自动填充 在常用业务中有些属性需要配置一些默认值,MyBatis-Plus提供了实现此功能的插件。在这里修改user表添加 create_time 字段和 update_time 字段,在User类中添加对应属性。 1、为需要自动填充的属性添加注解 ==@TableField== 提供了4种自动填充策略:DEFAULT,默认不处理。INSERT,插入填充字段。UPDATE,更新填充字段。INSERT_UPDATE,插入和更新填充字段。 @Data public class User { private Long id; private String name; private Integer age; private String email; @TableField(fill = FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; } 2、实现字段填充控制器,编写自定义填充规则 实现 MetaObjectHandler 接口,实现 insertFill 和 updateFill 方法,此处的 create_time 和update_time字段需要插入时填充值, 只有 update_time 字段在修改时需要填充,所以策略如下。 //需要将自定义填充控制器注册为组件 @Component public class MyMetaObjectHandler implements MetaObjectHandler { private static final Logger LOGGER= LoggerFactory.getLogger(MyMetaObjectHandler.class); //insert操作时要填充的字段 @Override public void insertFill(MetaObject metaObject) { LOGGER.info("start insert fill ..."); //根据属性名字设置要填充的值 this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } //update操作时要填充的字段 @Override public void updateFill(MetaObject metaObject) { LOGGER.info("start insert fill ..."); this.setFieldValByName("updateTime",new Date(),metaObject); } } 3、插入数据测试 @RunWith(SpringRunner.class) @SpringBootTest public class CRUDTest { @Autowired private UserMapper userMapper; @Test public void testInsert(){ User user = new User(); user.setName("jack11"); user.setAge(20); user.setEmail("4849111@qq.com"); int result= userMapper.insert(user); System.out.println(result); System.out.println(user); } } 4、修改数据测试 @Test public void testUpdate(){ User user = new User(); user.setId(2L); user.setName("Jackie"); int result = userMapper.updateById(user); System.out.println(result); } 一次插入数据后,create_time和update_time都被填充了设置的时间,做update操作后只有update_time的进行了填充修改。 五、乐观锁插件 乐观锁的核心原理就是提交版本必须等于记录当前版本才能执行更新 意图: 当要更新一条记录的时候,希望这条记录没有被别人更新 乐观锁实现方式: 取出记录时,获取当前version 更新时,带上这个version 执行更新时, set version = newVersion where version = oldVersion 如果version不对,就更新失败 1、添加version到表和类中,为属性添加 ==@Version== 注解 @Version private Integer version; 2、配置插件 @Configuration public class MyBatisPlusConfig { @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor(){ return new OptimisticLockerInterceptor(); } } 3、测试修改的两种情况 @Test public void testOptimisticLocker1() { User user = userMapper.selectById(1128212430124097543L); user.setName("修改后"); int result = userMapper.updateById(user); if (result == 1) { System.out.println("修改成功"); } else { System.out.println("修改失败"); } } @Test public void testOptimisticLocker2() { User user = userMapper.selectById(1128212430124097543L); user.setName("修改后"); user.setVersion(user.getVersion()-1);//测试旧版本 int result = userMapper.updateById(user); if (result == 1) { System.out.println("修改成功"); } else { System.out.println("修改失败"); } } 六、分页插件 启用分页插件和启用乐观锁插件都是通过注册一个Bean完成 1、启用分页插件 @Bean public PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } 2、测试分页查询 @Test public void testSelectPage(){ //构建分页条件第二页每页显示3条 Page<User> page=new Page<>(2,3); //使用分页条件查询,不使用其他条件 userMapper.selectPage(page, null); //获取分页后查询出的记录 List<User> records = page.getRecords(); records.forEach(System.out::println); System.out.println("是否有下一页:"+page.hasNext()); System.out.println("是否有上一页:"+page.hasPrevious()); System.out.println("总记录数:"+page.getTotal()); } 七、逻辑删除插件 有些数据希望不再展示,但在物理上仍然存在,这时可以使用逻辑删除。逻辑删除就是在表中添加一个逻辑字段(在上面基础上添加字段 deleted),删除的实质操作就是操作这个逻辑值,在查询、修改时根据此逻辑值进行近一步操作。 1、启用逻辑删除插件 @Bean public LogicSqlInjector logicSqlInjector(){ return new LogicSqlInjector(); } 2、添加逻辑映射配置 mybatis-plus: global-config: db-config: logic-delete-value: 1 # 逻辑已删除值(默认为 1) logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) 3、逻辑字段添加注解 ==@TableLogic== @TableLogic private Integer deleted; 4、测试逻辑删除 @Test public void testLogicDelete(){ int result=userMapper.deleteById(1L); System.out.println(result); } 观察日志可以看到生成的sql是update语句 八、性能分析插件 在开发和测试时观察sql执行耗时 1、配置SpringBoot为开发环境 spring: profiles: active: dev 2、启用插件 @Bean @Profile({"dev","test"}) //设置 dev test 环境开启 public PerformanceInterceptor performanceInterceptor(){ return new PerformanceInterceptor(); } 九、CRUD其他操作 @Test public void testSelectById() { User user = userMapper.selectById(1L); System.out.println(user); } @Test public void testSelectBatchIds() { List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); users.forEach(System.out::println); } @Test public void testSelectByMap() { Map<String, Object> param = new HashMap<>(); param.put("name", "jack"); param.put("age", 18); List<User> users = userMapper.selectByMap(param); users.forEach(System.out::println); } @Test public void testSelectMap(){ Page<User> page = new Page<>(2, 3); IPage<Map<String, Object>> mapIPage = userMapper.selectMapsPage(page, null); } @Test public void testDeleteById(){ int result = userMapper.deleteById(1L); System.out.println(result); } @Test public void testDeleteBatchIds(){ int result = userMapper.deleteBatchIds(Arrays.asList(2L,3L,4L)); System.out.println(result); } 欢迎热爱技术的小伙伴和我交流

优秀的个人博客,低调大师

Kubernetes中,通过Service访问Pod快速入门

一.背景 理想状态下,我们可以认为Kubernetes Pod是健壮的。但是,理想与现实的差距往往是非常大的。很多情况下,Pod中的容器可能会因为发生故障而死掉。Deployment等Controller会通过动态创建和销毁Pod来保证应用整体的健壮性。众所周知,每个pod都拥有自己的IP地址,当新的Controller用新的Pod替代发生故障的Pod时,我们会发现,新的IP地址可能跟故障的Pod的IP地址可能不一致。此时,客户端如何访问这个服务呢?Kubernetes中的Service应运而生。 二.实践步骤 2.1 创建Deployment:httpd。 Kubernetes Service 逻辑上代表了一组具有某些label关联的Pod,Service拥有自己的IP,这个IP是不变的。无论后端的Pod如何变化,Service都不会发生改变。创建YAML如下: apiVersion: apps/v1beta1 kind: Deployment metadata: name: httpd spec: replicas: 4 template: metadata: labels: run: httpd spec: containers: - name: httpd image: httpd ports: - containerPort: 80 配置命令: [root@k8s-m ~]# kubectl apply -f Httpd-Deployment.yaml deployment.apps/httpd created 稍后片刻: [root@k8s-m ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE httpd-79c4f99955-dbbx7 1/1 Running 0 7m32s 10.244.2.35 k8s-n2 <none> httpd-79c4f99955-djv44 1/1 Running 0 7m32s 10.244.1.101 k8s-n1 <none> httpd-79c4f99955-npqxz 1/1 Running 0 7m32s 10.244.1.102 k8s-n1 <none> httpd-79c4f99955-vkjk6 1/1 Running 0 7m32s 10.244.2.36 k8s-n2 <none> [root@k8s-m ~]# curl 10.244.2.35 <html><body><h1>It works!</h1></body></html> [root@k8s-m ~]# curl 10.244.2.36 <html><body><h1>It works!</h1></body></html> [root@k8s-m ~]# curl 10.244.1.101 <html><body><h1>It works!</h1></body></html> [root@k8s-m ~]# curl 10.244.1.102 <html><body><h1>It works!</h1></body></html> 2.2 创建Service:httpd-svc。 创建YAML如下: apiVersion: v1 kind: Service metadata: name: httpd-svc spec: selector: run: httpd ports: - protocol: TCP port: 8080 targetPort: 80 配置完成并观察: [root@k8s-m ~]# kubectl apply -f Httpd-Service.yaml service/httpd-svc created [root@k8s-m ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-svc ClusterIP 10.110.212.171 <none> 8080/TCP 14s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d [root@k8s-m ~]# curl 10.110.212.171:8080 <html><body><h1>It works!</h1></body></html> [root@k8s-m ~]# kubectl describe service httpd-svc Name: httpd-svc Namespace: default Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"httpd-svc","namespace":"default"},"spec":{"ports":[{"port":8080,"... Selector: run=httpd Type: ClusterIP IP: 10.110.212.171 Port: <unset> 8080/TCP TargetPort: 80/TCP Endpoints: 10.244.1.101:80,10.244.1.102:80,10.244.2.35:80 + 1 more... Session Affinity: None Events: <none> 从以上内容中的Endpoints可以看出服务httpd-svc下面包含我们指定的labels的Pod,cluster-ip通过iptables成功映射到Pod IP,成功。再通过iptables-save命令看一下相关的iptables规则。 [root@k8s-m ~]# iptables-save |grep "10.110.212.171" -A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.110.212.171/32 -p tcp -m comment --comment "default/httpd-svc: cluster IP" -m tcp --dport 8080 -j KUBE-MARK-MASQ -A KUBE-SERVICES -d 10.110.212.171/32 -p tcp -m comment --comment "default/httpd-svc: cluster IP" -m tcp --dport 8080 -j KUBE-SVC-RL3JAE4GN7VOGDGP [root@k8s-m ~]# iptables-save|grep -v 'default/httpd-svc'|grep 'KUBE-SVC-RL3JAE4GN7VOGDGP' :KUBE-SVC-RL3JAE4GN7VOGDGP - [0:0] -A KUBE-SVC-RL3JAE4GN7VOGDGP -m statistic --mode random --probability 0.25000000000 -j KUBE-SEP-R5YBMKYSG56R4KDU -A KUBE-SVC-RL3JAE4GN7VOGDGP -m statistic --mode random --probability 0.33332999982 -j KUBE-SEP-7G5ANBWSVVLRNZAH -A KUBE-SVC-RL3JAE4GN7VOGDGP -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-2PT6QZGNQHS4OL4I -A KUBE-SVC-RL3JAE4GN7VOGDGP -j KUBE-SEP-I4PXZ6UARQLLOV4E 我们可以进一步查看相关的转发规则,此处省略。iptables将访问Service的流量转发到后端Pod,使用类似于轮询的的负载均衡策略。 2.3 通过域名访问Service。 我们的平台是通过kubeadm部署的,版本是v1.12.1,这个版本自带的dns相关组件是coredns。 [root@k8s-m ~]# kubectl get deployment --namespace=kube-system NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE coredns 2 2 2 2 17d 通过创建一个临时的隔离环境来验证一下DNS是否生效。 [root@k8s-m ~]# kubectl run -it --rm busybox --image=busybox /bin/sh kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead. If you don't see a command prompt, try pressing enter. / # wget httpd-svc.default:8080 Connecting to httpd-svc.default:8080 (10.110.212.171:8080) index.html 100% |*******************************************************************************************************************************| 45 0:00:00 ETA / # cat index.html <html><body><h1>It works!</h1></body></html> 顺便提一下,在未来版本中,kubectl run可能不再被支持,推荐使用kubectl create替代。此处偷了个懒,后续不建议如此操作。 在以上例子中,临时的隔离环境的namespace为default,与我们新建的httpd-svc都在同一namespace内,httpd-svc.default的default可以省略。如果跨namespace访问的话,那么namespace是不能省略的。 2.4 外网访问Service。 通常情况下,我们可以通过四种方式来访问Kubeenetes的Service,分别是ClusterIP,NodePort,Loadbalance,ExternalName。在此之前的实验都是基于ClusterIP的,集群内部的Node和Pod均可通过Cluster IP来访问Service。NodePort是通过集群节点的静态端口对外提供服务。接下来我们将以NodePort为例来进行实际演示。修改之后的Service的YAML如下: apiVersion: v1 kind: Service metadata: name: httpd-svc spec: type: NodePort selector: run: httpd ports: - protocol: TCP nodePort: 31688 port: 8080 targetPort: 80 配置后观察: [root@k8s-m ~]# kubectl apply -f Httpd-Service.yaml service/httpd-svc configured [root@k8s-m ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE httpd-svc NodePort 10.110.212.171 <none> 8080:31688/TCP 117m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d Service httpd-svc的端口被映射到了主机的31688端口。YAML文件如果不指定nodePort的话,Kubernetes会在30000-32767范围内为Service分配一个端口。此刻我们就可以通过浏览器来访问我们的服务了。在与node网络互通的环境中,通过任意一个Node的IP:31688即可访问刚刚部署好的Service。 三.总结 这些天一直在看kubernetes相关的书籍和文档,也一直在测试环境中深度体验kubernetes带来的便捷,感触良多,综合自己的实践写下了这篇文章,以便后期温习。距离生产环境上线的时间越来越近,希望在生产环境上线之前吃透kubernetes。 学习任何新东西都必须静下心来,光看还不够,还要结合适量的实际操作。操作完成之后要反复思考,总结,沉淀,这样才能成长。 Kubernetes确实是一个比较复杂的系统,概念很多,也比较复杂,在操作之前需要把基本概念理解清楚。 四.参考资料 Kubernetes官方文档

优秀的个人博客,低调大师

如何快速开发一个IM系统

本文将会给大家介绍如何开发一个简单的即时通讯系统(IM)。 为什么不简单 我们的站点加一个即时通讯(IM)的功能,那么我们怎么做? 在回家的路上,问了同是实习生(网络方向)的舍友这样一个问题,他回答:“很简单,只需要在服务端保存一个list,收到一个人的message后,我转发给list中指定的另一个人就好啦” 接着,我们讨论了一晚上下面的几个问题 对方不在线怎么办? 内存里保存list的话,人多了怎么办? 怎么查看历史记录?怎么多端同步数据? 为什么微信用户只能建立有限个群,并且群聊功能很晚才开放?为什么微信好友数是有上线的? 怎么保证消息有序、不丢失数据? 如何保证消息的时效性? 如何承担高并发流量? 最后讨论的结果是:开发一个稳定高效的IM产品是相对困难的,上面这些难题,QQ、微信等产品都遇到过。而且IM产品一旦量达到一定程度,性能、稳定性、可用性

优秀的个人博客,低调大师

Linux下快速配置Java开发环境

1.下载 jdk8官网下载地址 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 我的百度云下载地址, 链接:https://pan.baidu.com/s/11Z37_qsdT5UtPqQe_nVnig 密码:r50o, 一直用,稳定性没的说! 先点一下接受,再选择对应版本下的包。我的是CentOS7.3/7.4, 选择tar.gz压缩包。 2.上传 把下载的压缩包上传到你的Linux服务器。 推荐工具 WinScp 直接拖拽上传! 3.命令 推荐下载Putty搭配WinScp超级爽!或者其他Shell软件都可以(XShell等等) 接下来假设你已经把jdk压缩包上传到服务器了,并假设存放在/usr/local/java/jdk8.tar.gz 1.进入jdk存放目录 cd /usr/local/java 2.查看 ls 3.解压 tar -zxvf jdk8.tar.gz 4.编辑 vi /etc/profile 光标移到最后,新系统是没有export xxxxx等,按一下i进入写入模式。 5.在下面添加下面这段 export JAVA_HOME=/usr/local/java/jdk1.8 export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=${JAVA_HOME}/bin:$PATH 再按下esc,输入:wq保存并退出! 6.设置立即生效 source /etc/profile 7.验证 java -version 出现如下所示信息即为安装成功 java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode) Create By yster@foxmail.com 转载注明出处

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册