2020javaweb开发环境搭建

1.前言

目前常用的IDE有eclipse、idea、vscode,本文暂时介绍前两个

tomcat、mysql、jdbc驱动无论哪个方案都需要

2.基础组件下载

2.1.tomcat9

不要用10,eclipse还不支持

https://tomcat.apache.org/download-90.cgi

2.2.mysql

https://dev.mysql.com/downloads/installer/

2.3.jdbc

https://dev.mysql.com/downloads/connector/j/

3.eclipse方案

目前最新eclipse运行本身需要java11以上,这里为了方便使用openjdk15

3.1.IDE下载

下载地址  https://www.eclipse.org/downloads/packages/

3.2.jre下载

如果你本地有,可以不用下载

下载地址 http://jdk.java.net/15/

3.3.配置

见视频

3.4.helloworld

见视频

4.idea方案

4.1.idea下载

下载地址 https://www.jetbrains.com/zh-cn/idea/download/download-thanks.html?platform=windows&code=IIC

4.2.tomcat插件下载

见视频

4.3.个人偏好配置(可选)

见视频

4.4.helloworld

见视频

 

2019C语言题目3

做点有意思的

代码如下,每变动一次重新粘贴一版,方便你们观察变化

第二题

第三题

第四题

第五题

2019C语言题目2-循环强化

循环强化

答案如下

接下来的两个对每列的打印顺序反转下就行

最后一个把前面的空格数除2,分三段打印就行,留给你们自己练习用

2019C语言题目1

题目如下,稍后再更新配套说明,zhanggai说他要写题解,等他的了。或者有哪个同学觉得自己写的好的发给我,我更新

答案如下

gradle入门中文教程

—————————下面是废话,可以忽略—————————-
第一次见到gradle是在写Android的时Android Studio下方的提示,那时候还没有仔细研究。第二次是在搭建校内中央认证的时候,由于需要研究代码不得不从源码导入idea,但是官方只有一堆源码,没有任何idea的项目文件。idea的依赖是存在.idea文件夹下的xml中的,而这个项目的依赖都写在了gradle文件中,当时费了好多时间才把官方4.2.0的源码成功导入,手工解决各种依赖问题,我高估了idea,还以为它能解析gradle并自动识别各种依赖呢,事实证明它确实能导入,但是依赖的级别都是错的或者有丢失。(顺便吐槽一下,如果一个jar中的依赖缺失是不会报错的,手动微笑)
官方文档居然一点提示都没有→_→后来偶然发现build.gradle文件中有这么几行

瞬间脑洞大开,想到当时写QQ机器人时候用的boost库的安装,是先根据需要生成不同版本vs的sln文件再导入到vs中,怀疑这个会不会一样的套路。

由于还看不懂build.gradle的语法,但是大概猜到意思是所有的项目使用了这几个插件,于是去gradle文档翻了翻,果然看到了这个文档

原文:The IDEA plugin generates files that are used by IntelliJ IDEA, thus making it possible to open the project from IDEA (File – Open Project). Both external dependencies (including associated source and Javadoc files) and project dependencies are considered.
意思是说这个插件可以生成idea所需的文件,让这个项目可以通过idea打开。

啊~~我花了这么长时间都在干些啥,再次鄙视CAS官方没在4.2.x文档写清楚,咳咳
今天特意上去看了下,4.2.x的文档确实没写,臻不是我没看到。我有句XXX一定要讲!最新版本的文档在开发者一栏增加了Build Process的教程传送门

