IntelliJ IDEA

一、IntelliJ IDEA 2019下载:
  1.访问IntelliJ IDEA官网,点击Download转到下载页面:
  !
  2.IntelliJ IDEA有两个版本:商业付费旗舰版(Ultimate)和开源免费社区版(Community)。旗舰版和社区版功能对比也在该页面下面,个人推荐下载商业付费旗舰版(Ultimate),毕竟功能丰富且强大。当前版本为IntelliJ IDEA 2019.2.3:
  !
  3.以IntelliJ IDEA 2019.1 Ultimate为例,双击安装包安装:
  !
  4.开始安装,点击Next:
  !
  5.选择安装位置,点击Next:
  !
  6.接下来有如下三个安装选项:
  Create Desktop Shortcut:创建桌面快捷方式图标,建议勾选64-bit launcher;
  Update context menu:是否将从文件夹打开项目添加至鼠标右键,根据需要勾选;
  Create Associations:关联文件格式,不推荐勾选,一般都是使用如Sublime Text、EditPlus等轻量级文本编辑器打开;
  Download and install JRE x86 by JetBrains:下载并安装JetBrains的JRE。若曾在安装JDK的时候也安装了JRE,则无需勾选此项;
  Update PATH variable (restart needed):是否将IDEA启动目录添加到环境变量中,即可以从命令行中启动IDEA,根据需要勾选:
  !
  7.创建开始菜单文件夹:
  !
  8.安装成功:选择第二个(稍后手动重新自动电脑)
  !
  9.首次安装选择Do not import settings,即不导入任何设置;若是升级可以选择第一项Config or installation folder,即指定为之前版本的配置文件夹或安装根目录:
  !
  10.是否同意用户协议,勾选I confirm that I have read and accept the terms of this User Agreement,点击Continue:
  !
  11.是否发送匿名使用统计数据,建议点击Don’t Send:
  !
  12.设置IntelliJ IDEA的UI主题,个人喜欢Darcula主题(以前的版本Darcula都放在IntelliJ后面,现在可能更多的人喜欢Darcula),后期也可以在设置里自行修改,点击Next: Default plugins:
  !
  13.IntelliJ IDEA支持功能插件化。以IntelliJ Platform为基础,添加相应功能的插件后就有了CLion、WebStorm、PyCharm、PHPStorm、Android Studio、GoLand、RubyMine等独立的IDE。对IntelliJ IDEA的插件管理,可以根据开发需求对某些插件开启或关闭。适当地关闭不需要的插件有助于减少占用空间和加快响应速度。初次使用IntelliJ IDEA建议直接点击Next: Featured plugins,上手以后可以在设置的插件管理中进行对插件增删:
  !
  14.IntelliJ IDEA推荐的插件列表,个人推荐安装IDE Features Trainer,可以在空闲的时候练习使用IDE的一些功能和快捷键,其余的根据自己的需要安装,一般选第二个!,点击Start using IntelliJ IDEA:
  !
二、商业版激活:
  1.新建一个记事本,将以下代码复制之后将文件改为reg格式:

1
2
3
4
5
6
7
8
9
10
Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\*\shell\runas] 
@="获取超级管理员权限"
"NoWorkingDirectory"="" [HKEY_CLASSES_ROOT\*\shell\runas\command]
@="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F" "IsolatedCommand"="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"
[HKEY_CLASSES_ROOT\exefile\shell\runas2]
@="获取超级管理员权限"
"NoWorkingDirectory"="" [HKEY_CLASSES_ROOT\exefile\shell\runas2\command] @="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F" "IsolatedCommand"="cmd.exe /c takeown /f \"%1\" && icacls \"%1\" /grant administrators:F"
[HKEY_CLASSES_ROOT\Directory\shell\runas]
@="获取超级管理员权限"
"NoWorkingDirectory"=""[HKEY_CLASSES_ROOT\Directory\shell\runas\command] @="cmd.exe /c takeown /f \"%1\" /r /d y && icacls \"%1\" /grant administrators:F /t" "IsolatedCommand"="cmd.exe /c takeown /f \"%1\" /r /d y && icacls \"%1\" /grant administrators:F /t"

  2.然后把该文本文档命名为 “Win10获取超级管理员权限.reg” ,然后双击导入注册表即可,这样就获得了Win10超级管理员权限。

  3.需要将0.0.0.0 https://account.jetbrains.com:443添加到hosts文件中(C:\Windows\System32\drivers\etc\hosts)中,屏蔽JetBrains校验注册码。

  4.打开软件,依次选择Activate、Activation code,将注册码粘贴到下面的框里,点击OK:
例如(百度激活码):

1
2
MNQ043JMTU-eyJsaWNlbnNlSWQiOiJNTlEwNDNKTVRVIiwibGljZW5zZWVOYW1lIjoiR1VPIEJJTiIsImFzc2lnbmVlTmFtZSI6IiIsImFzc2lnbmVlRW1haWwiOiIiLCJsaWNlbnNlUmVzdHJpY3Rpb24iOiIiLCJjaGVja0NvbmN1cnJlbnRVc2UiOmZhbHNlLCJwcm9kdWN0cyI6W3siY29kZSI6IklJIiwiZmFsbGJhY2tEYXRlIjoiMjAxOS0wNC0wNSIsInBhaWRVcFRvIjoiMjAyMC0wNC0wNCJ9XSwiaGFzaCI6IjEyNjIxNDIwLzBwIiwiZ3JhY2VQZXJpb2REYXlzIjo3LCJhdXRvUHJvbG9uZ2F0ZWQiOnRydWUsImlzQXV0b1Byb2xvbmdhdGVkIjp0cnVlfQ==-Zmbxcn7NPlqBNqAURX0uiLzybnruyx6PG+6KYZrpzm/IJJs5nnIogGgdfIJoifO6fbaaJYc5pjds7CHdrt/neIpvF2o/HvIjMEF4/AhNV7HUGsAa9zpMszc6YBIkMmVFh4Y7GPKOStA14/Ld83AC7kGnwL1Fq7eAXKJFljc00GMejPpfE0zDqTN634bC+0ojfklhWXaLqhUt230SiE8onnd3quvEaH5NsW7sIQm2spyONZI+iHvHFtl4EvG7tlRlD1StsfhrbgNNxz61FOEEQ+GtZIzMx+T4sbpfoRyms7lbWQecrbAtE0c2sR98esm4PcDUhrFVBxGorPC1ppOLSQ==-
MIIElTCCAn2gAwIBAgIBCTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE4MTEwMTEyMjk0NloXDTIwMTEwMjEyMjk0NlowaDELMAkGA1UEBhMCQ1oxDjAMBgNVBAgMBU51c2xlMQ8wDQYDVQQHDAZQcmFndWUxGTAXBgNVBAoMEEpldEJyYWlucyBzLnIuby4xHTAbBgNVBAMMFHByb2QzeS1mcm9tLTIwMTgxMTAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAF8uc+YJOHHwOFcPzmbjcxNDuGoOUIP+2h1R75Lecswb7ru2LWWSUMtXVKQzChLNPn/72W0k+oI056tgiwuG7M49LXp4zQVlQnFmWU1wwGvVhq5R63Rpjx1zjGUhcXgayu7+9zMUW596Lbomsg8qVve6euqsrFicYkIIuUu4zYPndJwfe0YkS5nY72SHnNdbPhEnN8wcB2Kz+OIG0lih3yz5EqFhld03bGp222ZQCIghCTVL6QBNadGsiN/lWLl4JdR3lJkZzlpFdiHijoVRdWeSWqM4y0t23c92HXKrgppoSV18XMxrWVdoSM3nuMHwxGhFyde05OdDtLpCv+jlWf5REAHHA201pAU6bJSZINyHDUTB+Beo28rRXSwSh3OUIvYwKNVeoBY+KwOJ7WnuTCUq1meE6GkKc4D/cXmgpOyW/1SmBz3XjVIi/zprZ0zf3qH5mkphtg6ksjKgKjmx1cXfZAAX6wcDBNaCL+Ortep1Dh8xDUbqbBVNBL4jbiL3i3xsfNiyJgaZ5sX7i8tmStEpLbPwvHcByuf59qJhV/bZOl8KqJBETCDJcY6O2aqhTUy+9x93ThKs1GKrRPePrWPluud7ttlgtRveit/pcBrnQcXOl1rHq7ByB8CFAxNotRUYL9IF5n3wJOgkPojMy6jetQA5Ogc8Sm7RG6vg1yow==