论写好文档的重要性T T虽然我也懒的写(逃

—————————上面是废话,可以忽略—————————-

扯了这么多废话还是说正事吧,咳咳。

1.安装

要求:gradle可以在当前主流的平台上运行,仅仅需要jre或jdk7以上就可以。
如果你已经有一个使用gradle生成的项目,并且使用了GradleWrapper的话,就不需要安装任何其他的东西了,只要运行gradlew这个shell脚本就可以了,windows下为gradlew.bat,这个脚本会下载项目对应的gradle版本。但是我不推荐使用,国内的网你懂得。
windows上手动安装只需要下载这个包(传送门)然后解压即可。记的把bin目录加到环境变量PATH中。

Ubuntu上更简单apt-get install gradle,不解释了。

安装完成后运行gradle -v检查版本。
另外官方支持Zsh和Bash的自动完成脚本(传送门)

2.基本使用

如果你用过linux的make编译软件,那么你会比较容易理解gradle,感觉很像。
新建一个文件夹,里面放入一个名为build.gradle的文件,内容如下:

依赖关系如图(不知道能不能直接用官方图。。。如果不能自己点开吧)
图片地址:https://docs.gradle.org/current/userguide/img/commandLineTutorialTasks.png

进入命令行执行gradle dist,输出如下

每一个任务都有自己的依赖,当任务自己不依赖其他任务时候,就可以开始执行了,按拓扑序列执行所有任务,直到指定的dist完成。
如果想跳过某个任务,使用-x参数,例如gradle dist -x test跳过了test任务

默认情况下,gradle执行时候如果碰到有任务失败就会停下来,如果你为了尽可能多的发现错误,可以使用--continue参数。这时候如果有某个任务的依赖执行失败,那么这个任务也会被跳过。

当执行命令行时,可以使用任务名简写,只要给出的名字能确定唯一任务就行。例如di指的是dist,cT指的是compTest。

gradle tasks用来列出可以执行的任务列表。
gradle help --task someTask 用来查看某个任务的详细说明。
gradle -m someTask 用来查看某个任务的执行顺序,但是并没有真的执行。

3.Gradle Wrapper

大多数工具在使用之前要求你安装一些东西,如果他们安装简单那是最好的。但是如果像Hadoop安装一样繁琐,你就会感觉好气啊,怎么还不能用。更重要的是版本问题,如果版本不兼容怎么办?Gradle Wrapper同时解决了这些问题。
如果一个项目使用了Wrapper(官方建议每个项目都用),你可以像上文提到的那样使用gradle 来执行构建任务。(虽然我不推荐,因为网速实在是感人)

每个Wrapper都知道自己应该下载什么版本的gradle,所以不用担心版本问题。
这些文件很重要,不能删
gradlew (Unix Shell script)
gradlew.bat (Windows batch file)
gradle/wrapper/gradle-wrapper.jar (Wrapper JAR)
gradle/wrapper/gradle-wrapper.properties (Wrapper properties)

当通过Wrapper导入IDE的时候,IDE会使用Gradle的all版本,这可以帮助IDE更好的完成代码补全(个人建议安装的时候就下载all版本)
Wrapper下载的Gradle默认存放位置为
linux上为~/.gradle/wrapper/dists
windows上为C:\Users\<你的用户名>\.gradle\wrapper\dists

4.Gradle Daemon

From Wikipedia:
A daemon is a computer program that runs as a background process, rather than being under the direct control of an interactive user.

从3.0开始Gradle默认会启动一个守护进程,来减少每次build时候启动JVM的时间,并且可以在内存缓存项目相关的信息。
使用gradle --status查看守护进程
使用gradle --stop停止守护进程
在gradle.properties文件中写入org.gradle.daemon=false,并把文件放在默认目录下即可禁用守护进程。
linux上为~/.gradle/wrapper/dists
windows上为C:\Users\<你的用户名>\.gradle\wrapper\dists

5.依赖管理

大概来说,依赖管理由两步组成。Gradle需要知道你构建或运行项目需要的东西。第一步:找到它们,我们把这些文件叫做项目的依赖。第二步:Gradle需要把这些文件编译链接重组结构到你的产品中,我们把生成的文件叫做项目产品。

大多数项目的编写或测试都需要依赖其他的项目,例如为了使用Hibernate,在编译时候我需要把一些jar文件包含到我的classpath中,为了运行单元测试我需要额外的JUnit的jar包,还有就是JDBC数据库驱动等

这些外部依赖可能是远程的、本地的、子项目的等,Gradle需要知道这些依赖信息,并且把他们加载进来,我们把这个过程叫做依赖解析。

下面这段说的是Gradle比Ant更NB,不翻译了=_=好累.
Note that this feature provides a major advantage over Ant. With Ant, you only have the ability to specify absolute or relative paths to specific jars to load. With Gradle, you simply declare the “names” of your dependencies, and other layers determine where to get those dependencies from. You can get similar behavior from Ant by adding Apache Ivy, but Gradle does it better.

通常项目的依赖也会有他们的依赖,例如Hibernate的核心要求其他的几个库来运行,所以当Gradle运行项目测试的时候也需要找到这些依赖的依赖,叫做传递依赖。

大多数项目的目的是生成其他项目可用的库,例如Java Library,你需要生成jar文件或者包括源码和文档的jar文件并且发布出去。我们把这个过程叫做发布。
下面大概说Gradle非常关心你的用户体验,它能帮你把产品发布到任何地方(中文的博大精深)。
These outgoing files form the publications of the project. Gradle also takes care of this important work for you. You declare the publications of your project, and Gradle take care of building them and publishing them somewhere. Exactly what “publishing” means depends on what you want to do. You might want to copy the files to a local directory, or upload them to a remote Maven or Ivy repository. Or you might use the files in another project in the same multi-project build. We call this process publication.

示例代码:

上面的脚本声明了项目编译时需要Hibernate core 3.6.7.Final版本,言外之意是在运行时依然需要Hibernate和它自身的依赖。同理在编译单元测试的时候依赖junut4.0以上版本。同时它告诉Gradle在Maven中心仓库寻找任何其他需要的依赖。

Gradle依赖是分组管理的,一个配置组代表了一系列的依赖,Java插件定义了一系列标准配置。详见这篇文档

compile 这些依赖在编译时需要。
runtime 这些依赖在运行时需要,默认情况下已经包含了compile依赖。
testCompile 这些依赖在编译测试代码时需要。默认情况下也包含了所有编译后的class文件和compile依赖。
testRuntime 这些依赖在运行测试时候需要,默认情况下包含上面3个所有的依赖。

许多组件添加了很多标准配置,你可以定义你自己的配置,详见这篇文档.

示例:
外部依赖声明

第二个写法是简写
关于仓库设置不再啰嗦:原文传送门

(未完待续。。。。)

参考:http://wiki.jikexueyuan.com/project/GradleUserGuide-Wiki/
https://gradle.org/docs
https://gradle.org/getting-started-gradle/
https://docs.gradle.org/3.3/dsl/index.html
https://gradle.org/install
https://gradle.org/getting-started/creating-a-build
https://docs.gradle.org/current/userguide/userguide.html
http://www.cnblogs.com/davenkin/p/gradle-learning-1.html
http://blog.jobbole.com/71999/
http://blog.jobbole.com/72558/
http://blog.jobbole.com/72992/

本地虚拟机远程桌面穿透内网

1.注册花生壳账号。http://hsk.oray.com/
2.登录路由器配置界面。
3.绑定虚拟机网卡MAC和IP。
4.添加转发规则,把3389端口转发到外网。
5.配置花生壳账户,启用DDNS。
6.把自己的子域名加CNAME解析记录指向花生壳的动态域名。
7.更改虚拟机网卡设置,改成桥接模式。
8.更改系统设置,允许远程桌面访问。
9.开启Windows防火墙,配置规则。
10.关掉虚拟机和主机之间的所有共享文件夹。
这样在公网上即可使用自定义的域名连接家里的虚拟机了。

数据结构——线性结构

终于可以开始填这个坑了233333
————————————
像上一篇文章说的数据结构要解决的问题是数据如何在内存中存储,以什么结构存储。
用张仰森老师的话来说,就是“数据以及数据之间的关系。”
今天主要要聊的就是线性结构。

这里说的线性结构,是指从逻辑结构上来划分的。
说到这,就不得不提下物理结构。所谓逻辑结构,就是在逻辑、理论上定义的结构,而物理结构是指在实际的内存中数据的存储结构。

比如,有这么一种结构,每个元素只有唯一的前驱、唯一的后继、第一个元素没有前驱、最后一个元素没有后继。满足这样要求的结构就是线性结构。
而上面所说的结构仅仅是逻辑上的结构,而不是物理上的结构。之前已经学过的数组、链表,都可以表示这种结构。但是数组在物理结构上来说每个元素就是相邻摆放的,而链表的节点在实际内存中的分布却是分散的,仅仅是由于指针的存在好像使得前后有了关系。

C语言已经内置支持了最简单的线性结构,就是数组。
声明一个数组之后,就能得到N个相邻的物理空间。这N个空间中的变量就满足之前说的规律。
而概念里说的元素,可以是一个int,也可以是一个结构体。在本系列文章或者代码、我通常会用一个整数来代表一个元素。
而实际的应用中,一个元素可能是一个结构体、指针(最常见的是结构体的指针)。

说完了数据和数据之间的个关系,那么这个数据结构就已经快说完了,还差对应的一系列操作。
这里仅列出简单的几个操作,也就是增删改查,实际实现时候包括但不限于以下几种,候根据需要来写。
向线性表插入一个元素
从线性表删除一个元素
从线性表中查找关键字为i的元素
修改线性表中某个元素

套路:确定操作之后如何开始写代码
0.定义自己的数据结构(这里以C为例,所以写的是结构体。不排除以后用Java类的可能性=-=)
然后对每个操作按下面四个步骤
1.确定函数名、参数类型、参数数量
2.预想函数执行前内存的状态
3.确定函数执行后预期的内存状态
4.返回值类型极其含义

接下来将以两种实现方式进行说明,参考代码在github(求star求follow):
第一种:用数组实现的线性表
头文件:https://github.com/956237586/DataStructure-C/blob/master/DataStructure-C/1.1.linearlist.h
源文件:https://github.com/956237586/DataStructure-C/blob/master/DataStructure-C/1.1.linearlist.c

0.定义一个新的类型,叫List
//我默认大家都能看懂C语言,看不懂的请回上一篇看基础测试或者重新看下C的教程=-=
如上面代码中5-9行所示,我把一个数组和数组的长度定义为一个List。
createList,创建一个列表,
参数:长度
执行前状态:无
执行后状态:初始化一个指定长度的List
返回值定义 返回一个List
其他的同理。。。。

定义完了函数先写测试程序,如上面的主函数。
然后依次实现每个函数,createList的时候注意,在申请完内存后一定要初始化内存中每个地址的默认值,要么用NULL要么用0要么用参数,不要啥都不做,免得给自己挖坑
其实这也就是构造函数做的事情。。。
(代码中createList的时候其实应该返回指针更好一些,不然会再复制一份函数内部的List再return回去,然而这是很久之前的代码了,我懒得重写了=-=凑合着看吧233333)
代码中的问题(现在看当时写的代码简直是naive=-=):
风格不是很好。。。比如我省略了一些大括号,这是不好的习惯。。。
容错处理并没有做到最好,有些地方并不是一定会成功的操作我都没有做判断,比如realloc之后的返回值可能为NULL然而我没判断。。。

第二种实现方法,用链表实现线性表:
参考代码我就不贴上来了,去github看吧。。。
地址:
头文件:https://github.com/956237586/DataStructure-C/blob/master/DataStructure-C/1.2.linearlist.h
源文件:https://github.com/956237586/DataStructure-C/blob/master/DataStructure-C/1.2.linearlist.c

这是最基本的线性结构,之后所有复杂的结构都是这两种结构的组合、延伸,说白了再复杂的结构最终也能用这两种形式来组合表达。
其实计算机内存是线性的,所以某种意义上来说,所有的存储都是在把非线性的结构转换成线性结构来表达、然后存储、运算。

建议自己亲手仿写一个自己版本的线性表。。。。
写完后再继续往下看。
刚刚的线性表我们可以对对任意位置、任意元素进行操作。
如果我们加一点点限制,就出现了新的数据结构(其实并不是新的数据结构,只是操作操作受限的线性表而已)
也就是栈、和队列。
如果我们限制只能在一端增加和删除元素,那么就是栈。
如果我们限制只能在一端增加、在另一端删除,那么就是队列。
代码稍稍改一改就能搞定,参考代码地址如下:
https://github.com/956237586/DataStructure-C/tree/master/DataStructure-C
其中2.1是用数组实现的栈。
2.2是用链表实现的栈、也叫链栈。
(待补充详细说明,链栈的部分有个经典写法。。。)
3.1是用数组实现的队列,一般来说为了节省空间,数组会重复利用已有的空余内存,所以一般是循环队列。
(待补充详细说明,循环队列的关键在push和pop如何复用空余空间。。。。)
3.2是用链表实现的队列。(未完待续)
——————————–
今天先写到这=-=之后再继续写。。。。