三、创作开始:
  1.Create New Project,即创建新项目
  2.需要先配置项目JDK,点击New:选择本地所安装的JDK的根目录(系统环境变量JAVA_HOME)(一般就是你安装的jdk显示的位置)
  3.选择Java
  4.询问是否从模板创建项目,不勾选,点击Next
  5.项目创建成功后,自动生成了.idea文件夹、src文件夹和HelloWorld.iml。.idea文件夹和HelloWorld.iml是IntelliJ IDEA项目配置信息相关的,暂不予考虑。在src文件夹下编写代码。右键src文件夹,选择New,通过二级菜单可以创建Java Class、Package和XML文件等
  6.运行HelloWord.java,可以通过右键或顶部工具栏运行或调试,Run为运行,Debug为调试。运行结果在下面的Console控制台显示

接雨水

题目

 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。


 
示例:
 输入: [0,1,0,2,1,0,1,3,2,1,2,1]
 输出: 6

解题思路

在乘更多的水的题目基础下,此题需解决每个格子怎么确定接水量。
通过分析,每个格子左边和右边的最大值中哪个小一点就会影响接水量(受最小值影响),因此我们确定两个指针i和j用来移动得出每个格子的接水量,而定义leftmax和rightmax为当前格子左边和右边的最大值。
  分为两个情况:
(1)如果左边的最大值<右边的最大值,那么就要确定左边i指针指向的格子接水量(leftmax-height[i])
(2)如果左边的最大值>=右边的最大值,那么就要确定右边j指针指向的格子接水量(rightmax-height[j])

方法:双指针法

代码(根据力扣官网提交作品的格式):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public int trap(int[] height) {
int max=0,leftmax=0,rightmax=0;
int i=0;
int j=height.length-1;
while(i<j)
{
leftmax=Math.max(leftmax, height[i]); //更新为左边最大值
rightmax=Math.max(rightmax, height[j]); //更新为右边最大值
if(leftmax<rightmax) //如果左边最大值小于右边最大值,左边就为限制因素
{
max+=leftmax-height[i]; //接水量=左边最大值-当前格子值
i++; //指针后移,计算下一个格子
}
else //如果左边最大值大于等于右边最大值,右边就为限制因素
{
max+=rightmax-height[j]; //接水量=右边最大值-当前格子值
j--; //指针前移,计算前一个格子
}

}
return max;
}
}

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.util.Scanner;
public class Solution{
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt();
int[] a=new int[n];
for(int w=0;w<a.length;w++)
{
a[w]=input.nextInt(); //输入n个柱状
}
System.out.println(trap(a)); //输出接水量
}
public static int trap(int[] height) {
int max=0,leftmax=0,rightmax=0;
int i=0; //从首部开始
int j=height.length-1; //从尾部开始
while(i<j)
{
leftmax=Math.max(leftmax, height[i]); //更新为左边最大值
rightmax=Math.max(rightmax, height[j]); //更新为右边最大值
if(leftmax<rightmax) //如果左边最大值小于右边最大值,左边就为限制因素
{
max+=leftmax-height[i]; //接水量=左边最大值-当前格子值
i++; //指针后移,计算下一个格子
}
else //如果左边最大值大于等于右边最大值,右边就为限制因素
{
max+=rightmax-height[j]; //接水量=右边最大值-当前格子值
j--; //指针前移,计算前一个格子
}

}
return max;
}

}

代码截图


乘更多的水

题目:
 给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水
 说明:你不能倾斜容器,且 n 的值至少为 2。
 示例:
 输入: [1,8,6,2,5,4,8,3,7]
 输出: 49

解题思路
此题意味着垂直的两条线段将会与坐标轴构成一个矩形区域,较短线段的长度将会作为矩形区域的宽度,两线间距将会作为矩形区域的长度,而我们必须最大化该矩形区域的面积,所以考虑面积最大的情况。
方法一:暴力法
代码(根据力扣官网提交作品的格式):

1
2
3
4
5
6
7
8
9
public class Solution {
public int mArea(int[] height) {
int max=0; //存放最大值
for (int i=0;i<height.length;i++)
for (int j=i+1;j<height.length;j++)
max = Math.max(max, Math.min(height[i], height[j])*(j-i)); //最大面积=较短边×下标的差
return max;
}
}

 复杂度分析:
 时间复杂度:O(n²)
 空间复杂度:O(1)


方法二:双指针法
思路:在方法一暴力求解的前提下,我们考虑两线段之间形成的区域总是会受到其中较短那条长度的限制。此外,两线段距离越远,得到的面积就越大。
 我们在由线段长度构成的数组中使用两个指针,一个放在开始,一个置于末尾。 此外,我们会使用变量 maxarea 来持续存储到目前为止所获得的最大面积。 在每一步中,我们会找出指针所指向的两条线段形成的区域,更新 maxarea,并将指向较短线段的指针向较长线段那端移动一步。
 为了使面积最大化,我们需要考虑更长的两条线段之间的区域。如果我们试图将指向较长线段的指针向内侧移动,矩形区域的面积将受限于较短的线段而不会获得任何增加。但是,在同样的条件下,移动指向较短线段的指针尽管造成了矩形宽度的减小,但却可能会有助于面积的增大。因为移动较短线段的指针会得到一条相对较长的线段,这可以克服由宽度减小而引起的面积减小。
代码(根据力扣官网提交作品的格式):

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Solution {
public int maxArea(int[] height) {
int maxarea = 0,i = 0, j = height.length - 1; //指针i和j分别指向首部和尾部
while (i < j) { //i小于j才能循环
maxarea = Math.max(maxarea, Math.min(height[i], height[j]) * (j - i)); //最大面积=较短边×下标的差
if (height[i] < height[j]) //如果左边的值小,就将指针i右移
i++;
else //如果右边的值小或者两者相等,就将指针j左移
j--;
}
return maxarea;
}
}

 复杂度分析:
 时间复杂度:O(n)
 空间复杂度:O(1)
完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.Scanner;
public class Ji {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
int n=input.nextInt(); //输入n个柱状
int[] a=new int[n]; //动态生成n大小的整型数组
for(int w=0;w<a.length;w++)
{
a[w]=input.nextInt(); //循环输入每个柱状的值
}
System.out.println(maxArea(a)); //输出最终值
}

public static int maxArea(int[] height) {
int maxarea=0,i=0,j=height.length-1; //指针i和j分别指向首部和尾部
while(i<j)
{
maxarea=Math.max(maxarea,Math.min(height[i], height[j])*(j-i)); //最大面积=较短边×下标的差
if(height[i]<height[j])
i++; //如果左边的值小,就将指针i右移
else
j--; //如果右边的值小或者两者相等,就将指针j左移
}
return maxarea;
}



}

文字篇2-《码农翻身》

  国庆期间看了看《码农翻身》这本书的第一章-计算机的世界你不懂。
  从中和计算机网络等课程进行对比和细化。

1. 线程 

  线程一出生就被编了一个唯一的编号,其作用是处理系统分配给它的任务。
  线程有三种状态,等待状态,就绪状态,运行状态。
  当线程的执行时间过长时会被cup中断从而进入等待状态,处于等待状态的线程在进入运行状态之前必须先进入就绪状态。
  一个线程如果占用了大量的cpu资源将会被kill掉然后当做垃圾回收。
  处于线程池中的线程在处理完任务后不会被注销,系统重启后线程池全部销毁。
  Memcached线程可以帮助网站缓存很多用户数据而且还是分布式的。
  在使用线程的时候一定要注意加锁(大Boss操作系统可以解决)

2. TCP/IP

  TCP连接是虚拟的,连接的状态信息并不会在路上保存:相反,连接的状态信息是在两端维持的。
  三次握手主要是为了验证通信双方的发信和收信能力没有问题。
  - 第一次握手:客户端发信,服务器端收到,这时服务器就明白客户端发信能力和自己的收信能力都是没有问题的。
  - 第二次握手:服务器发信客户端收到了,此时客户端明白自己的收发信能力和服务器的收发信能力都没有问题,但此时服务器端还不知道自己的发信能力和客户端的收信能力,所以需要第三次握手。  
  - 第三次握手:客户端发信,服务器端收信,这样就消除了服务器端对于客户端的收信能力的担忧。
  两端发送的信息并不是直接到达的,中间将会经过多个路由器的转发。在传输的过程中可能会发生数据包丢失的情况,所以TCP传输采取了超时重传的机制,当经过了一定的时间还没有收到确认包的时候,发送端会重新发送数据。
  两个地点传递信息的两种方式,一种是在两点间建立确定的信息通路,信息传递准确,代价高;另一种是建立不确定的通路,代价较低,可靠性也低,丢失则重传。
  TCP建立连接需要地址和端口,连接是虚拟的,连接状态信息在两端维持。要进行三次握手。使双方都确认自己和对方的收发能力没问题。信息分成小包经过一系列路由器发送,接收方确认之前发送的包已到达接受方后再发下一个包。如果有丢失等情况则重发。

3. CPU阿甘

  我的脑容量很小,所以醒来以后只想起我的创造者告诉我的几件事情:
  (1)你的工作就是运行指令。(只负责运行指令其他不管)
  (2)你不能保存指令,你的指令全在内存里。
  (3)你的第一条指令放在地址0xFFFFFFF0处。
  那还有什么可说的,感觉去取第一条指令吧。运行时我只关心两件事:
  (1)我工作必备的寄存器就放在我面前的工作台上。
  (2)程序计数器,我用它记住我要执行的下一条指令地址。
   缓存:根据局部性原理,将经常访问的东西存放在缓存中,这样就不用每次都访问内存了,可以加快速度,因为访问内存是很慢的。 (访问了内存地址之后,不久之后还会再次访问。这就是程序的局限性原理!!!)

4. 进程

  冯诺依曼提出存储程序的思想,将专用计算机变成通用计算机。操作系统一开始处理程序是批处理形式的,一次只能运行一个程序。由于硬盘和内存的速度远低于CPU,CPU经常闲置。为了充分利用CPU能力,产生了多任务系统,同时运行多个程序,每个运行的程序叫进程。操作系统维护一个进程控制块(PCB),并经常切换进程。
  多个进程共享内存产生了内存访问越界的问题,解决方法有静态重定位动态重定位,最后产生内存管理单元来控制内存访问。
  由于多进程系统可能出现某一进程长期占用CPU导致其它进程假死的问题,产生了分时操作系统,系统定时切换进程。
  由于程序内存占用量越来越大,产生了内存分块装载进内存的想法,同样是基于局部性原理。程序也可以比内存大得多。可以给每个程序一个超级大的虚拟空间,再通过MMU映射到真实内存地址上。操作系统维持一个页表,用来映射虚拟页面和物理页面。如果访问一个还没有被映射到物理内存的页面,就会产生缺页中断,操作系统负责到硬盘中调取。地址分成页号和偏移量,MMU负责完成地址的转换。CPU把最常用的页表放到缓存里,加快访问速度。
  一个程序被分成了代码段,数据段和堆栈段,操作系统维护一个段表。在每个页的内部,仍然按分页来处理。地址也变成了段号+偏移量。程序非法访问内存,就会产生段错误(segmentation fault)
  装载器创建虚拟地址空间,用一个数据结构把程序的数据颌和代码在硬盘上的位置记录下来,操作系统为程序建立进程,进程开始。代码被读入内存并执行。运行完成,内存空间被清理,覆盖。
  由于进程开销过大,在一个程序内部 可以使用多个线程共享进程的所有资源,其目的是像切换进程那样切换线程。程序员要注意不要让线程同时访问一个资源产生冲突。

,