GG修改器破解版下载地址:https://ghb2023zs.bj.bcebos.com/d/z/p/d/dbzs.apk?GGXGQ
进程的理解
但是为什么是伪并行呢,因为严格意义上来说,对于单CPU的电脑来说,在某一瞬间,CPU只能运行一个进程,但是他可以非常快速的在多个进程之间切换,堪称时间管理的鼻祖,因此在1秒中内,它可能运行多个进程,给人们产生并行的错觉。这种快速切换也称为多道程序设计。
进程的出生到灭亡
进程的创建有4种方式,
1、系统初始化:启动操作系统时,通常会创建一些进程,一些是前台进程,与用户进行交互,例如我们的整个桌面,一些是后台进程,例如邮件系统,通知系统,这些进程停留在后台运行,也称为守护进程(daemon)大部分时间都在睡眠,只有来新通知了才会被唤醒。
其余三种是正在运行的程序执行了创建进程的系统调用,用户请求创建新进程,以及在批处理系统中一个批处理作业的初始化。
这几种方式都是因为一个已存在的进程执行了一个用于创建新进程的系统调用,在UNIX中,只有一个系统调用——fork 来创建新进程。他会创建一个与调用进程相同的 副本,(不同的地址空间,不可写的内存区可以共享)也就是子进程,这两个进程拥有相同的内存映像,环境字符串和同样的打开文件。子进程的叛逆性较强,通常接下来他会调用 execve 或一个类似的系统调用以修改内存映像并运行一个新的程序,不和他爹父进程一样。
进程的层次机构:一个父进程可以创建多个子进程,一个父进程和他的多个子进程组成一个进程组,而一个子进程只能有一个父进程。这种结构类似树,而UNIX中,系统发出的信号可以一层一层在所有进程中传递。例如在UNIX在启动过程中,一个叫做 init 的进程出现在启动映像中,他读入一个说明终端数量的文件,然后为每个终端创建一个登陆进程(用来等待用户登陆),用户登陆成功之后,该登陆进程就启动一个新进程 shell来接受命令,所接受的命令会启动更多进程,以此类推,所有的进程都属于 init 为根的那一棵树。
进程的状态:进程有三种状态分别是,就绪(可以运行,但是因为其他进程正在运行而暂时停止),阻塞(出问题了,除非某种外部事件发生,不然没办法运行),运行(正常,正在占用CPU);
因为CPU在某时刻只能运行一个进程,加上很多进程都有运行的需求,以及运行过程中会发生各种各样的问题,进程在活着的时候就不停的在这三种状态来回切换。
一个进程在运行过程中会遇到数不清次的中断,那么如何在中断后的下一次运行时还能保持正常呢?重点是,保存中断时刻进程的信息,包括。。。。
系统中那么那么多的进程,操作系统老师维护这一张 进程表 来进行管理,表中包含了进程状态的重要信息,下图为进程表中的保存的一些字段。
多道程序设计模型
假设一个进程在生命中只有20%的时间被CPU执行,如果提高进程的数量,那么就可以提高 CPU的利用率,可以用公式 1 – p^n 表示,p为等待时间占比,n为进程数量,如下图所示,如果进程 80% 的时间都在等待,那么进程数量在10个以上时,CPU利用率才能达到80%。
为什么我们需要在一个进程中再创建线程呢,这是因为大部分应用的功能不是单一的,在其运行过程中同时发生着许多活动,通过将应用分解成许多准并行的线程,分而治之,会简化程序设计模型。
与进程非常不同的一点是:线程之间是 共享地址空间的,这意味着他们可以便利的进行合作,并且创建线程更加轻量级,创建时间比一个进程要快10~100倍;还有一个优点是性能方面的,如果存在大量的I/O处理以及计算,90%的时间花在I/O交互中,拥有多个线程意味着活动可以重叠进行(也就是并行),加快执行速度,如果大量的活动都是 CPU 密集型(大部分时间都占用CPU,而CPU在一个时刻只能被一个任务占用)的,就获得不了性能提升。
一个进程中的多个线程拥有其自己的信息,包括程序计数器,寄存器,堆栈,以及状态,每个线程会调用不同的过程,拥有各自不同的执行历史,用其自己的堆栈记录。
创建一个新线程需要调用 Pthread_create,返回新线程的标识符, Pthread_exit 用于在线程完成任务后结束线程, Pthread_join 调用来等待别的特定线程的终止。 Pthread_yield 用于当自己执行时间过长,希望让其他线程运行而主动停止自己,让出 CPU。 Pthread_attr_init 和 Pthread_attr_destory 分别用于初始化和结束线程的属性结构。
在用户空间实现:
线程在操作系统的用户空间的进程中实现时,每个进程需要有其专有的线程表,存放了每个线程的程序计数器,堆栈指针,寄存器,状态等。线程表由运行时系统管理维护。
但是这样也存在一些问题,首先是如何实现阻塞系统调用,因为我们不能让一个线程的调用阻塞系统,因为这样会停止其他所有正常运行的线程。一种方案是,改变系统调用,使得全部系统调用都是非阻塞的,但是这样很麻烦,也会影响其他用户程序。另一种方案是,在线程的某个调用会导致阻塞,就提前通知,由系统来审核,只有在安全情况下才进行线程要求的调用,不然就放一边,先运行别的线程,下次该线程取得控制权后在进行检测。系统周围从事检查的这类代码成为包装器(wrapper)。类似的问题是缺页中断问题,因为不是所有的程序都一次性放在内存中,当一个线程调用跳转到了一个不在内存上存储的指令时,CPU就要去访问别的地方(可能是磁盘),然后进行I/O操作,这会吧整个进程阻塞起来,指导磁盘I/O完成。
在内核空间:
内核支持和管理线程时,无需使用运行时系统了,内核中有用来记录系统中所有线程的线程表,保存的信息和用户空间中每个进程的线程表一样。
内核中实现线程的一个优点是,内核中的线程的所有阻塞系统调用都以系统调用的形式实现,这样当一个线程阻塞时,内核可以选择运行其他线程(自己进程或者其他进程的)。而在用户空间中,运行时系统始终运行自己进程中的线程,直到内核剥夺他的CPU为止。
由于在内核中创建和撤销一个线程的代价较大,某些系统在线程被撤销时,将其标记为不可运行状态,稍后在需要创建新线程时就重新启动某个旧线程,节省一部分开销。
调度程序激活机制
即使内核级线程在某些点优于用户级线程,但是内核级线程的速度慢,科学家提出了调度程序激活机制来解决用户级线程的阻塞调用问题。
其基本思路是,内核给每个进程安排一些虚拟处理器,运行时系统分配线程到处理器上,当内核了解到一个线程被阻塞后,内核通知该进程的运行时系统,并在堆栈中传递一些线程编号和事件描述,然后运行时系统就重新调度其线程。通常,运行时系统把该线程标记为阻塞状态,然后再其线程表中取出另一个线程启动。当内核知道原来的线程又可以运行时,再一次通知运行时系统,运行时系统再进行判断是否立即重启线程。
在这个过程中,内核通过在一个地址上启动运行时系统,从而传送一些信息,这个机制称为上行调用,这违反分层系统内在结构的概念,通常 底层提供高层可调用的服务,而不调用高层中的服务。
进程之间经常要进行通信,正确通信需要解决三个问题,首先是进程如何把信息传递给另外一个进程,第二是通信过程中如何避免碰撞(例如两个进程对同一资源进行读写),第三是如何确保顺序。这三个问题也同样适用于线程间通信。
进程冲突
临界区
为了避免进程间的冲突,我们找到一些方法组织多个进程同时读写共享的数据。引入临界区的概念,我们将那些访问共享内存的程序片段称为临界区,在一个进程进入临界区后,就不允许别的进程进入临界区,这样在一定程度上可以保证避免冲突。
一个好的解决方案应满足以下几点:
首先介绍忙等待的解决方案,忙等待是指临界区外的进程不断检查是否可以进入。
屏蔽中断
我们可能在一个进程进入临界区后,立即屏蔽所有中断(CPU装聋),在进程将要离开时再打开中断,允许其他进程来访问共享内存。
信任问题,将屏蔽中断的权利交给用户不安全(如果进入后再也不打开中断就GG了),但是在操作系统本身是一项很有用的技术。
多核处理器中,屏蔽中断不会屏蔽所有的CPU,其他进程可能会使用没有别屏蔽的CPU操作共享资源。
使用锁变量
这是一种软件层面的方案,在进程中设置一个锁变量,当一个进程想进入临界区时,查看锁变量的值,如果是1(代表有进程以及进入)就等待直到值变为0。进程进入临界区后再将锁变量设置为1。
但是其实这个方案啥也没解决,当一个进程刚进入临界区后,还没来得及更改锁变量为 1,另外一个变量一看锁变量还是 0,一下子就进来了,这样临界区里面就有两个进程了,Boom。
严格轮换法
这个方案借用了轮换的帮助,对共享资源的操作是轮流的。定义一个锁变量 turn,turn 为 0 时代表进程 0 可以进入操作,进程 0 操作完之后,再将 turn 改为 1,然后退出。这个过程中进程 1 一直在检查 turn的值,发现变为 1 之后就进入,完成后再改为 0,让进程 0 进入。
这种方法中,等待的进程连续测试一个变量直至一个值出现为止,称为忙等待。用于忙等待的锁,称为自旋锁。
但是,当进程 0 在临界区完成操作后将 turn 置为 1,并退出临界区,此时按理说应该进程1 进去临界区表演了,但是进程 1 还在忙别的,等了好久才进入临界区。这不是耽误事嘛,该你了你还在忙别的。
因此,当两个进程的速度相差甚远时,轮流进入并不是一个好办法。
Peterson解法
这种耽误事的情况荷兰科学家 Perterson在 1965 年解决了,最早提出了不严格轮换的互斥算法。他将一个 interested 数组结合了进去,这个数组中存储了进程们是否想进入临界区。
例如一开始没有进程希望进入临界区,现在进程 0 想进入临界区,它将 interested[0] 设置为 true 并且 把 turn 设置为 0,只有当 interested[1] = false(别人没兴趣进来) 并且 turn = 0 时,进程0才能进入成功;进程 0 离开时将 interested[0] 设置为 false。
当两个进程 0 和 1都想进入时,它们将分别设置 interested[0] = true, interested[1]=true, 并将自己的进程号 存入 turn,假设进程 0 先存了 0 ,然后就进去了,接着进程 1 有把 1 存入 trun,此时因为 interested[0] = true ,他就无法进入,只能在外面一直等待,直到进程 0 退出(退出前设置 interested[0] = false)进程 1 才能进入。
TSL指令
现在我们考虑硬件层面的指令,在一些多处理器的 计算机中,会有一条指令 TSL RX,LOCK 称为测试并加锁,它将一个内存字 LOCK 读到寄存器中,然后在该内存地址上存入一个非零值。
执行 TSL 指令的CPU将 锁住总线,禁止其他 CPU在指令结束前访问内存。而前面讲到的屏蔽中断,并不能屏蔽别的处理器。
以上方案虽然不错,但还是没有解决忙等待的问题,为了避免资源浪费,我们可以先让等待者进行睡眠(调用 sleep),先将他挂起,直到另一个进程将其唤醒(调用 wakeup)。
举一个生产者- 消费者问题,也称为有界缓冲区问题,两个进程共享一个缓冲区,一个是生产者,负责将消息放入缓冲区,另一个是消费者,负责将取出消息。它们两个可以同时再缓冲区运行,当缓冲区存在的消息达到上限之后,生产者就会睡眠,等消费者从中取出一个或多个消息后再将其唤醒;同样的,如果缓冲区一个消息也没有了,就将消费者睡眠,等到生产者生产几个消息后再唤醒他。
这种方式在一定程度上解决了忙等待的问题,现在如果不需要进程的话,他就可以先睡一会了。但是现在考虑一种情况。现在缓冲区消息数量为 0,消费者准备睡眠,此时生产者启动,发现现在是 0,他推测消费者正在睡觉,于是生产一个消息之后,调用 wakeup想要唤醒消费者,但是消费者此时并未睡眠(准备睡,但是还没闭眼),因此唤醒失败,过了一会消费者就睡了,而生产者稍后将缓冲区填埋后自己也睡了,这样两个进程都将永远睡眠下去。
互斥量
如果不需要信号量的计数功能,可以使用他的一个简化版本,称为互斥量,可以用来管理共享资源,或者一小段代码。
快速用户区互斥量 futex
在进程进行一些同步操作时,需要陷入内核完成,在开始时和退出时都要陷入内核去检查是否有进程在里面或者是等待。当并行进程的数量增加,有效的同步和锁机制对性能而言非常重要。在竞争激烈,等待时间较短时,使用自旋锁会很快,这时阻塞等待进程,仅当锁被释放时让内核解除阻塞会很有效。而竞争的激烈程度是难以预测的,如果刚开始竞争并不激烈,那么频繁的内核切换将花销很大,我们需要减少不必要的内核陷入。
Futex 实现了基本的锁,并且除非在迫不得已的情况下才会陷入内核,这样做改善了性能。Futex 包含内核服务和一个用户库,内核服务提供一个等待队列,允许多个进程在一个锁上等待(将进程放到等待队列中需要系统调用),这些进程均被阻塞。因此,在没有竞争时,futex 完全在用户空间工作。而这些进程共享一个锁变量,线程通过减少并检验来夺取锁,如果发现锁被人持有,就使用一个系统调用将线程放在内核的等待队列上。而进程使用完锁后会通过原子操作“增加并检验”来释放锁,并检查结果,看是否仍有进程阻塞在系统队列上,如果有就会通知内核可以对队列中的进程接触阻塞。
总的来说,在没有锁竞争时,完全不需要陷入内核。
pthread 中的互斥量
pthread (POSIX的线程标准)提供了许多可以用来同步线程的函数。其基本机制是用一个可以被锁定和解锁的互斥量来保护每个临界区。线程如果想进入临界区,首先要尝试锁住相关互斥量,如果发现互斥量已被加锁,就被阻塞,直到该互斥量解锁。与互斥量相关的函数有 pthread_mutex_init (创建互斥量) pthread_mutex_destory(销毁), pthread_mutex_lock(加锁,失败的话阻塞调用者)pthread_mutex_trylock( 尝试锁住互斥量,失败就返回错误码)
除了互斥量之外,pthread 还提供了 条件变量,用于线程由于一些条件未达到而被阻塞,pthread_cond_wait 用于阻塞线程以等待另一个信号,pthread_cond_signal 和pthread_cond_broadcast 分别向另一个或多个线程发送信号来唤醒。
互斥量和条件变量经常一起使用,互斥量用于锁住或解锁一个互斥量,而条件变量用于使线程阻塞以等待信号以及发送信号唤醒线程。
即使有了信号量和互斥量,还是不能完全保证进程间通信完全不冲突,在一些情况下,会发生死锁。
一个管程是由过程,变量,数据结构等组成的一个集合。进程可以在任何需要的时候调用管程,但不能之间访问管程内部。管程的一个重要特性是在任意时刻,只接受一个活跃进程,这样可以有效的保证互斥。
典型的处理方法是,当一个进程调用管程后,管程的前几行代码检查是否有活跃进程正在管程内部,有的话调用线程被挂起,如果没有就进入。但是只解决互斥问题并不足够,还要保证管程中的进程在无法运行后被阻塞,解决的方法是引入条件变量 以及相关的两个操作 wait 和 signal,当一个管程过程发现它无法继续运行时,就在 某个条件变量上执行 wait 操作将自身阻塞,然后将一个在管程之外等待的进程放入管程中。而那个进程可以在完成任务后,调用 signal 通知另一个阻塞进程,signal 语句可以简单的放在管程过程的最后一条语句。
wait / signal 和 sleep / wakeup 虽然很像,但是有一个关键的区别,后者之所以失败是因为一个进程唤醒另一个还未睡眠的进程,导致信号丢失,而管程的互斥性保证这一点不会发生。
但是管程只是一个编程概念,是编程语言的组成部分,编译器知道它们的特殊性,因此可以使用不同的方法来处理对管程的调用,写管程的人只用将所有临界区过程转化为管程过程即可,无需担心别的。管程的应用是较为局限的,因为大多数编程语言都没有管程。
与管程和信号量有关的另一个问题是,这些机制都是用来访问公共内存的一个或多个 CPU 上的互斥问题的,而现在企业级应用都是具有多个 CPU 分布式系统,每个 CPU 有自己的私有内存,它们之间通过局域网连接,那么这些原语将失效。可以得出结论,信号量太低级了,而管程只能用于少数几个编程语言,这些原语均为提供机器间的通信方法,所以需要其他手段。
消息传递
上面提到的其他手段就是消息传递,使用两条原语 send (dest, &msg) 和 recieve(src, &msg)。前一个调用向一个给定的目标发送消息,后一个负责从一个指定的源接收消息。
当计算机是多道程序设计系统时,通常会有多个进程或进程同时竞争CPU,选择去执行哪一个进程叫做调度。
进程行为
几乎所有进程的 I/O 请求和计算都是交替发生的,如下图所示,将多数时间用于计算的称为计算密集型,用于I/O操作的称为 I/O密集型。随着 CPU和内存速度差异的增加,未来对 I/O密集型进程的调度似乎更为重要。
如果运行I/O密集型进程,应让其尽快得到计算机会,以便发出磁盘请求并保持磁盘始终忙碌。
何时调度
第一,当进程完成工作退出时。
第二,当一个进程阻塞在I/O和信号量上,或由于其他原因阻塞时。
第三,在一个I/O中断发生时。
调度算法
如果硬件时钟提供一定时间间隔的中断,可以在每个时钟中断时进行调度。
根据如何处理时钟中断,可以将调度算法分为抢占式调度算法和非抢占式调度算法,前者挑选一个进程,并设定一个进程运行的最大时间,如果超过这个时间进程还在运行就将其挂起,挑选另一个进程运行。后者挑选一个进程运行,直至该进程被阻塞(阻塞在I/O上或等待另一个进程),或者直到进程自动释放 CPU,在时钟中断发生时不会进行调度,
不同的环境需要不同的调度算法,这里的环境可以划分为3类:
批处理系统中不会有很多时效性要求高的用户请求,非抢占式算法通常是可以接受的。设计调度算法主要需要考虑系统的吞吐量(单位时间作业数),周转时间(批处理任务从提交到终止的时间),CPU利用率。
先来先服务
按照进程请求CPU的先后顺序来决定运行次序,这种方法简单易行,也具有一定的公平性。但是,这种方式有一个很大的缺点,现在假设有一个计算密集型的进程1,他运行1s然后去读1次磁盘(花费1s),接着很多I/O密集型的进程运行了,它们每个需要读1000次硬盘;过了1s之后,进程1又开始使用CPU运行1s,紧跟着I/O密集型的进程再运行。这样一来,每个I/O密集型进程需要花费1000s才能完成操作。此时如果有一个抢占式调度,每10ms抢占计算密集型的CPU,那么I/O进程将在10s内完成。
这就好比一堆人吃饼,每个人先拿一个,吃完了再拿,大多数人拿饼1s,吃饼1分钟,而有个哥们拿饼1s,吃饼也1s,吃完就拿,吃完就拿,吃的比其他人多的多。
最短作业时间
适用于运行时间可以预知的另一个非抢占式的批处理调度算法。当队列中有多个进程等待运行时,调度程序选择预计运行时间最短的作业来运行。
这种方法的优点是可以减小平均等待时间,假设现在有4个作业,分别用时8,4,4,4。如果按照先来先服务运行,它们的周转时间分别为8,12,16,20,平均为14分钟。如果这种方法,将次序变为4,4,4,8,它们的周转时间将变为4,8,12,20,平均为11分钟。
这种方法的局限是参加比较的所以进程应当是已经准备好的,同时可以运行的情况下。
最短剩余作业时间
这种方法是最短作业时间的抢占式版本,将当前运行的进程剩余时间也拿来比较,如果存在某个等待的进程其运行时间比当前运行的进程剩余时间还短,就把当前进程挂起,运行该进程。
交互式系统经常会有多个用户发送请求,为避免进程霸占CPU太久而影响其他进程使用,抢占式调度是必须的,在设计算法时要考虑响应时间,以及均衡性(尽量满足用户的期望)
轮转调度
最古老,简单,公平的调度算法,给每个进程分配一个时间段,称为时间片,允许进程在该时间段中运行,如果在该时间段内进程完成或者阻塞,CPU立即进行切换,如果超过时间段还未结束,就剥夺CPU分配给另一个进程。调度程序所做的就是维护一张可运行进程表,当一个进程用完他的时间片后就被移动到队尾。
而进程的切换,也叫上下文切换是需要时间的,假设时间片为4ms,上下文切换为1ms,则CPU 20%的时间浪费在管理开销上。因此,适当的增加时间片长度会提高CPU效率。但是如果时间片太长,一些短的交互请求的等待时间会增加,通常20-50ms是一个比较合理的折中。
优先级调度
轮转调度的假设是每个进程的优先级相同,但是现实中总有一些比较重要的进程需要先被执行。根据情况的不同,进程执行过程中可以采用抢占式或者非抢占式的方法进行调度,可以将进程根据优先级分为几类,在每一类上采用轮转法分配时间片。
多级队列
为CPU密集型的进程设置较长的时间片比频繁给他们分配很短的时间片更为高效。而另一方面,长时间的时间片又会影响响应时间。解决的方法是设立优先级类,属于最高优先级类的运行1个时间片,一次类推,优先级越低,时间片越长。进程运行一次就降低一个优先级。
举个例子,假设一个进程需要计算100个时间片,起初被分配1个时间片,第二次被分配2个,然后4个,8个,16个,32个,最后一次他只使用64个时间片中的37个即可完成作业。该进程需要7次交换,远远低于轮转调度的100次。而且,随着运行频度变慢,可以为短的交互进程让出CPU。
最短进程优先
类似批处理系统中的最短进程优先调度,降低进程的平均调度时间,这里的问题是如何估计进程的运行时间,一种办法是根据进程过去的行为进行推测,执行预计时间最短的那个。
通过测量当前值和先前估计值进行加权平均而得到下一个估计值的 aT0 +(1-a)T1 ,这种技术称为老化。适用于许多预测值必须基于先前值的情况。
保证调度
这种算法,保证n个进程运行的情况下,每个进程获得CPU处理能力的 1/n。系统必须跟踪每一个进程自创建以来已经使用CPU的时间与CPU运行时间的比值,根据这个比值与1/n的差距来调度进程。
彩票调度
上述保证调度虽然挺好,但是难以实现,可以采用更为简单的彩票调度来实现。每个进程拥有一些彩票,CPU在做调度决策时,随机抽取彩票,拥有该彩票的进程就获得CPU资源。这样在很长的一段时间内,进程得到CPU的概率是几乎一样的。
公平分享调度
当我们把进程的归属(用户)也考虑进去时,如果一个系统有两个用户,每个用户都保证有50%的CPU时间,用户1启动9个进程,用户2启动1个进程,我们就不能简单的使用以上方法。
用户级线程:内核并不知道有线程的存在,还是对进程进行调度,而进程内部的线程调度程序来对线程进行调度,可以是以上任何一种。
内核级线程:内核选择特定的线程运行,不是必须考虑该线程属于哪一个进程,
区别:
1、性能,用户级线程切换需要少量的机器指令,内核级线程切换时需要完整的上下文切换,修改内存映像,使高速缓存失效。但是好处是,内核级线程阻塞时不需要像用户级线程一样将整个进程挂起。
2、用户级线程可以定制线程调度程序,选择更适合应用的调度策略。
1965年,Dijkstra提出并解决了这个问题。哲学家的生活只有吃饭和思考两个问题,现在5个哲学家坐在圆桌上,每个人面前有一盘通心粉,相邻连个盘子间放着叉子,每次只能拿一个叉子,拿起两个叉子后才可以吃饭,吃完饭把叉子放下继续思考。现在需要写出一段描写哲学家行为的程序,并且要求不造成死锁。哲学家问题对于互斥访问有限资源的竞争问题十分有用,
天要下雨,人要吃饭;不管再怎么想,到了年龄,就算不结婚生子,但还是得找工作。
不讲什么本人勤奋热爱好学、吃苦耐劳这套老掉牙的事了,这玩意就是你情我愿,一拍即合,不行就拉倒,谁也没有必要低声下气,彷佛占了什么便宜,双向选择嘛。
招聘网站一个个看(不太信任,听说骗子挺多,还是需要线下跑来跑去,还可能被第三方公司外包,扯皮都没法扯,精力都耗没了),什么一面二面,还要花时间背没有用的题目,互相试探,装的很牛的样子,然后等通知;或者一个个线下到处漫无目的地找;除以上途径之外,我还想在各大网站上发布信息,希望能够找到合适的工作。
好吧,说实话,别看我好像挺拽的,其实我已经没有任何信心主动尝试了,质问还不够多吗?四肢不勤,五谷不分,无一技傍身,混的好惨啊,但敲代码挺幸福的,也没精力也不想干别的了。
若你想要了解我掌握的东西,那你看看我写的这个就行,也不会超出这个内容太多,忘了很正常,看看就捡起来了,我又不是电脑,没必要一直存储到脑海中,超时就丢掉。
要求:
工作地址:离湖北越近越好。
工作内容:与电脑相关就很好,我不想丢失熟练度。
工作要求:
1)连续工作半小时 ~ 1 小时,因为现在码字,眼睛不是很好,很干涩需要流泪才能缓解,需要休息 5 分钟远眺;我常常使用番茄钟,提醒自己该休息了,以免精力不足,影响明天。
2)可以接受重复性劳动,时长不能超过 9 小时;禁止夜班,没得商量。为了身体着想,说不定工资还不够看病呢。
公司气氛:不要勾心斗角、人人胡思乱想;不要官僚作风、气氛紧张;不喜团聚。
工资要求:实习期间工资 3000 以上。
个人缺点:
1)手笨,不会系绳子,只会打蝴蝶结与死结。
2)习惯沉默寡言,不会烘托气氛。
3)英语不好,我尝试过好多次了,暂时办不到,以后有时间再试试。
如果确定要为您办事了,我会在入职前将鱼放生,所以请不要耍我玩。
补充一条,禁止传销、坑蒙拐骗其他人、等其它犯法行为。
你如果有意向,可以列出岗位的技术相关要求,若我有不熟悉的,我直接自学完了,再到你那来,给你干活去,这对我小菜一碟。
声明:天下没有不散的宴席,人都有分别的时候,好聚好散;请直接提出来,别耍阴谋,调来调去,或突然增大压力。
本人联系方式
(有人问,有工作就不错了,怎么还提这么高的要求?漫画附图:)
PS:这要求还算高?直接免费打工,用爱发电,饿死自己,让其他人引以为鉴,变得冷漠,好吗?
当然我很清楚,能够看到这篇文章的,要么是小白急于寻找信息,要么是好奇,因为真正高手、HR 搜也不可能搜这,也绝对不会看到这篇文章的。也不用掺杂其它情感,图一乐就好;我这啰里吧嗦的,这写了也是白写,所以没有寄托太多的希望;再说了,这毕竟不是专门的招聘网站。
工作情况
物业维修员:2019.10 ~ 2020.5
状态:待业中
说明:最近被催着找工作,能敲电脑就行;只是怕又头脑一热,选错了,又浪费 3 年;当然最主要的原因是还有一大堆的知识还没整合完,小鱼苗还未长大,需要天天收集活食,不太放心啊;对,你可以认为是一种逃避外界的借口,无所谓。多你这一句话,暂时还压不垮我。
妄想的工作分支:送餐员、流水线、文员、Java 初级工程师、渔场、志愿员…
致谢
首先感谢父母给我一个好的身体,感谢母亲耐心的支持,感谢永远的 36 岁,永远的 42 岁,永远的 12 岁,那是少有的幸福时光。一点痛苦就可以掩埋无数的平淡时光。
其次感谢遇到的挫折与不堪,及时纠正我前进的方向。好吧我还是讨厌它,为什么我总要给自己的生活添堵呢?
这些在网上搜集的资料,如有侵权,烦请告知。
编者:cqh
2022 年 3 月 4 日,于湖北安陆
勘误
笔者也只能算是新手,学识尚浅、水平有限,有些抽象、底层的东西以目前的功力无法一眼看破,找不到合适的方法去验证结论,只能是凭第一感觉得到具体的规律,所以也可能是想当然,看法比较片面。你就当成强行解释,笑一笑吧,对身体好。
部分解释可能不详细或不清楚(词不达意),如果你有更好、更通俗易懂的语言,欢迎留言指出。
在阅读文章时,请你时刻持有一种质疑的态度,这样既能帮助自己思考,也能发现我文章的不足之处,如果文章中有什么错漏的地方,还请不吝啬指教与批评,十分感谢!
若有帮助,会将你列入鸣谢名单中。
书中源码地址
本人专科毕业。我始终认为只有自己喜欢的才需要学,忽略了高中这不是专项发展,而是筛选人才;那么多的人,企业正好设置为本科门槛可以节省筛选时间;此外你通不过本科,企业难道不会怀疑你的学习能力有问题?既然是为了赚钱,那为什么不选更好的?人才多的去,谁稀罕你这一个。
我倒是没有什么后悔的,因为学历与钱对我而言不太重要,还比不上自身学会了写代码的那种喜悦,只是觉得大多数人经过 18 年的学习,每三年的转眼间淘汰了一半人,估计都流向工厂的流水线了,太浪费了。说好听点,成绩不太好的,进入技校,学习本领,直接对接企业,好好动手、做事,成为一线工人,读书好的进高校做理论好好做研究、理论,互相弥补。说难听点,我觉得不大现实,都下去了,还指望公平对待,齐头并进吗?至于指望未来进入技校后再努力,有这个本事,还至于掉下去吗?
还是不得不承认,学历高,见识的东西就更多,学习能力强,能够打下更坚实的地基,就算现在一无所有,也能东山再起。
我想起了,上半年看到的一句话:“我们的教育生产理想主义者,再由现实击碎他们的幻想,并将这种重塑称之为成长。每当我回顾我所接受的教育,我总感觉到被欺骗的愤怒,到现在还是无法释怀。”
一直笑着说大不了回家种田,但其实要是真的能够维持生活,没有人愿意背井离乡,出去打工的。我之前提到过滞后性,上一辈人因为这种滞后性,吃够了亏,于是只让我们专心学习,自己在外辛苦打工,进厂或在工地成为耗材,承受所有的风险,只为了子代不再重蹈覆辙,以为我们考上大学了以后就能赚很多钱,不用进厂或在工地遭殃了,终于可以享福了,却忽略了其它方面。
我们都以为学成了,考上了好大学,也许前途就顺了。但总还有一半人被淘汰了,比如我;父母还是抱有期望的,至少是个大学生啊!至少比我们强吧,结果期望越大,失望也就越大,到头来终究成空。
其实学校教的东西可用的很少,大多数就是纯粹应付考试。等上了大学后,被忽略的其它方面,弊处就开始显现;上一辈人突然觉得这么聪明的大学生,读了这么多年的书,这点生活常识都不懂?人际交往、生活常识、整理内务、洗衣做饭、修电脑啥都一团糟?你们在学校学了个啥?换我来吧!读书有啥用!废物!你们 90 后当家了,这个社会要完蛋!
我不太在意,我知道他的局限性,他所在的小地方,也就只能看到我,误以为我就是大学生的缩影。但是网上有才有能力的人多了海了,否则你们找工作怎么这么难找。当然工厂、销售…等岗位还是挺需要人的,可惜我并不擅长,也就敲敲键盘喽。
我认为有这些高智商的人材们,尤其是特别努力勤奋的,社会只会越来越好,但是对自己的命运不是特别乐观,或许这是另一种形式的物竞天择吧,但是我真的很讨厌争、去比,所以每次都主动落在后面,能轮到我自然好,但如果资源提前光了,重新换个队伍排吧;如果没有自己的世界会变得更好,也不知道是开心呢还是寒心,既然不需要我,我也看不到身上有什么可以交换的利益帮助到别人,那还召唤我干嘛,激起好胜心,衬托别人的优秀嘛,又不是养蛊,难怪基因还能流传来下,呵呵。
我希望以后不会固步自封,局限自己的认知,觉得自己经历过这么多的事情,可以一言堂,狂妄地自以为看清了一切,断定周围人的秉性。因为经验有时效性,且与个人息息相关,在别人身上不一定适用。传递的观念如果别人不听后吃亏掉坑,我就在旁边暗笑,那样太可怕了,那说明我已经变质了,经验此时反而束缚住了我前进的脚步。
警告自己的一句话:我知道人都会变,可是当你看到这曾经写下的这句话,如果觉得很幼稚可笑,算了,不想前进了,就说明你已经融化了。那么狠狠地抽自己,往死里抽,别让我瞧不起你,你欠我的。我现在拼死累活地,下决心,不是为了让现在的你心安理得的阻碍其他人的梦想,嘲讽其他人,也不是让你吃老本,坐吃山空,别以为这是理所当然,好好想想自己该做什么,还是在楼下打麻将与其他人夸天?
小学时都想当什么科学家、医生、警察之类的,唉,现在想想简直就是做梦,能活着就不错了,哪有这个能力。
当初高中毕业,选专业,认为新能源汽车发展起来了,也可以保护环境啊,于是特别天真地就选了此专业。
当时实习时来的都是接插线、黑白班做饲料、卖挖掘机、开叉车…尤其看到要求男女不限,18 ~ 50,身体健康…沉默,我这时才明白自己早就已经 out 了,到这来只是将噩耗延迟而已,其实刚进大学时觉得完了啊,时间一长,如同温水煮青蛙一般,渐渐习惯了自己的处境,不要觉得扎心就视若无睹,假装身边都是好事。
应该事先多看看东西扩展一下视野,或许可以认清自己,然后挣扎一下;不禁怀疑我到底这 18 年的生涯到底学了什么?混成这个样子?竟然不知道在简历添些什么东西,热情开朗?踏实能干?会求微积分?也不明白自己有什么优点,自己的价值在哪?凭什么让企业招聘我。再看看其它要求高的,不觉得我能够达到,别人说不定看不上,真是贱啊。
或许你看到很多视频教你如何夸大,人人都这样,你不变,就等同于落后了,但我做不来,主要是不想,或许再经历几次毒打,就可以沦为同类人了。
好吧,乌龟壳虽然保护了我不受伤害,但是一旦有朝一日,从壳中脱离,没有练成应对危机的本能,只能扑街。
因为 2020 上半年考了一个电工证与驾驶证,友每天恨铁不成钢,即使之前有多不敢,导致错失了机会,所以这次一定不能放过!于是如同赶鸭子上架般慌着选择了工作,貌似能扯上一点关系的物业维修,正遭疫情,每天都是抄水电表,没积累可用的工作经验。解封辞职后,想回到心心念的家乡舔舐伤口,好好休息,可惜我周围一个人都没有,尽管一切都没变,但还是变了,心中没法容纳其它了,无论人还是热爱,空空的;时间长了,出门偶尔被指指点点,越发绝望,觉得谁都不需要我,我的意义在哪?实力弱,处处都是地狱。于是开始养起了鱼,获得了一种原来还有生物依赖我的踏实感,如果有兴趣养鱼可以看看:
休息一个月后机缘巧合下知道了 Java,于是到处搜罗学习资料,跟着网上的博客与视频一步步来,哎!觉得希望来了,这有什么难的。
那段时间,父亲和亲戚不再问读书成绩的事了,时常问我学了什么名堂,答:我学的这个集合很厉害,底层用多种数据结构存储数据,你看这个双向链…停停停,别跟我讲这个,我听不懂,这么有用,什么时候出去找事?可以赚多少钱?答:额…,没信心啊…
期间为了方便翻阅和复习,加页码、加目录、记时间、正字复习、画星星、康奈尔…方法效果甚微。
所以以我为反例,别用纸质笔记,很不方便的。
(之前有人问我,5 个月怎么这么慢?其实我之前太贪心了,还想学数学、英语、物理…)
也不是没有人劝我,江山易改本性难移,固定的思维就像茅坑里的石头难以改变。每次听到劝导,又开始神经发作,万一呢?你到底怕什么呢?谁会吃了你?这是否已经成了本能?我想不通,也说不清了…
我的理智告诉我,我只是害怕未知,本能拒绝去尝试,害怕再次失败,又被人侮辱与嘲笑,尤其是年龄大了,没有试错机会了,只能尽力维持现状,一旦没有了父母的支撑,把我投入到大海中,要么四肢扑腾,学会游泳,要么淹死。说到底,我还是有很好的父母,坚实的后盾,实在太幸福了,所以才令人感到如此悲哀。再结合到三和大神、26 岁成人被饿死之类的,我能理解亲戚他们的想法。算了,不说了,混成这个小孩模样,也是没谁了,希望能在饿死之前,主动寻求改变吧。没想到还真自证了自己初中时的想法,讽刺啊。
觉得学的也差不多了,开始看招聘,清一色的本科以上要求,这还玩个毛啊。再从网上看看题目,倒是不难,但想流利的说出,还是要背;语文、英语对我还是有点难,由于耳朵问题,只习惯看字幕,真不想把时间花在这无用的试探之上。说到底,我的信心一直被摧残,没被培养起来,一做事就放下手头的事跑过来看我,指指点点,说这不行那不行,不停地被否定,最后直接推开替换了我,一说话就被认为是借口,为什么别人行而我不行?对啊,我也纳闷这到底是为什么。所以畏手畏脚,一想到工作就躲避,哎呀都是我不行的,干不了,主动失去信心,下贱自己。那么别人看到这个样子,没有一点正能量,只会让现状越来越坏,犹如囚笼之兽。现在回想起来,这本来就不难,小事一桩!为什么非要挫折教育呢???究竟经历过什么事才会认为这是正确的做法?是不是我视野窄了,看不到背后的良苦用心?
得到一个规律:不犯错,必败事;如果小时候文文静静,逆来顺受,畏手畏脚,被框在自以为的规矩下,不敢尝试,看上去很听话很乖;但年纪大了,躲得了一时,躲不了一世,没有小错带来的经验,将来必定踩坑,成为平庸的人;这虽然不是必然发生的,但是概率很大,常在河边走总有一次会湿鞋嘛。小时犯错相比大时犯错,周围人包容度更高,所以建议小时多尝试。
受限于学历,所以我降低了要求,不得非要与代码搭边,随便啊,别进工厂黑白班、天天 12 小时,我还不想猝死。你们如果有什么好的渠道,智联、前程、脉脉…欢迎交流啊!
我觉得是基础没打好,也许是哪里走错,之前学的不够系统,又把 JavaSE 内容看了一遍,尚硅谷、动力节点、狂神说…,收获不是很大。
终于下定决心,这 Java 内容之多,之繁杂,总得有人要整理一下节省小白的时间,稍微扑腾一下吧;为了帮助和我一样的人,避免踏入同一个坑,开始本书的第 1 版制作:
唉,我平常喜欢在小路上慢悠悠地走,轻松自在,没想到变成了赛道,真可惜。
(当然现在知识忘得差不多了)
当时正是过年,前前后后忙了几个月。又被打击了一顿,说我在家里游手好闲、不学无术,不务正业,试过辩解,被认为只晓得找借口,是废物一个,在村里都不好意思说,不敢走亲戚,抬不起头,对外统一口径是我好高骛远,只晓得在家里玩,那么我也就没有什么可以说的呢,我不明白这是在激励我还是在保护我呢;每当别人问起我的年龄时,是否还在上学,总是感到脸上一阵青一阵白十分羞愧,无力感萦绕在心头阴魂不散。此时负标终于超过负荷,被最后一根稻草压倒,期间强行振作,努力维护日常作息,又被说年轻人还是没有被锻炼到,还是要多给点压力锻炼下,否则太脆弱了,心理承受能力太差,连这点打击就把你压垮了,去做销售扭转下性格就好了,挺适合的。终于压不住内心的痛苦崩溃了,开始自暴自弃,为什么所有的评价都认为只有我这么废?算了吧,说的对啊,我的确没用,还学什么啊,都卖了吧,我实在太脆弱了不堪一击,整个人又坏又蠢,估计就连小学的我就瞧不起现在的自己,不搞了,自闭中;眼泪不能流,声音不能出,打碎牙齿往肚子里呜咽…男人!男人嘛,男人!你这么大个人,怎么还跟小儿一样,好意思吗?没希望了,一生已经毁了。
但是过了一段日子后,越看越觉得这个笔记不对劲,写的这么粗略,这是给自己看的吧?新手能够看得懂吗?强行驱动自己,做事必须有头有尾,还是续了一根弦。在此期间,我明白了既然寻求人这种生物的认同十分地困难,那么还不如把精力放在代码、鱼、自然身上。有人说自然与这些生物有灵性,我不否认,可是它们的灵性如果达到了人的高度,假如我散步去了另一个地方、今天没有喂鱼…它们会不会在心里扯着喉咙喊:“为什么不到我这玩!为什么今天不喂我!!”那我该是什么表情?是不是比与人打交道更累?
当时又看了韩顺平老师的课程,他总结的学习方法很不错,先 demo 再写注意事项。然后由此编写了第 2 版:
好,没关系,大不了重新开始。
我现在想明白了,去追赶那些前言技术,学习语法,如何使用,只会流于表面,疲于奔命;干脆放弃掉,重新开始。我觉得就连 Java 语法,也变得不太重要,毕竟只是背别人定义的规则,还是表面;但是要写程序,没有办法,于是就有了语法入门篇。
根据纸质资料和粗略的第 1 版,以及网上的博客资料,拼拼凑凑得来了第 3 版,至此只完成到集合部分。并且我还是不满意,决定抽出时间,继续重置。
现在又要看最开始的老版笔记重新写一遍,做事有始有终,不能轻言放弃,爬也要爬到终点!没有什么是不可能的(Nothing is impossible),即使这份感情被背叛过千百次。还好现在没工作,否则抽不出时间写。由于删了之前的博客,有很多都是后来在最初版的基础上修修补补地,可能有很多疏漏、没来得及添加的、知识变异了的,恳请大家提出宝贵的批评和建议,以便改正。学习路线就按韩老师的来,先 demo 再声明课堂注意、出题目,按部就班的点还是挺不错的。
2022.3.11
接受现实,痛定思痛,干脆抽出时间,整理曾经写过的纸质笔记与博客,为尚未踏出校门的同学节省一点时间。
有的地方根本没必要学,直接复制粘贴看看 API 就行,没啥技术含量的。对于那些性格内向的人,心里有很多内容与墨水,但嘴里吐不出话的人,我特别能够理解你的苦衷,珍惜校招吧,避免毕业就是失业的尴尬局面。
有些人的确很聪明,在这里我不想扯勤奋与努力,以前也讲过,这只是表象,何况对于有些人也真的很难,考虑到通用性,内容稍微细一点,不要嫌我啰嗦。
我已经很知足了,阳光、空气、可以动的四肢、能计算 1 + 1 的大脑,没用什么遗憾了。对我而言,健康远比时间、金钱、技术重要。不对,这该死的技术,这抵挡不住的魅力啊!!!
真的好怀念魔兽,如果阿尔萨斯王子没走屠杀线一定会有美好的结局吧。
2021.7.4
经过一段时间的摸索中,得出了以下结论,希望对新手有帮助。
1、删除无效的软件(打造合适的环境)
比如一直让你刷刷刷,停不下来的。因为你每次刷,都在期待下一个视频对你有用,但很大的可能只是满足了你的多巴胺分泌。
上瘾后不要责怪自己,想办法清醒后把这些触手可及的东西,不管是卸载、还是关闭推送、扔在角落…尽一切可能不要让它来打扰你;如果你是因为没有事情,好无聊,看这些来打发时间,那就找一些其他事情吧,如散步、健身、看书什么都可以…
这种大量占用时间碎片,令人上瘾的软件,可以说是一种毒瘤,我想不通为什么要研发它,钱真的很重要,但也不至于这样吧。
我说过人就是个石头,现在看看销售营销等一些手段玩弄心理,越发坚定这个想法;我们能做的只不过是别让那些外力推动自己。
2、工作与学习之间的平衡
公司都是重复性劳动,没有实际上的经验提升,还要担心上级领导的试探,同事的打压,构建话术。下标后自学也只能学习 1、2 个小时,并且还不包括动手尝试的环节,能够学到手的知识十分浅显。等学完,天都换了。
并且公司本质上是私人组织的、有了好点子想变现、以盈利为目的的结构;你想想你要是老板,谁不行直接替换掉,反正人才多的是,为何还要等你慢慢成长,真以为自己是潜力股吗。
但是辞职也不可取,长时间在家,没有了生活来源;走在路上还要被婆婆们嬉笑。
此外亲戚们都不会理解,最亲的人也会骂你不中用,你给他也讲不明白,还会被觉得十分可怜。一开始还可以打哈哈,说自己已经毕业了,在学习编程;但之后呢?这条漫长的学习之路,不同于进厂教教就能直接上手。
我想提醒你,你是否也感觉大学的课完全没必要上,但我们也许还如同高中一样,按部就班,讲什么就听什么,那么到了毕业就等于失业,你应该抽空把自己的爱好发扬光大。如果等到上班再学,其他人会怎么想?
结论:请好好珍惜大学的时光,那是唯一适合自学的时候。否则你要承担额外的精神压力,扛不住人就废了。
3、适当约束自己的好奇心
不要看到什么都想学,什么都想买,一直在搜,知识太多,你学不过来的。你先在网上搜索,比如后端的整套知识点,按顺序来,一心一意,一套教程为主,有疑惑的再去别的地方比对。不要没事就搜索一大堆资料收藏,又不开始,资料一定要精简,那些看上去有用的知识但短期用不上的,直接取消收藏。等你到了这步,再找资源,别做松鼠。
不要背代码,要掌握原理,方法可以到 API 文档上查。之前基本都是概念上的东西,理解就好了,但学到集合、IO、常用类如 String,只背方法名一定会消灭你学习的兴趣。
如果学习资料抛出一大堆让人心痒痒的新名词,操作不讲规则与原理,没有容易理解的例子,只是像背或粘贴似的敲打代码以及一大堆的命令控制流程,那么我劝你趁早跳过,用时再翻阅。
4、管理好精力
并不是一直在同一个地方枯坐,工作效率才会高。
要合理分配精力,因为精力是有限的。学习并不是生活的全部,如果你整天扑到学习上,只会感动自己。随着精力的消耗,自控力的减弱,一定会在某天突然崩掉,开始变得什么都没有兴趣,行动力拉到最低,即使强迫在学,也只是枯坐原地,享受着左耳进右耳出的枯燥感。
早起别熬夜,每天一定留至少 30 分钟的时间午睡。(为了第 2 天的精神良好)学习时推荐使用番茄钟,每过半小时就休息一小会,合理分配精力。(休息时不要看电子产品与动脑筋,要适当远眺)
5、学好英语
没什么说的,英语真的很通用很重要,为了阅读懂优质的国外资料。看着机翻的我太拉跨的,简直是哑巴英语。学不会也没关系,就算关了一扇窗,把开这扇窗的力量用到别的地方去,一定不会浪费的。
6、必学的知识点
从大多招聘岗位的要求取出交集:
剩下的知识,应聘意中岗位时再选择性补全。
7、选择书籍还是视频
视频时间看完所需时间更长,但可以一步步来,如果章节内容划分合理,每个视频时常合适,学习者更轻松完成每个目标,掌握自己的进度。适合初学者。
书籍花费时间较少,但经常有断节之处,初学者搞不明白缺少哪一个环节,看着晦涩难懂的文字,翻不了几页就草草放弃,适合耐得住性子的人。
8、不要过分追求完美(承认自己的不足之处)
想做就直接放手干,不要计划的那么周全,稍微一有变动,就放弃目标,想明天再做。是吧,别觉得只有从容不迫、不慌不忙、按部就班地才叫做事,而达不到自己的心理预期就不做了,大多数人都是计划赶不上变化,被搞得灰头土脸的。
另外人都是有惯性的,如果设置了太高的目标难度,只要有一天没坚持下来或不想做了,那么最终结果一定是放弃。
这不禁让我怀疑,以前对生命的定义。我本来以为生命是一种奇迹,我感到自豪,超脱于物质之上;比如从下坡推一个石头,它只会毫无疑问的滚落下去,而我们可以做出反应。
但经过太多的事后,我发现生命的本质与死物没有太大区别;生命就像是一台精密的操作仪器,如同电脑、机器人,只不过比它们先进点。
接收输入做出反应,将应对方式与最终结果存储;等下一次事件再发生时,可以不断优化脑海中存储的应对危机的方法,达成自我学习的本领。
9、学会分享
第一,人人都有开始,你发出来了,别人才能纠正你的错误,避免成为井底之蛙。
第二,你又开始自耗了,不停地在脑海天人交战,一顿脑补:会不会万一发出来被人嘲笑怎么办?…于是藏着掖着,生怕别人知道,出丑,事情还未做,就想一系列的后果,别人有多可恶。我觉得世上还是好心人多,当然不要被零星几个恶评就忽略了大多数支持你的人。
10、关于努力与勤奋
有人经常说,要自律,要吃苦,要努力,才能成功,你看看这些成功人士都是这样…努力才能得到一切,才能成功。但我抛出一个结论:努力与吃苦,并不能成功,也不能改变命运。
他们忽略了一个东西,自律、吃苦等只是个表面行动展现出来的结果,并不是成功的原因。比如你打王者,技术很菜,但是你就想升段位,不用别人提醒,开了一把有一把,一直连跪,日夜颠倒,身体早就向你警告了,这种违反本能的行为真够自律的。不打一定不会上王者,打了无数盘由于技术太菜,也不一定能上王者。
另外无论是游戏、还是学习,多了总会令人厌烦,这不是真心喜欢,大多数人并不喜欢打游戏,这只是无声的对抗与放纵罢了。
如果你真心地想要完成某个目标,你不会觉得这是折磨的。再次声明,不是自律、努力才会成功,它们实际是想到达成目标,而自发控制自己身体机能活动的行为。
所以努力只是达成目标的一种手段;由于基因与环境很难改变,于是性格也几乎定型,形成了独有的接人待物的一套行为模式,感兴趣并为之付出汗水的也就那么几件,还要承受不理解;
之所以说“努力改变命运”这种只是安慰、激励自己的空话,是因为至少要给一点希望,好被利用,而不是自暴自弃,十分绝望,没有向上的动力;如果让“唉,都是自己不够聪明,天赋不好,于是就不努力了,让子代好好搞吧(甚至认为改变不了,都不要后代了)”的观点占了主流,那么原本有希望改变的人也会受到负面影响;
所以人们不太乐意听“唉呀,只是你天赋好”之类的话,无法改变的事实对其他人是沉重的打击。这就是不要将过错、天赋归咎于自身,而是归因于经验水平不足,认为只要努力就还有希望进步。
我之前都说过部分人根本就谈不上拼努力与天赋,正常学习不放弃就 OK,没有必要与头部的那群神仙比;刷熟练度而已,当然在没有专家指点迷津的情况下,自己总结出的经验(甚至还没有,只是靠肌肉记忆)很可能不完善,很快就会达到瓶颈,再无寸进,这时就比拼天分与悟性了,但不管怎么说总比从来都不碰强。
“努力才能成功”这种原意激励人给以力量,逐渐成了合法霸凌其他人的手段,潜台词被恶意解读成“不成功就是你还不够努力”、“不成功就是你在假努力、无效努力”、“什么比不过人,就说你还不够努力”,偏偏还难以反驳,一说就是找借口,只能怀疑自己;得,由此观点诞生了一个又一个诱捕器,看着似乎有道理,其实空空如也。
自从这句话变味后,努力似乎慢慢变得廉价,成为人最基本的底线。
那么我换一种说法:“知识就是力量”。
友情提醒:全身心很耗精力,记得番茄钟打断此状态(半小时),休息的时间眺望远方,不要看电视、玩智能设备,否则越来越累。
11、学完要多久?
如果你不复习,不怎么练,只看视频的话,最多半年。能够记住多少看命。
正常一年半(每天 8 小时以上不间断)
12、是不是很难?
相比越到后面越抽象,一环扣一环的数学,Java 其实还算好,小白也能调用方法完成工作,理解一下就行,屏蔽了底层如何实现的繁琐细节,看看 API 即可拿来用。
至于为什么一看就会,一敲就废?是不是我没有天赋?
说实话,这些东西不会就跳过,以后再补,只要学会调用方法,看看 API 就行。还没有达到拼天赋的地步,努力也无需拼,努力只是外表展现的结果,而不是因,若你感觉自己很努力了,很痛苦,就像我之前说的这样,你想想哪里出现了问题,是不是真的不感兴趣,居然会觉得要强逼自己,努力才会成功?想着人只有逼逼自己才行?
话说回来,不会不是真的完全不会,而是你看时觉得很正常,但一到做时脑海中缺少一些关键片段,甚至连思绪的头都没有,无法串联成珠,往往出错,其他人只不过是由于过往经历(熟能生巧)或者下自然地就补齐了这个漏洞。
没必要担心,如果你接触它的时间过长,会弥补的。不用特意寻找解决它的办法,多看看就行。(把同一个知识点学三遍差不多就熟了)
此外我觉得人略微笨些,是好事,意味着你能够帮助这世界绝大多数人,不会出现理所当然,而一些人却不能理解的事,知道哪里有槛,知道一些人哪里有误区。只要你走通了,其他人就能走通。
花自己的时间,让更多人节省了时间,值。努力活完短短的一生,将所得成果留给后代分享,人类真的是很了不起呢。
2021.2.11
本人才疏学浅,感悟还不够深,只能根据些许痕迹揣摩出背后道理。主要是臆想成分居多,如果有什么不对的地方,还请各位大师指点,大家一起共同进步。
另外希望把已建立的认知体系撕开一个口,推倒。包容,承认自己的失败,不要斗气就认这个死理,大不了掌握其它方法重头再来。
2020.6.13
内容导视:
内容导视:
看不懂就跳过,这里不是重头戏,说实话,挺无聊的,我也不是很懂,这根本不是初学者应该考虑的,直接跳过也没问题,但又不能不讲,否则感觉缺了点啥。其次我一直孤军奋战,没有评判体系,只能靠自己甄别好坏,难免有些遗漏。
Java 最早是由 SUN 公司(已被 Oracle 收购)的 James Gosling(詹姆斯·高斯林)在 1992 年开发的一种编程语言,最初被命名为 Oak,目标是针对小型家电设备的嵌入式应用,结果市场没啥反响。谁料到互联网的崛起,让 Oak 重新焕发了生机,于是 SUN 公司改造了 Oak,在 1995 年以 Java 的名称正式发布,原因是 Oak 已经被人注册了,因此 SUN 注册了 Java 这个商标。随着互联网的高速发展,Java 逐渐成为最重要的网络编程语言。
有兴趣查看以下文章,了解 Java 发展历史
此外 JDK1.5 与 JDK5 是一样的意思。因为比之前版本的变化大,以此作为区分,表示与众不同。就像美猴王自封齐天大圣,都是一个人(猴)。
此外还有 J2EE 、JavaEE,只是叫法不同,不必纠结。
JavaSE(Java Standard Edition):Java 标准版,包含核心的类库,主要开发桌面应用(如 Windows 下的应用程序)。允许您在桌面和服务器上开发和部署 Java 应用程序。JavaSE 和组件技术提供了当今应用程序所需要的丰富的用户界面、性能、多功能性、可移植性和安全性,并为 JavaEE 提供基础。
JavaEE(Java Enterprise Edition):Java 企业版,为开发企业环境下的应用程序提供的一套解决方案,包括 Web 网站后台开发等。该技术体系包含的技术:Servlet、JSP 等。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务端Java 应用。JavaEE 是在 JavaSE 的基础上构建的提供 Web 服务、组建模型、管理和通信 API。
JavaSE 是整个 Java 平台的核心,做 Java 后端先学 JavaSE。
前端
编写 html 代码搭建一个框架展现网页内容,如图片、文字、视频…,打开浏览器的任意网页,按下 F12 可以看到网页对应的 html 文件
用 JavaScript 语言控制与用户的交互,比如网页弹窗、动态改变网页内容、验证登录信息、跳转页面等。
例:点击登录页面,输入用户名与密码,按下回车,会触发事件执行 JavaScript 代码,给用户响应(登录失败或成功)。
可以说前端相当于前台,是可以看的见的内容。
后端
接收从前端页面或其他后端服务传递过来的请求,处理业务逻辑,对数据库中的数据增删改查 CRUD。
给调用者一个响应,如把数据返回给调用者、操作是否失败、返回对应的 html 代码等,用户是看不见的。
例:接收到前端传过来的用户名与密码,查询数据库中是否存在,若不存在返回用户不存在。前端接收到后,改变页面信息给用户提示。
不限于使用哪种编程语言,只要能把正确的数据返回给调用者即可。
要保证访问量很大时(同一时间内能够处理尽可能多的请求)而服务器不宕机、响应时间短不至于用户长时间等待、多个用户访问时保证数据的一致性等。(高可用、高并发、分布式、自动化)
Java 是一门编程语言,特性如下:
1、面向对象
Java 以类为结构组织代码,对对象、继承、封装、多态、接口、包等均有很好的支持。为了简单起见,Java 只支持类之间的单继承,但是可以使用接口来实现多继承。使用 Java 语言开发程序,需要采用面向对象的思想设计程序和编写代码。
如果不想使用此特性,Java 也可以写出面向过程的代码。
2、平台无关性
一次编写,到处运行(Write Once,Run any Where)。因此采用 Java 语言编写的程序具有很好的可移植性,而保证这一点的正是 Java 虚拟机。在引入虚拟机之后,编译后的 class 文件可以在不同的平台上运行,不需要重新编译。
3、简单性
Java 语言的语法与 C 语言和 C++ 语言很相近,使得很多程序员学起来很容易。对 Java 来说,它舍弃了很多 C++ 中难以理解的特性,如操作符的重载和多继承等,而且 Java 语言不使用指针,加入了垃圾回收机制,解决了程序员需要管理内存的问题,使编程变得更加简单。
4、解释执行
Java 程序在 Java 平台运行时会被编译成字节码文件,字节码与所在平台无关,可以在有 Java 环境的操作系统上运行。在运行文件时,Java 的解释器对这些字节码进行解释执行,执行过程中需要加入的类在连接阶段被载入到运行环境中。
解释型的转换工具称为解释器,程序在运行时使用解释器。每翻译一句,就执行一句,效率低,但跨平台性能好。
编译型的转换工具称为编译器,事先把源代码交给编译器,它一下子全部翻译,得到编译后的代码,可以直接被机器执行。
例如 JavaScript 语言有编译型的转换工具,如 chrome 的 V8 引擎,也有解释型的转换工具如 Netscape Navigator 的 JS 引擎。
5、多线程
Java 语言是多线程的,这也是 Java 语言的一大特性,它必须由 Thread 类和它的子类来创建。Java 支持多个线程同时执行,并提供多线程之间的同步机制。任何一个线程都有自己的 run() 方法,要执行的方法就写在 run() 方法体内。
6、分布式
7、健壮性
Java 的强类型机制、异常处理、垃圾回收机制等都是 Java 健壮性的重要保证。对指针的丢弃是 Java 的一大进步。另外,Java 的异常机制也是健壮性的一大体现。
8、高性能
Java 的高性能主要是相对其他高级脚本语言来说的,随着 JIT(Just in Time)的发展,Java 的运行速度也越来越高。
9、安全性
1、Android 应用
2、在金融业应用的服务器程序
Java 在金融服务业的应用非常广泛,很多第三方交易系统、银行、金融机构都选择用 Java 开发,因为相对而言,Java 较安全 。大型跨国投资银行用 Java 来编写前台和后台的电子交易系统,结算和确认系统,数据处理项目以及其他项目。
3、网站
4、嵌入式领域
Java 在嵌入式领域发展空间很大。是指各种小型设备上的应用,包括机顶盒、车载的大屏影音娱乐设备、POS 机等。在这个平台上,只需 130KB 就能够使用 Java 技术。(在智能卡或者传感器上)
5、大数据技术
Hadoop 以及其他大数据处理技术很多都是用 Java,例如 Apache 的基于 Java 的 HBase 和 Accumulo 以及 ElasticSearchas。
6、框架
解决企业应用开发的复杂性,让开发更加方便。
7、软件
制作小游戏、开发工具 IDE 。
内容导视:
即使编写了 Java 源代码,系统也无法直接执行,需要 JDK 提供编译和运行 Java 程序的环境,将代码解释为系统可识别的机器码。
JRE(Java Runtime Enviroment):是 Java 的运行环境。面向 Java 程序的使用者,而不是开发者。
核心类库:主要是开发经常使用的类库,避免重复造轮子。如 java.lang 下的 String、包装类等,已经被编译成了 .class 文件,需要时直接拿来用,不用自己重新写一份。
如果你只是想运行 Java 程序,就只安装 JRE 即可。
有 JDK7、8、11,通常使用的是 JDK8、11,因为它们是长期支持版本,一般的版本支持半年就不再显示。此时的你点开链接,说不定已经看不到 JDK7 了。
LTS 代表长期支持的版本。
Oracle 产品支持的三个策略:
JDK8 扩展支持到 2030 年,Oracle 将每三年指定一个版本作为长期支持版本。
查看自己电脑位数
x86 是 32 位,x64 是 64 位。
打开文件资源管理器,右键此电脑属性查看系统类型是 64 位操作系统,还是 32 位。
根据自己的系统、位数决定下哪个
比如我的电脑是 windows 系统 64 位,我使用的是 JDK8,按图选。
特别说明
安装
(安装后我又卸了,使用了 zip,所以地址前后不一致)
是 zip 解压即可,点击解压后的文件夹,地址栏上显示的就是安装目录,要看到 bin 和其它目录,如图:
认为安装目录是 D:cqh_environmentJava 就错了。
记住 JDK 的安装目录,配置环境变量要用
安装好后,看看目录:
bin 目录存放命令,如常用的 javac.exe、java.exe,用于编译,运行程序。
lib 存放着 jar 包,如 dt.jar 是运行环境类库,存放了 Swing 组件;tools.jar 是工具类库,用来编译与运行 java 文件。
src.zip 存放着 Java 源代码压缩文件。
rt.jar 在 jrelib 中。
解释
我们编写源代码使用的文件后缀为 .java,这种 .java 文件经过编译生成 .class 文件,多个.class 打包放在 .jar 包中。
呃,这只是教你如何卸载,并不是现在让你卸载…
打开控制面板/卸载程序,找到 Java。
或者打开 Windows 设置/应用/应用和功能,单击要删除的软件,会弹出卸载字样。
如果你不知道如何打开它们,请用百度搜索,如如何打开 Windows 设置
;其实由很多问题都已经得到回答,没必要重复造轮子。学会使用搜索,对自学很有帮助。
卸载成功后,所有目录名带 Java、Sun、Oracle 的一律删掉,如:
删除安装 JDK 的目录、删除 C:Program Files (x86)Common Files
和 C:Program Files
下的的 Java 和 Oracle 目录、C:Users用户名AppDataLocalLow
下的 Oracle 和 Sun 目录、C:Users用户名AppDataRoamingSun
。
这是可选项,不是必须要做的,因为我觉得时不时弹出来像牛皮癣一样挺烦。
高级/应用程序安装/从不安装。
如果你是什么都不懂的新手,请别慌着写代码,还有如下几件事要做:
内容导视:
为了对抗遗忘,可以快速回顾、促进理解、加深记忆,将知识有条不紊地归类,提炼反思应用。
不建议使用纸质的笔记,记录麻烦,不方便携带,有老化被撕毁的风险,摘抄代码时不能 Ctrl + C 快速复制粘贴。
推荐使用 Typora 软件、博客、等各大网站记录。
工欲善其事必先利其器,使用系统自带记事本编写程序,按下 Tab 缩进一大节,逼得我每次使用 4 个空格,回退也难;关键字没有颜色,不易于识别与查看。
下面介绍几个更好的工具,安装后,右键文件选择打开方式即可。
EditPlus
建议网上搜下汉化版的,下面是官方的收费的。
有 30 天的试用期,过后要购买许可证。
Notepad++
如何设置主题
设置/语言格式设置/选择主题,此外还可以根据不同语言设置样式。
Sublime Text
Visual Studio Code
Atom
不能指定安装目录;这种是以项目的方式管理文件。
也可以搜索一下其他的文本编辑器,看哪款适合你。
编写代码
打开刚刚下好的软件,输入源代码,最后 Ctrl + S 保存,另存为 First.java。但是现在还不到写代码的时候,下一章好吗?
一个指头敲字,一边看键盘,一边看输入的代码,很容易出差错。
既然选择了在电脑上打字,就要提高自己的指法速度,敲代码和写笔记才会快,两只手共同配合。
不用担心,我也这么走过来的,虽然一开始没有单只手指头快,但坚持下来,不看键盘,手势正确,打字速度会有明显的提升。
推荐使用金山打字通。
安装好后点击新手入门,练到不用看键盘,打字速度超过 30 ~ 60 字/分钟差不多够用了。(只需练习英文部分即可)
掌握常用的快捷键,能够极大地提升效率,节省时间。
如果是有触摸板的笔记本电脑。单击是鼠标左键,双击是鼠标右键。
请打开 windows 设置/设备/触摸板查看:(Windows + i 打开设置)
下面是我总结的常用几个快捷键。如 Ctrl + A,在电脑键盘上找到这两个键,同时按下去即可触发全选操作。
如果打不出中文,怀疑是按 Caps Lock 开启了大写或者连续按下 Shift 启动了粘滞键,再次按下此键即可恢复。
提前说明:
Ctrl + + 指同时按下 Ctrl、+ 这个键,别看见两个加号就懵了。
文本相关
先选中文字,Windows 键是 Alt 左边的。
内容如下:
热键相关
若桌面崩了,使用快捷键打开任务管理器,运行新任务,输入 explorer 后回车。
内容如下:
有的快捷键按下去时讲究先后顺序。
例:如 Alt + Tab ,先按住 Alt 键不要松,再按 Tab,有先后顺序(同时按也行),自己试试就知道我在讲什么了。
← 指的是左箭头。
说实话我向来很反感背知识,随用即取就行。但是那面试题人人都背,你不看看,万一被难倒了怎么办?算了不考虑这些,下面这些快捷键你只看看经常使用的即可。
截屏
1)快捷键打开截全屏的工具
Windows + W
2)区域截屏
Windows + Shift + S
3)截全屏
Windows + PrtScSysRq
PrtScSysRq 键在 F12 右边,保存的图片在 C:Users自己的用户名PicturesScreenshots
下。
PrtScSysRq
打开画图工具,Ctrl + V 将截屏捕捉。
4)截屏,范围限制在当前工作页面(得到焦点的页面)
Windows + Alt + PytScSysRq
5)录屏,范围限制在当前工作页面
Windows + Alt + R
捕获的图片和视频在 C:Users用户名VideosCaptures
里。
6)游戏栏工具
Windows + G
Alt
打开软件,按一下 Alt ,会有字符提示,并且将焦点定位到菜单栏,此时可按左右键切换功能区,上下(不行就 Enter 回车)键打开功能区。
字符提示会显示出功能的快捷键,例:文件功能区会显示出 F ,代表只需要 Alt + F 就可以打开此功能,弹出的下拉列表一般也有字母提示,按下对应字母即可。(有时需同时按下 Alt )
总结: Alt + 划下划线的字母,可以快速打开菜单。
快速启动任务栏上的软件
你看看你的任务栏(屏幕的最下方),打开应用后可以右击任务栏上的应用图标,将其固定到任务栏,下次直接单击此图标就可以打开应用。或者 Windows键 + 数字,比如
我希望你能后来居上,分享你的经验让我开开眼界。
下面是本人经过大量时间总结的经验,但你可以不看,因为没有什么规则可以量身定制。
1、约束好奇心,停止收藏资源
我直接说,你是学到死都学不完的。
资源无穷尽也。不要看到什么都想学,什么都想买,一直在搜,知识太多,你学不过来的。你先在网上搜索,比如后端的整套知识点,按顺序来,一心一意,一套教程为主,有疑惑的再去别的地方比对。不要没事就搜索一大堆资料收藏,又不开始,资料一定要精简,那些看上去有用的知识但短期用不上的,直接取消收藏(也包括我)。等你到了这步,再找资源,别做松鼠。
不要背代码,要掌握原理,方法可以到 API 文档上查。之前基本都是概念上的东西,理解就好了,但学到集合、IO、常用类如 String,只背方法名一定会消灭你学习的兴趣。
这东西是一回生二回熟,第一遍不要想着要弄的多明白,简单过一下即可。下次复习的时候,无师自通,我敢说人就是最强的智能机器人。
至于看视频还是阅读书籍,我感悟如下:
视频时间看完所需时间更长,但可以一步步来,如果章节内容划分合理,每个视频时长合适,学习者更轻松完成每个目标,掌握自己的进度。适合初学者。
书籍花费时间较少,但经常有断节之处,初学者搞不明白缺少哪一个环节,看着晦涩难懂的文字,翻不了几页就草草放弃,适合耐得住性子的人。
2、管理好精力
人一天能够利用的时间极其有限,所以要学会合理分配精力。学习并不是生活的全部,要参与家务,如果你整天扑到学习上,只会感动自己。随着精力的消耗,自控力的减弱,一定会在某天突然崩掉,开始变得什么都没有兴趣,行动力拉到最低,即使强迫在学,也只是枯坐原地,享受着左耳进右耳出的枯燥感。
早起别熬夜,每天一定留至少 30 分钟的时间午睡,为了第 2 天的精神良好。学习时推荐使用番茄钟,每过半小时就休息一小会,合理分配精力。(休息时不要看电子产品与动脑筋,要适当远眺)
3、学会分享
人人都有开始,你发出来了,别人才能纠正你的错误,避免成为井底之蛙。
你又开始自耗了,不停地在脑海天人交战,一顿脑补:会不会万一发出来被人嘲笑怎么办?…于是藏着掖着,生怕别人知道,出丑;事情还未做,就想一系列的后果,别人有多可恶。我觉得世上还是好心人多,当然不要被零星几个恶评就忽略了大多数支持你的人,这么大的林子总会有几个脑残。
对于四处搜索资源的人,是没有精力留下痕迹的,没有用的直接毙掉,有用的看完理解后也直接毙掉;这么快节奏的生活,没人关心你是谁,最多充当局外客。当你还在纠结别人的看法时,纠结要不要做时,别人根本记都不记得你。我们在网络时代那是十分渺小,沧海一粟,很快被淹没,就算有弄潮儿掀起了几朵浪花,也会很快平息,所以别再纠结丢不丢脸了。
帮助别人就是帮助自己。虽然这个地球少了谁都能转动,但我愿意相信天生我材必有用,自己的不可替代性。
你已经落后别人太多了,得到的都不是最新的知识;不要求自己跑的更快,但是也要有行动的勇气吧,就算有 1000 个人从众笑你、反对你,我也不会笑你,只会支持你,为你的敢于行动喝彩。
或者你担心教会了徒弟饿死了师傅,认为自己凭什么白白让别人分享自己的辛苦所得,让那些白嫖怪轻而易举获取到所有。
呃,我也不反对你,曾经的我认为那些动不动说要分享,文章标题、内容弄得很吸引人;结果在文章底部放了个二维码,说要关注才能获取验证码与资源,我一向嗤之以鼻,这不就是引流吗,能赚多少钱啊?但是现在觉得别人有权力这么做,没有人必须无偿满足你,因为用爱发电,得不到利益,很容易让人寒心。既然付不了金钱,就只能搭进时间和人脉,等价交换而已。
对于那些开源的人,要不是他们的分享,让我窥见一斑,那我现在应该不在家,而是进厂做流水线去了,是不会发文章的,或许抱怨这个世界不公平。所以再次感谢开源的人,感谢你们的无私奉献,你们就是一道光,照亮被淘汰看不见希望的我,至于我的信念就从此转变为萤火虫也可与日月争辉。(不禁想起了一句话:为众人抱薪者,不可使其冻毙于风雪;为大众谋福利者,不可使其孤军奋战;为自由开路者,不可使其困顿于荆棘)很抱歉我现在捉襟见肘,无法回馈你们。
说实话,现在当我使用手机、电脑、冰箱、自来水等一切产品时,都会惴惴不安,一是因为怕现在习惯了离不开了,但是不了解底层原理,要是他们以后技术垄断,坐地起价…;二是当我还在感叹新技术新发展新气象,日新月异,这些东西如此方便快捷,被制作被运送,傻瓜都能轻松使用。但是到底以牺牲了多少人的自由空暇为代价,令他们如同机械一般麻木,我们却理所当然,嘻嘻哈哈,嘲笑着都是因为不努力,教导下一辈不要学他们,要成为人上人…扪心自问,真的能够心安理得使用吗?平等或许只是伪命题。
4、承认自己的不完美
人无完人,总有顾及不到,犯错的时候。想做就直接放手干,不要计划地那么周全,稍微一有变动,就放弃目标,想明天再做。是吧,别觉得只有从容不迫、不慌不忙、按部就班地才叫做事,而达不到自己的心理预期就不做了,大多数人都是计划赶不上变化,被搞得灰头土脸的。
人是一种很奇怪的生物,我把人称为石头,有 1 就有 2。当难度设定太高,有一次累了没去执行,那么最后结局就是放弃。我就改变思路,将难度设定为合适、简单。还是如此,不管之前坚持了多少天,只要有一次意外,没做,结局还是放弃。
结论:没有外力时,一直滚动;有外力一碰,就停了;结论:维持当前状态,会被外力改变。
但是在滚动的过程中,会磨去棱角,那么下一次进入相同的环境,会很容易滚落下去,很难控制。所以每一次尝试,都是为下一次作铺垫,不要认为失败就是无用功。
5、调整心态(找准目标)
如果你学这个只是为了找工作,那么你一定会很痛苦。为了以后不再工作而工作,为了以后享福而选择现在吃苦(为了不再吃苦而吃苦),为了将来而牺牲现在;这种矛盾的做法,并且大部分人实现不了财务自由,如果你只靠出卖自己的时间换来金钱的话。
你想得又得不到,或追赶不上前面的事物,你会处于十分焦虑的状态。你真想财务自由,那么就要垄断其他人的时间,给自己带来利益(用金钱换他们的时间,创造价值收入囊中),或者搭上顺风车。
但我不一样,我写这个,并不奢求得到回报,因为我写这个同时,我就很满足了。
但也不要担忧,如果企业家全都使用机器人或者雇很少的人,短时间的确能够让利润增加,因为减少了给员工那一项的支出;但是员工既是生产者也是消费者,如果他们没有时间买或者没有钱买,就算降低商品的价格,但为了有利润可赚,员工的工资也会降,那就更没有钱买,继续降低商品价格…如此反复,就倒闭了;所以他们是不会让穷人更穷的。
(我只是安慰你,这些玩意早被研究透了,说不定命运都被安排的明明白白)
6、相信自己
可你也与我有着同一样的感受,为什么这些大佬如此牛逼,而自己什么都看不懂,不能理解,沮丧睡不着觉。我觉得这不是你的问题,而是每个人的必经之路。希望你能够坚持下来,即使在人生最黑暗的时候也能与本心融为一体,认同自己,一起冲向光明;最后祝你学业有成,找个好饭碗。
7、选择城市
之前聊天时,问到了这个问题:去大城市还是小城市发展?然后又说小城市容不下灵魂、大城市容不下肉身。其实我都没有工作,村里人都知道我是游民,我给不了什么实质性的意见。
哈哈,没关系,任何一个选择都有得有失,你看看代价与风险是否自己能够承受:是接受安稳,被人看扁;还是避开喧嚣之地,舍命一拼,打下一片未来;就看你怎么选了。
说到底,被人欺,与老不老实无关,而是与实力相关;假如你不讨喜,没有什么朋友,与他人的联系几乎没有,有你没你一个样,未来也不可期;你无法变现自己的价值,别人凭什么要帮你,给你留一点蛋糕?另外一点,别人也无法以你为桥,认识更多有价值的人,那么纯粹是浪费时间。
当出现不是让所有人都满意的结果时,别人权衡利弊后觉得你很好欺负,得罪你的代价可以承受,你没有价值,削去你的利益,事卡着不给你办,或者祸水东引,反正你也掀不起大浪。
实力不够,人间处处是地狱。不想融入阻扰了别人利益,被排外,没有晋升的机会。你佯装融入,等你实力终于够了,你也已经同化成其中一员,将曾经的憋屈发泄,迫害如同当年的像你一样的人,十分地爽,开始心安理得,阻扰那些想要发声的人,觉得凭什么我受而你们不用受,心理不平衡,主动维护旧有秩序。
8、没有绝对正确的理论
给出一个貌似符合常理的结论,有人举出反例,然后结论被推翻,再重新给出符合此反例的新的结论,不停周而复始…
如果这个结论目前还未被推翻,就暂时当作正确的吧,不需要怀疑一切,那样会很累的;我的知识体系到处东拼西凑,别人说什么如果验证不出来,就分不清真假,只能暂时当成对的。
简洁、功能强大、实时预览的 md 编辑器。
下一步 next,
选中复选框代表创建桌面快捷方式。
打开文件资源管理器,把文件扩展名和隐藏的项目打上对勾,就可以看到隐藏的后缀和文件夹如 AppData;
此时刚刚创建的文件显露真身,原来还是 txt 文件;右键重命名,把 .txt 去掉,再双击点进去。
md 语法的出现不是为了替代 html,而是更方便书写。如果让我写那么多的 <>,不停思索如何嵌套,写一大堆长长的 css,我会疯掉的。
内容如下:
标题
一个 # + 空格,跟上标题内容即可。(Ctrl + 1 是一级标题,以此类推)
一个 # 是一级标题,两个 # 是二级标题,依此类推,直到 6 级标题。(越来越小)
复选框
一个减号 + 空格 + [ ] + 空格
粗、斜、斜加粗等字体
1、被两个星号包裹的字自动变粗(Ctrl + B);
我是粗
2、被一个星号包裹的字是斜体(Ctrl + i);
3、被 3 个星号包裹的字是粗斜;
4、Tab 上面有一个键,按住 Shift,再按住它,可以打出 ~。
废弃
引用
大于号 + 空格 + 内容
键盘风格
ctrl+c是复制
超链接和图片
这些地址就是网址。
(右击打开链接或按住 Ctrl,再单击此链接)
表格
Ctrl + T 快捷键创建表格,Ctrl + Enter 添加新行,Shift + Ctrl + Del 删除一行。
代码
单行使用 `,多行三个 `,指定代码语言:
单行代码
列表
1、无序列表
单个星号 + 空格 + 内容
2、有序列表
数字. + 空格 + 内容
3、列表套列表
大纲
可以把标题列出来,即 # 后的内容。
分割线
三个减号+回车(Enter)
以下内容不需要了解,几乎不用,有很多网站不支持这种语法。
甘特图
流程图
内容如下:
因为都是中文,只讲一点点,剩下的自己在菜单栏上研究吧。
快捷键
直接点击菜单栏,查看快捷方式,如点击视图、段落,上面显示了快捷方式更方便触发;或者按住 Alt + O,即可打开格式:如 Ctrl + B 是加粗的快捷键,Ctrl + 是清除样式,Ctrl + T 是创建表格的快捷方式,Ctrl + / 是查看源代码,Windows + 句号是表情符号、视图可以放大、缩小…
主题
Alt + T 选择自己想要的主题。
偏好设置
Ctrl + ,
如通用的自动保存选上,每次修改自动保存,不用按下 Ctrl + S。
代码块显示行号
更换主题
学了 CSS 后,再来。
之前创建 md 文件时,给隐藏的项目了打上对勾,代表显示隐藏的项目。其中 AppData 就是隐藏的项目,一般存放软件的配置文件。
C:Users你的用户名AppDataRoamingTypora hemes
下的几个 CSS 文件代表着不同的主题,如果不满意页面样式,可以修改对应主题 CSS(记得留个备份)或自定义 CSS,重新打开笔记后,可以在主题中看到你的 CSS,随便更换。
将笔记转成其他类型的文件
文件/导出,
或者打开浏览器,使用打印功能(Ctrl + P),无渲染与解析,很差劲。
支持数学公式
常用的的数学符号写法:
恢复未保存的文件
打开偏好设置,点击恢复未保存的草稿。
它升级到了 1.0 版本了!收费了。
Typora 代理商:
最后一个免费版,分享者:王炳明,
其实从来都没有说过免费,之前只是 Beta 测试版,类似于游戏中的公测吧,也不知道免费版什么时候就“关服”了。
作为一个即时渲染,所见即所得,按下 Ctrl + / 就可以看源码,简洁实用,早已习惯,离不开它了。其它的软件花里胡哨,什么功能都往里面加,试图想代替其它同类型的软件,结果搞得不伦不类,十分臃肿。
像其它 md 编辑器,大部分都是双栏丑丑的大屏幕,十分占空间,并且滚动内容时,左右视图不一致,还得分心同时看两边,真的是种折磨。应该让软件配合人,而不是让人记住软件的用法,主次关系要分清;真希望以后能够统一,有个规范,其它软件实现就可以了。
你如果使用久了,经常在网上发布文章,一定会遇见这个问题。
把写好的 md 文件,复制粘贴到博客园中。结果你发现图片加载不出来,一看地址,C:Users自己的用户名AppDataRoamingTypora ypora-user-imagesxxx
。
这才知道原来图片被保存到了本地中,也难怪网上读取不到。那么你发现了,将图片直接拖拽到博客园的编辑页面,会自动生成网络上的 URL,可以在全网都能访问到。
但是时间长了,一张、一张拖拽也不是事啊。这时就需要图床替我们自动保存图片。下面介绍两种方式;
命令行上传图片
打开偏好设置/图像,
意思是当本地图片被你拖进 md 文件中,会自动上传图片。
这个 token 如何填?
自己注册账号后,再登陆:
点击 User/Dashboard/API Token,进入:
点击 Generate Secret Token 按钮生成 token,将其填入 JSON 文件。
填完后,保存 JSON 文件。将图片拖拽 md 文件时,如有 Uploading 字样,就成功了。
在 Pictures 可以管理或删除这些文件,可惜根本没法根据 URL 找到图片,时间长了,定位删除图片还是不方便。
说实话我很担心,手贱全删了,导致 md 文件图片全部失效,还是放在博客园中保险些,真可惜我的硬盘不能作为服务器。
PicGo app 上传图片
但无论怎么双击就是不会显示窗口,看看电脑右下角,点击蓝色图标:
Typora 软件,偏好/图像,按图设置
在 PicGo 的安装目录下有个 PicGo.exe,PicGo 路径就选择此 exe 的绝对路径。
内容导视:
打开 DOS 窗口的几种方式
进入目录内:使用绝对路径与相对路径演示
常见的 DOS 命令
写出来的 Java 代码,需要在命令窗口中执行编译与运行命令,需要知道如何打开此黑窗口(Disk Operating System)。
下面说的目录和文件夹是一个意思。
输入命令后按下回车才能执行,回车键是 Enter。
由于不是可视化界面,不能像之前一样,点到哪里就跳到哪个文件夹下,需要使用 cd 命令,跳转到某路径下。
路径分为绝对路径和相对路径。
打开文件资源管理器(Windows + E),随便打开某盘下的文件夹,可以看到地址栏上的路径。假如以 D: 开头,D: 称为盘符,显示的路径称为绝对路径,D:
称为 D 盘的根目录(最上一级,不能再上了)。
而相对路径,是以当前路径作为出发点的路径,比如进入当前路径的 a 目录。
首先打开 DOS 窗口,切换盘符。
例:想要到 E 盘下,就输入 E:
后回车,输入 dir
回车查看当前路径下有那些子文件(没有就在该盘手动创建文件夹),使用 cd 文件夹名称
进入此文件夹。
使用 cd a
时,单看这个 a,鬼才知道这是哪个地方的文件夹,在哪里才能找到它,需要结合当前路径 E: 才能知道,原来是要到 E 盘下去找 a,那么这个 a 就是相对路径。
..
:上级目录
.
:当前目录
现在回到上级目录,使用cd ..
,现在演示一下绝对路径,cd 绝对路径
,使用绝对路径时,必须是当前所在盘下的路径。
注意:路径必须存在,你需要把目录创建出来,才能使用 cd 命令进去。
如果使用相对路径,先切换到根目录,再执行 cd acd
。
怎么回到根目录?使用 cd E:
吗?或者 cd ........
?
还有一种简单的方式 cd
即可
一个 cd ..
是回到上级目录,
cd ....
是回到上上级目录。
若文件名太长记不住,可以打出首字母,再按下 Tab 键,也可上下键切换已经输入过的命令,或者你直接将文件拖入这个黑窗口,地址就出来了。
通过刚才的例子,发现跳转路径时,必须是当前盘下的路径,那么还不如使用相对路径,反正盘名写其它盘也没用。解决办法:加个参数 /d 即可。
例:现在在 C 盘下,我要直接到 E:acd
,输入 cd /d E:acd
即可。
内容如下:
由于可以设置中文,只讲一点点。
菜单栏的 Tools/Options/General,右边的 Language,下拉列表,选择中文(简体)。
Alt + ?打开对应的菜单栏:
F:文件
E:编辑
V:视图
G:跳转
B:笔记笔记本
N:笔记
T:工具
H:帮助
Ctrl + Q:退出。
导入 md 文件
把文件同步到本地
工具/选项,同步,同步目标设为 File system,设置同步目录。(当然你也可以花钱存云)
给同步目标上的备份文件加密
工具/选项,加密,启动加密;这样的话,如果把同步文件上传到云端,也不怕别人偷看。
如果删除了同步目标的文件,为了安全(故障保护默认开启),不会删除本地文件。
如果删除了本地文件,同步时间一到,同步目标的文件也会被删除。
可以趁着这时间差,从同步目标导入数据到本地。
同步/显示高级选项,自己重新上传数据到同步目标或删除本地数据并从同步目标导入数据
如果两个终端数据不一样(同时修改一个文件,为不同内容),会把冲突的文件移到新创建的”冲突”笔记本中,等你处理。
使用外部 md 编辑器
在 Joplin 上任意选一个笔记,按下 Ctrl + E,自动转用外部编辑器编写文件。
自定义笔记本图标
笔记本右击/编辑,图标/Select emoji,选一个表情。
网页剪藏器
知识太多了,短时间内是看不完的,如果收藏,也有链接失效的风险,需要将文章内容复制下来。
工具:Chrome 浏览器。
由于插件市场打不开,点击:
把 crx 文件直接拖入此页面,添加扩展程序
Joplin 软件,工具/选项,网页剪辑器,启动网页剪辑器。
使用:
Clip simplified page:简化后的页面
Clip complete page:完整页面
In notebook:保存在哪个笔记本
Title:文件名
同步到手机
把自己电脑当作服务器,同步到手机,教程:
作者:lightzhan,密码:h3mu,WebDAV 小秘:
打开 DOS 窗口,输入 ipconfig 命令,IPv4 地址对应的就是主机地址;用户名与密码自己设置。
手机上自己搜索 Joplin app 吧,因为谷歌你们可能访问不了,我总不能把如何翻墙写在这吧。
WebDAV URL:http://主机地址:端口号
填入自己电脑上设置的用户名与密码,然后检查同步配置,如果显示“成功!同步配置看起来没问题。”就 OK。
如果成功后依然没有开始同步,一直转圈,退出软件重新进入。
扩展语法
是 Typora 的同类型产品,开源免费,略微有些小 bug。
由于作者计划 v1.0.0 以后支持其它语言(国际化),英语不好的,可以搜下汉化版。
作者:,
安装用户脚本管理器:
加速脚本:
将 js 文件拖入其中,刷新页面,效果如图:
英文 OK 的同学可以跳过以下内容…
查看源代码:Ctrl + E
整体布局
正上方是 md 文件的绝对路径;
左上角 A 是总字符个数;点击可以切换。
Close:关闭文件(未 Ctrl + S 保存会弹出提示)
Close others:关闭其它文件
Close saved tabs:关闭已保存的文件
Close all tabs:关闭所有文件
Rename:重命名文件
Copy path:复制文件的绝对路径
Show in folder:打开文件所在目录
段落快捷操作
当你每次移动光标时,当前段落对应的图标(最左边)就会显示,点击
Duplicate:向下复制当前段落
Turn Into:变成?
New Paragraph:创建新的段落
Delete:删除当前段落
选中文字
插入表情
Windows + 句号,或者 :a:
,两个冒号跟一个字母
Ctrl + 逗号
General
自动保存
Auto Save:
Window:
Title bar style:
Editor
字体样式
Text editor settings:文本编辑设置
支持上下标
启用 Enable Pandoc-style superscript and subscript
Spelling
Enable spell checker:开启拼写检查
Default language for spell checker:检查器的默认语言
Key Binding
更改操作的快捷键方式
修改,重置,删除
每次修改后,需要翻到最下面保存
偏好设置/Image,
Default action after an image is inserted from local folder or clipboard:插入图片后的操作(只支持 macOS 和 Windows 系统)
Upload image to cloud using selected uploader(must be configured below):上传至云端
Global or relative image folder:指定图片保存的绝对路径
Prefer relative assets folder:…相对路径,开启后,图片会放在与 md 文件的同级目录下
说一下历程吧。
在 C:Users你的用户名.picgo
下创建了 config.json 文件,复制了如下:
PicGo-Core 指南:
用法:
如上传文件:picgo upload 文件的绝对路径
于是学了一下 Shell 脚本的语法,提示说输入的唯一参数是图片路径,要求输出图片的 url 路径;于是上网搜,如何接收第一个参数、输出,分别是 $1、echo;尝试过程中发现路径必须以 /
分隔,而不是 。
选择,点击 Set as default,默认图片上传至 sm.ms。
下拉框改为 Picgo 即可。
拖入图片到窗口时,必须拖到当前段落(会显示一条绿线),才会成功。
脚本:解释性语言,且是文本格式。
英语不好,又没有安装汉化版的…下面是菜单栏的各项,先从 File 开始:
New Tab(Ctrl + T):新建文件
New Window(Ctrl + N):生成新窗口
Open File(Ctrl + O):打开文件(可以直接将 md 文件拖入此窗口)
Open Folder(Ctrl + Shift + O):打开目录(显示目录下的 md 文件、查找、显示文章中的标题)
Open Recent:打开最近文件
Save(Ctrl + S):保存
Save As(Ctrl + Shift + S):另存
Auto Save:退出文件前自动保存
Rename:重命名
Export:导出为
Auto numbering headings:自动为 h1 以下级别的标题编号
Show front matter:显示前言
Theme:选择主题
Table of Contents:目录列表
Landscape orientation:是否横向
Page margin:页边距(毫米)
Top/Bottom:上下边距
Left/Right:左右边距
Header & Footer:页眉页脚
Header type:页眉类型
Single cell:单(中间)
None:无
Three cells:三(左中右)
Customize style:定制风格
Preferences(Ctrl + 逗号):偏好设置
Close Tab(Ctrl + W):关闭文件
Close Window(Ctrl + Shift + W):关闭窗口
Quit(Ctrl + Q):关闭所有窗口
导出时新增主题:
Undo(Ctrl + Z):撤销
Redo(Ctrl + Shift + Z):反撤销
Cut(Ctrl + X):剪切
Copy(Ctrl + C):复制
Paste(Ctrl + V):粘贴
Paste as Plain Text(Ctrl + Shift + V):纯文本粘贴
Select All(Ctrl + A):选中所有
Duplicate(Alt + Ctrl + D):向下复制一行
Create Paragraph(Ctrl + Shift + N):创建新的段落
Delete Paragraph(Ctrl + Shift + D):删除当前段落
Find(Ctrl + F):查找
Replace(Ctrl + R):替换所有、一个个替换
Find in Folder(Ctrl + Shift + F):在目录下的文件中查找(首先得 Open Folder 打开目录)
Line Ending:换行方式
Carriage return and line feed(CRLF):Windows 换行方式,即
Line feed(LF):Linux换行方式,即
Heading 1、2、…、6 为 H1、H2、…、H6 标题
Promote Heading(Ctrl + Shift + =、Ctrl + 加号):提升标题等级
Demote Heading(Ctrl + -):降低标题等级
Table(Ctrl + Shift + T):创建表格
Code Fences(Ctrl + Shift + K):代码块
Quote Block(Ctrl + Shift + Q):引用
Ordered List(Ctrl + G):有序列表
Bullet List(Ctrl + H):无序列表
Task List(Alt + Ctrl + X):复选框
Loose List Item(Alt + Ctrl + L):增加列表之间的距离
Paragraph(Ctrl + Shift + 0):段落
Horizontal Rule(Ctrl + Shift + U):分隔线
Bold(Ctrl + B):粗体
Italic(Ctrl + I):斜体
Underline(Ctrl + U):下划线
Superscript:上标
Subscript:下标
Highlight(Ctrl + Shift + H): 黄色高亮
Inline Code(Ctrl + `):单行代码块
Strikethrough(Ctrl + D):删除线
Hyperlink(Ctrl + L):超链接
Image(Ctrl + Shift + I):图片链接
Clear Formatting(Ctrl + Shift + R):清除格式
Always on Top:总是显示在最上层
Zoom In:放大
Zoom Out:缩小
Show in Full Screen(F11):全屏显示
Command Palette(Ctrl + Shift + P):查看操作的快捷方式
Show Sidebar(Ctrl + J):显示侧边栏(目录树、查找、文章标题)
Reload Images(F5):重新加载图片
Quick Start:
Changelog:
:赞助
Feedback via Twitter:反馈(使用推特)
Report Issue or Request Feature:
Website:
Watch on GitHub:
Follow us on GitHub:
Follow us on Twitter:关注我们(Twitter)
License:
(不要惊讶怎么这么少,我说过别把大脑当成硬盘,记一个 cd 命令就足够了,记得看完后休息一会,欲速则不达)
Java是最早由 SUN 公司的 James Gosling 开发的编程语言。
SUN 在 2009 年被 Oracle 收购;2014 年 3 月 19 日发布了 JDK8。
常用的 DOS 命令
cd 当前目录下的文件夹名
进入目录
1.1 JDK 和 JRE 的区别?
1.2 什么是编程?
1.3 Swing 组件是什么?
1.4 JAR 包是什么?
1.5 软件与程序指的是什么?
1.6 什么是编译型语言和解释型语言?
1.7 Java 语言特性?
内容导视:
内容导视:
我们要开始写源代码啦!但只是在 DOS 窗口中输出一句话而已…
创建以 .java 结尾的文件,如 Hello.java。(以后统称为后缀或扩展名,打开文件资源管理器,查看,勾上文件扩展名)文件右击选择打开一种打开方式。(EditPlus 或其他文本编辑器,找不到选择其它应用,然后选中“始终使用此应用打开此类型的文件”复选框)这样你以后双击 .java 文件就可以直接使用此软件打开啦。
双击此文件,输入如下。还是直接复制、粘贴吧,记得保存。(Ctrl + S)
打开 DOS 窗口,使用 cd 命令切换到此文件的所在目录。
(如果你在桌面上创建的文件,路径是 C:Users自己的用户名Desktop
,你可以自己打开文件资源管理器,点击左边的桌面图标,在地址栏上输入 cmd 后回车)
在 DOS 窗口中输入 javac Hello.java
,得到如下诡异的结果。
你可能会疑惑?怎么没有找到这个命令,不是在 JDK 的安装路径/bin 目录下有 javac.exe
命令吗?你说找不到?那为什么之前 DOS 窗口查看 IP 时,也就是 C:WindowsSystem32
下的 ipconfig
命令就可以执行?
此电脑右键/属性/高级系统设置/环境变量/系统变量/Path 下看到了 %SystemRoot%system32
,即 C:WindowsSystem32
。
(如果桌面上没有此电脑图标)
猜想:难道系统只会在 Path 指定的路径下寻找命令吗?我随手就删了它(别试,否则手动还原),确定保存刚刚的修改操作,重新打开 DOS 窗口,再次执行 ipconfig
,很明白了。
得出结论:执行的程序如果在当前目录下不存在,系统会在名为 Path 的环境变量指定的目录下查找。
好的,大概明白了,但我的电脑上有多个用户,那么为了不影响其他用户,我只配置用户变量的 Path,优先级当然没有系统变量的高。(系统变量针对所有用户生效)
上节知道了 Path 变量的作用,现在该把命令地址添加到 Path 中了。
有的人可能版本较老,Path 变量值在一行文本框上显示。那么添加路径时,注意路径与路径之前使用;分隔,注意这个分号是英文状态下的半角符号,你按下 Shift,看看电脑右下角是否中英在切换。写成 ;
就错了。以后如果不说明,统一使用英文状态下的符号。
例:
检查自己是否配置好了:
有的人可能有疑惑,明明自己没配环境变量,为什么 java.exe 可以使用?
答:使用 exe 文件安装 JDK 后,会自动在系统变量 Path 添加如下图路径:
C:Program Files (x86)Common FilesOracleJavajavapath
所以没有手动配置环境变量时,java 命令可以用,但 javac 不行。
每次改动,都需要重新打开 DOS 窗口,配置才能生效。输入 javac Hello.java
,如果你的语法正确,就会在当前路径下生成 class(字节码)文件,再输入 java Hello
,此时别带后缀。
新建环境变量 classpath:
.是英文输入的句号,代表当前路径,如果不写就不会从当前路径寻找 class 文件。
由于我习惯把 class 文件放在桌面上,于是新增了桌面的路径,路径和路径直接使用;分隔,别使用中文的分号。
这样不管在任何地方,输入 java Hello
就可以执行了。
总结
javac Te*.java 会将文件名开头为 Te 的所有 .java 文件都编译
也许你总是会忘记,此命令应该携带什么参数…
想要执行的命令 -help
,例举了可加的参数,如 -encoding。(对不起,我要给你埋坑了,如果你事先不知道此参数的作用…)
如 javadoc -help
、javac -help
。(其实不加 -help 也行)
看,这不就出来了:
看不懂很正常,学完面向对象就懂了。突然遇到看不懂的不要怀疑自己智力有问题,只是还没到这步而已,大不了直接跳过。
从头开始说吧。
(字节码文件是 class 文件,由源代码中定义的 class 生成)
过程如下:
首先新建后缀为 java 的文件,编写出符合语法规则的代码。
编译:经过 javac 源文件名.java
命令编译生成字节码文件;
(补充:因为一个源文件可以定义多个类,编译后生成多个 class 文件,所以 java 命令后面跟的不一定是源文件名)
编译
.java 文件是 java 的源文件,但是不能直接运行,必须先被编译成为 .class 文件才能够执行。别问,问就是电脑太笨,看不懂。
class 文件也称为字节码文件,上面的 javac 源文件名.java
就是编译的过程。
运行
(当源文件修改后,必须重新编译才能生效)
编译后生成 class 字节码文件,使用 java class文件名
运行,别加 .class 后缀。
字节码文件是一种和任何具体机器环境及操作系统环境无关的中间代码,编程人员和计算机都无法直接读懂字节码文件。它是一种二进制文件,是 Java 源文件由 Java 编译器编译后生成的目标代码文件。它必须由专用的 Java 解释器来解释执行,因此 Java 是一种在编译基础上进行解释运行的语言。
C 语言中文网下的解释,我觉得还行吧,我没玩过 C 语言。
1)将所有源代码一次性转换成二进制指令(也就是生成一个可执行程序,如 Windows 下的 .exe)
的转换工具称为编译器。
比如 C 语言、C++ 的 GCC、Golang 的 GCC GO 等,源代码改动需要重新编译一次。
2)翻译一句,执行一句,不会生成可执行程序。
比如 Python 的 CPython 等,这种的转换工具称为解释器。
3)Java 和 C# 是一种比较特殊的存在。
如 java 有编译器 javac,但编译后的 class 文件计算机无法执行,还需要 java 解释器进行翻译。
它们的源代码需要先转换成一种中间文件(字节码文件),然后再将中间文件拿到虚拟机中执行。
Java 引领了这种风潮,它的初衷是在跨平台的同时兼顾执行效率;
C# 是后来的跟随者,但是 C# 一直止步于 Windows 平台,在其它平台鲜有作为。
Java 解释器负责将字节码文件翻译成具体硬件环境和操作系统平台下的机器代码,以便执行。因此 Java 程序不能直接运行在现有的操作系统平台上,它必须运行在被称为 Java 虚拟机的软件平台之上。
Java 语言这种“一次编写,到处运行”的方式,有效地解决了目前大多数高级程序设计语言需要针对不同系统来编译产生不同机器代码的问题,即硬件环境和操作平台的异构问题,大大降低了程序开发、维护和管理的开销。
内容导视:
看不懂没关系,只挑能理解的。
2)在 java 中任何有效的代码必须写在“类体”中,就是 public class Hello 后的一对大括号 {} 中。
3)大括号必须要成对写,防止漏掉。
4)为了增加代码的可读性,大括号里的内容需要使用 tab 缩进,如 main 方法就比 class Hello 低一个层次。
5)main 后的 {} 包裹的内容称为方法体,由一行行的 java 语句构成,任何一条 java 语句必须以分号结尾;。若无特别说明,默认为英文状态下的符号。
6)方法体中代码遵循自上而下的顺序依次逐行执行,不可随意颠倒顺序。
7)一个 java 源文件可以定义多个类。编译后,每一个类对应一个 class 文件,如以下编译后会生成 A.class、B.class、C.class 三个字节码文件
8)有 public 修饰的类可以没有,但如果有,被 public 修饰的类名必须与源文件名一致。
例:源文件名为 Hello,则 public class 后的类名也应该为 Hello。
9)被 public 修饰的类如果有,则最多只能有一个。类似一个家只有一个主人吧。
10)运行时,只会调用对应类的入口方法里面的内容,入口方法有固定的书写格式:
public static void main(String[] args) {}
那我偏不信邪,改下,再运行。
好吧,再改回去了。
规范与规则不一样,不是必须遵守。但是如果你不遵守,代码可读性会很差。反例如下,虽然可以通过编译,但你看起来感觉如何?
1)类和方法上的注释,以 javadoc 的方式,方便生成文档注释。
2)非 javadoc 注释,用于给代码的维护者和读者看。(为什么这么写,如何修改,注意事项)
3)运算符如 <、= 的两边使用空格与字符隔开,举出正反例:
4)代码编写使用次行风格或行尾风格。你可以理解为这就是对整齐风格的一种追求吧。
声明:由于每次使用 import、带上完整类、main 方法比较繁琐。于是进行了简化,只提供关键部分,外面的类、方法等其它代码以后自己加吧,别直接复制代码,发现怎么跑不起来啊?
凡是程序员有权利命名的单词都是标识符。
比如:类名、方法名、参数名、变量名、接口名、常量名。(这些是什么,以后就知道了,现在只是看看)
你可以试试哪里可以修改,比如修改 public、int 等单词,是否会报错。你就明白,你可以动的地方有哪些。可以动而不报错的那些单词就是标识符,不可以动的就是关键字。
命名规则
可以使用 Character 类的方法检验,isJavaIdentifierStart 方法可以确定某字符是否可以作为变量名的开头;
isJavaIdentifierPart 方法确定某字符是否可以作为变量名的一部分,不包括开头。
命名规范
见名知意,如 day 代表天数。
1)别用拼音与英语混合,那样很难理解。
2)杜绝完全不规范的英文缩写,避免望文不知义。
驼峰命名,多个单词连在一起时,单词首字母大写,增加识别和可读性,下面是阿里巴巴开发手册(黄山版)详细:
1)类名使用 UpperCamelCase 风格(首字母大写,后面每个单词首字母大写),以下情形例外:DO / PO / DTO / BO / VO / UID 等。
2)方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格(首字母小写,后面每个单词首字母大写)。
3)常量名全部大写,单词间用_连接,力求语义表达完整,不要嫌名字长。
枚举成员实际上也是常量,名称需要全大写,单词间用_连接。
4)抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类命名以它要测试的类的名称开始,以 Test 结尾;枚举类名带上 Enum 后缀。
5)如果是形容能力的接口名称,取对应的形容词为接口名(通常是 –able 结尾的形容词)。
6)在常量与变量命名时,表示类型的名词放在词尾,以提升辨识度。
7)POJO 类中定义的布尔类型的变量,不要加 is 前缀,否则部分框架解析会引起序列化错误。
备注:POJO(Plain Ordinary Java Object):普通的 Java 对象。
8)包名统一使用小写,点分隔符之间有且仅有一个自然语义的英语单词。包名统一使用单数形式,但是类名如果有复数含义,类名可以使用复数形式。
9)避免在子父类的成员变量之间、或者不同代码块的局部变量之间采用完全相同的命名,使可理解性降低。
说明:子类、父类成员变量名相同,即使是 public 也是能够通过编译,而局部变量在同一方法内的不同代码块中同名也是合法的,但是要避免使用。对于非 setter / getter 的参数名称也要避免与成员变量名称相同。
关键字
Java 关键字是对 Java 编译器有特殊含义的字符串,是编译器和程序员的一个约定,程序员利用关键字来告诉编译器其声明的变量类型、类、方法特性等信息。
关键字一律用小写字母标识,按其用途划分为如下几组。
1)用于数据类型的关键字有:
boolean、byte、char、 double、 false、float、int、long、new、short、true、void、instanceof。
2)用于语句的关键字有:
break、case、 catch、 continue、 default 、do、else、 for、 if、return、switch、try、 while、finally、 throw、this、 super。
3)用于修饰的关键字有:
abstract、final、native、private、protected、public、static、synchronized、transient、 volatile。
4)用于方法、类、接口、包和异常的关键字有:
class、 extends、 implements、interface、 package、import、throws。
5)保留字:
cat、 future、 generic、inner、 operator、 outer、rest、var、goto、byValue、cast、const 等都是Java尚未使用,但以后可能会作为关键字使用。
另外,Java 还有3个保留字:true、false、null。它们不是关键字,而是文字,包含 Java 定义的值。和关键字一样,它们也不可以作为标识符使用。
内容导视:
注释是对代码的解释说明,方便理解代码的含义,提高代码的可读性。
注释不是编程语句,因此被编译器忽略。
如果不写注释,时间久了或代码过长本人也看不懂,所以编写注释是一个良好的习惯。
注释有三种,依次介绍。
使用双斜杠 //,// 后的就是注释(仅一行),不会被编译器当成 java 语句。
对于很多内容,单行放不下,可以使用多行注释,在 /**/ 里内写下内容,星号别省略。
下面看看就行,以后使用开发工具 IDE 自动生成,没必要手动敲。
文档注释可以被 javadoc 命令解析,生成以网页形式(html)显示的 API 文档。(Application Programming Interface:应用程序编程接口)。
当类又多又杂,一个个找类、看注释很麻烦,于是提取出来生成网页。
用来说明类、成员变量和方法的功能。不用在一个一个 java 文件中查看注释,直接打开 html 查看想要的方法。
javadoc 默认只提取 public、protected 修饰的部分,javadoc -help
查看可加的选项。
javadoc 命令只能提取文档注释。让我们试试吧。
javadoc Hello.java -encoding UTF-8 -version -author -private -charset UTF-8 -docencoding GBK
当前目录会生成 index.html 文件,双击此文件,交给浏览器解析(会自动打开浏览器),右键查看页面源代码,API 文档里的信息是读取 Hello.java 文件得来的。
使用此命令还可以追加其他 java 源文件的文档注释,例:javadoc -encoding UTF-8 Hello.java H.java
javadoc 命令中的参数说明
-encoding 是告知 java 源代码所用的字符编码;
-version、-author 是显示版本和作者;
-private 是显示所有类和成员;(包括显示私有,一般显示 protected 以上级别就行,可以不加此选项)
-charset 是告知浏览器此文件采用什么编码方式读取这个文件;
即 html 文件生成 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-docencoding 是指定生成的 html 文件的字符编码,不写此选项,默认 UTF-8。
由于文件被保存时的编码和读取时采用的编码不一致会出现乱码,所以别掉坑。咳咳,你知道自己的文件编码吗?在哪如何查看?编码是什么?你可以先了解下相关知识,或者你之前已经掉坑了,不知道满屏的 GBK 不可映射是啥意思,后面再讲好吗?
使用 -d
指定文件在 E:ac
下生成,很抱歉让你的桌面生了一大堆 html 文件。
javadoc Hello.java -d E:ac -version -author
代码一改,注释说明也得跟着改;为了避免无用功,代码中给标识符命名,见名知意,最好让所有人看到这段代码就知道它是干什么的,避免冗余无效注释。
示例如下:
以后有了 IDEA 工具再试,现在不用看,直接跳过;放心 IDEA 工具中会更详细地说明。
在 IDEA 中每创建一个类时,自动在类上加注释
左上角 File/Settings/Editor/File and Code Templates,includes/File Header
点击 apply 和 OK。
在方法上加注释
左上角 File/Settings/Editor/Live Templates
点击加号 Template Group 自己创建个组后,再选择你刚刚创建的组点击加号 Live Template。
解释:
当输入 Abbreviation 所写内容”**
“时,按下 Enter 就把 **
转成 Template text 中的内容
被 $$
包围的变量需要点击 Edit vaiables 设置。
选择 Define 勾选 Java,就可以定义此模板只有在编写 java 文件才能使用。
点击 apply 和 OK。
然后我又定义了一个方法模板,缩写词:psvt;设置好后 OK 返回。
在 java 文件输入 psvt 后按下 Tab 键,光标停在 $VAR$
等我们输入;按下回车,光标到了 $END$
处。
内容如下:
本节片段提取:
友情提示,先复制文本,转换后直接粘贴。目的是避免转换编码后造成中文乱码,又得一个个改。
有 2 种方式解决:
1)文件/另存为副本,更改编码为 ANSI。(如果使用的是 notepad++,就在上方的工具栏的编码,转成 ANSI 编码)
2)指定使用的编码格式。(编码格式在文本编辑器的右下方)-encoding UTF-8
是指定文件编码格式是 UTF-8。
正文如下:
可能编译时由于代码(包括注释里面)中有中文,编译时说什么含有 GBK 的不可映射字符,不让通过。我相信新手的第一道关就卡在这,有人就干脆不写中文了。
为何报错
计算机只认得二进制数,也就是 0 和 1,存储和读取数据时都要使用二进制数表示。
0 和 1 可以有很多的组合,如 011、1001010 等等。可以用它们表示不同的数据,字符编码就是人为定义的一套转换表,规定一系列文字与二进制的映射关系。
(这里未区分字符集与字符编码的概念)
有多种字符编码,比如 ASCII 码,一般是 8 位二进制表示一个字符,如字符 ‘a’ 对应 01100001,这个二进制码转为十进制是 96;
学过概率的知道,8 位数,每位是 0 或 1,最多可以表示 2 ^ 8 = 256 个字符,应对 26 个英文字母绰绰有余。这 8 位称为 1 个字节(byte),单个位称为 bit。
2 ^ 8 即 2 的 8 次方,只是为了方便表达。有的网站不支持上标、下标语法时,你会看到 2^8^、2~8~,分别对应 28、28。
ASCII 是美国人定义的,没有考虑其它国家。但我们国家用的不是英文,有很多字符是 ASCII 码没有的,1个字节也表示不了那么多的汉字,于是国人粗略规定了 GB2312,使用 2 个字节(16位)表示一个汉字。
如在 GB2312 编码中 “中国” 对应的二进制数 11010110 11010000 10111001 11111010,要是系统采用 ASCII 码读取这段二进制,由于它们定义的字符的映射关系都不一样,ASCII 编码也不可能有中文对应的二进制码,所以解码不可能正确,解析不出来就会乱码。
这里二进制数每 8 位隔开,只是方便你们观看,实际使用时还是合在一起。
来,我们使用记事本试试看。此处文件编码为 ANSI,使用 ANSI 编码读取文件,没有乱码,显示 “天下”。
ANSI 代表系统默认编码方式,在中国是 GBK,放心 GBK 兼容 GB2312,使用 GBK 可以解析 GB2312。
举个例子,如果 ASCII 中所有字符对应的二进制码,在 GBK 中,对应关系也同样如此,就说明 GBK 兼容 ASCII 码。说人话就是 01100001 在 ASCII 中表示 ‘a’,在 GBK 中也表示 ‘a’。那么使用 GBK 编码读取 ASCII 文件没有问题,反过来则不一定,因为 GBK 还多了 ASCII 中没有的汉字。
让我们把文件编码转成 ISO-8859-1,也使用此编码读取文件。
现在再看看,这不就乱码了吗?
所以解码和编码都要使用同一套字符编码规则,notapad++ 可以使用不同的编码方式解析,你测试哪些编码是兼容的,不会乱码。
编码:字符 -> 二进制码
解码:二进制码 -> 字符
底层存储的实际是二进制码。
使用 javac 命令编译时,如果不指定 -encoding 选项,一般默认采用操作系统的字符编码方式,我们是 GBK。
在编写代码时,文本编辑器的右下角会显示当前文件的编码格式。编译时,若与系统当前编码不一致,不是同一套字符编码规则,解析不出来,就会报错;以后讲 char 类型时还会深入,现在讲的很浅显,看不明白很正常,不是你的原因。(我移到扩充内容中了)
两种方式解决
告知此文件的编码方式。
例:当前文件的编码格式是 UTF-8,文件是 Hello.java,编译时添加 -encoding 参数指定文件编码javac Hello.java -encoding UTF-8
修改文件编码方式为 ANSI,文件另存时可以看到编码。(notepad++ 在工具栏/编码/转为…记得先全选复制,改编码后再粘贴,否则乱码没法撤回)
所有文件使用统一的编码方式,如 UTF-8,新建环境变量 JAVA_TOOL_OPTIONS
,值为 -Dfile.encoding=UTF-8
,不建议,以后使用 IDE 工具统一使用 UTF-8 编码,不需要自己在外面配。
我不写中文了,不建议,你是中国人,要不是英文通不过编译,我还真想全部使用中文符号。
通过 java 代码查看
通过 DOS 窗口查看
打开 DOS 窗口(Windows + R,输入 cmd 回车),点击左上角图标/属性
看到了没有,我没有画圈哦。当前代码页是 936,对应简体中文编码 GBK。
代码页是字符集编码的别名,也称内码表,下面是代码页与编码的对应关系:
也可通过 DOS 命令查看当前编码:chcp
。
修改当前 DOS 窗口的编码:chcp 对应编码的代码页
,如chcp 936
,当控制台不支持中文时,可以试试。(重新打开 DOS 窗口时会失效,恢复原来默认编码)
修改系统编码
如果是 Windows10,打开设置(Windows + i),时间和语言/语言/管理语言设置/更改系统区域设置,
老版本的使用控制面板/时钟和区域/区域/管理/更改系统区域设置。
下面还有 beta 版(即测试版),使用 UTF-8 编码提供全球语言支持;但有些地方莫名其妙的乱码,不建议尝试,还是 GBK 靠谱。
作者:,内容:修改 cmd 控制台默认代码页编码的几种方法【GBK、UTF-8】,
解决了中文乱码后,来看看 rt.jar 包中的类、方法、字段上的文档注释生成的 API 文档。
JDK17 API文档:
JDK8 API文档:
JDK8 API中文文档:
就是记不住方法名怎么办,翻阅 API 文档查看方法的作用,你得首先记住哪个类好像有这个方法。
Java 语言提供了大量可供使用的基础类,Oracle 为这些类提供了对应的 API 文档,告诉开发者如何使用此类,以及方法。
通过包名 -> 类名 -> 方法这样的方式寻找。
以 JDK8 为例,哦,对了,将最上面的广告关掉。
如果不知道类在哪个包下,点击最上方的索引(INDEX)
以这种方式,的确没有 API 文档访问方便不是吗?(养成在方法上写文档注释的好习惯,这样方便提取出来)
这是谷歌翻译:
编译与运行
先编译成 .class 文件,后运行此类的 main 方法。
程序员可以命名的单词是标识符,如类名、方法名、变量名、接口名、常量名。
命名规则
命名规范
注释
合理使用注释,解释代码含义,方便他人阅读。
编码
使用 UTF-8 格式编写源文件更通用。
2.1 为什么 Java 代码可以做到一次编译,到处运行?
2.2 一个源文件可以生成多个 class 文件吗?
2.3 Java 源文件定义的类名必须与文件名一致吗?
1.1 JDK 和 JRE 的区别?
JDK(Java Development Kit)Java开发工具包,包含了 JRE 和开发工具(javac.exe、javadoc.exe、javap.exe 等),不仅可以运行 Java 程序,也可以开发 Java 程序。
JDK 中包含 JRE,如果只想运行 class 文件,JRE 就足够。
1.2 什么是编程?
编程:解决某个问题而使用某种编程语言编写程序代码控制电脑得到结果的过程。
使用高级语言编写的源代码需要进行编译或解释,能够让操作系统识别,理解你的意图,接收一系列的指令去一步步操纵硬件工作,最终解决某个问题。
1.3 Swing 组件是什么?
1.4 JAR 包是什么?
1.5 软件与程序指的是什么?
软件可以完成特定的功能,可以理解为应用程序的集合。而应用程序是软件的一个组成部分,它是软件的必要元素。简单来说,软件 = 程序 + 文档 = 数据结构 + 算法 + 文档。
程序指计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合。
1.6 什么是编译型语言和解释型语言?
使用计算机语言(一大串二进制数)或汇编语言,一个指令只能对应一个操作中的一个细微的动作,太繁琐,不利于记忆,容易出错,开发效率极低。计算机语言能够被计算机直接识别,执行效率最高。(面向机器)
后来生成了高级语言,方便让人类理解,开发效率高。但是编写的源代码不能被机器识别,需要翻译成机器可以识别的语言,请看下答的平台无关性。
1.7 Java 语言特性?
1)面向对象
面向对象虽然执行效率没有面向过程高,但是以类的方式管理大量代码时(一个类中有变量、方法、代码块、内部类),更加方便程序员组织和管理代码,思路更清晰不易出错。
由此才有了对象、继承、封装、多态等概念。
① 对象:使用类为模板指定参数创建的实例,通过实例可以调用类中定义的方法、访问类中的字段,不会混乱。
② 继承:解决多个类中重复出现的代码,只要继承了一个类,自动拥有这个类的全部字段和方法。(私有、构造器、静态、final除外)
③ 封装:为了保护数据,不被错误的修改;在类、字段、方法上添加访问权限修饰符,如 private,只允许在本类中访问,再提供公开的 set 与 get 方法以供别人修改(在方法中可以添加判断逻辑来决定是否赋值)或访问本类的字段。此外还有包机制可以管理大量的类,可以区分两个同名类、将类似功能的类放在同一个包下…
④ 多态:子类继承了父类,但不满意父类的方法实现,可以重写此方法,表面是父类型,但可能底层为子类实例,调用的方法是子类重写后的方法,展现了不同的结果。
然后使用 new 关键字创建狗,同时指定狗的初始属性值。
new Dog(3, "土狗");
② 继承:想一想子女能够继承父母的财产吧。
③ 封装:父母可不能什么都让你访问,总要有自己私人的东西吧。
④ 多态:你老爸有事不能去了,你可以代替老爸,以他的身份参加这次宴席,你要是不满意老爸继承给你的如何为人处事的方法,可以使用自己的方法应对这些客人。
当然你如果不想使用面向对象,嫌麻烦还要设计字段、方法,也可以把所有变量、方法都塞进一个类中,只是看着乱糟糟的,不好维护。(代码量很少时,没有必要使用面向对象)
2)平台无关性
编写出的代码不可直接被机器识别,需要工具进行转换。
先讲编译器与解释器的区别:
① 编译器将源代码一次性全部翻译,生成一个二进制码文件,这个文件可以直接被机器识别,执行效率高。如果源代码改动需要重新编译生成新的二进制码文件。
② 解释器将源代码逐行解释成特定平台的机器码,解释一行执行一行。每次执行都需要翻译,跨平台性好。
Java 的做法:
之所以这么做,是 Java 既想保持解释语言的跨平台性(可移植性),又想解决解释语言执行效率低的问题。
但效率还是不如编译性语言。为了避免解释型语言带来的执行效率低的问题,Java 设计者制作了 JIT(just in time compilation)实时编译程序,将运行频率很高的字节码直接编译为机器指令执行来提高性能。
① 给一个英语文件,你看不懂,有人直接将英语文件翻译成汉文,将翻译的结果保存在一本书中,给你发过去;这样你每次就直接看这本翻译后的书即可,缺点是原著改了,你又需要请他翻译一下。
② 有人跟在你身边,你看一句,他就说一句这是什么意思;即使你换了一本英语书,他照样解释给你听,只不过效率低。
③ 有的人没有直接翻译成汉文,而是记录了源文件的重要信息、文章主题、中心思想、具体脉络等,再以后看到这份批注,能够迅速理解原文含义,get 到这个点,能够不假思索说给你听。
后来发现也挺麻烦,他干脆挑出你最喜欢、频繁看的部分,将这部分先翻译好了,等你需要看别的地方时,再请教他。
所以不要纠结这个语言究竟是编译执行、还是解释执行,没有多大意义。
3)支持多线程
a)线程与进程
单线程:一个进程同一时刻只有一个线程。
多线程:同一时刻有多个线程用以完成任务。
b)CPU 处理线程的方式
① 并行:同一个时刻,多个任务同时执行(多个 CPU)
② 并发:同一个时刻,多个任务交替执行(单个 CPU),通过 CPU 调度,速度十分快,造成貌似同时执行的错觉。
③ 串行:按先后顺序依次执行任务,一次只做一件事。后面的任务想要执行,必须等前面的任务执行完毕。
c)线程之间的关系
① 同步:一个线程需要等待另一个线程执行完毕,返回了消息,才能继续往下运行。
② 异步:一个线程 A 对另一个线程 B 发起请求,可以不用等待 B 返回消息,因为 B 线程执行完后会通知你,你直接去干别的事情了;等到接受通知后,再处理。
d)单个线程的状态
① 阻塞:一个线程在等待的过程啥也不干。
② 非阻塞:没必要一直等待,可以干别的事。
异步非阻塞:快递员给你发短信,说快递放到菜鸟驿站了;随后没有等你来拿,直接把短信继续发给下一个人。直到你签收后,他那边才接收到消息,然后做相应处理。
异步阻塞:别人拿完快递后,自然会有信息通知你,你完全可以做其他事情,却还在那傻等。
4)安全性
双亲委派机制可以防止恶意加载同名字节码。
5)健壮性
异常处理机制:对可能出现异常的代码实现进行预先处理,防止遇见问题时,程序直接挂掉。
垃圾回收机制:自动清除长时间没使用的对象,防止内存泄漏(内存满了),这也算是简单性吧。
6)简单性
JavaSE 标准版,包含核心类库。主要用来开发桌面应用,允许在桌面、服务器开发和部署 Java 应用程序。
JavaEE 企业版,帮助企业开发和部署可移植、可伸缩且安全的服务端 Java 应用程序,包括 Web 网页后台开发等。
2.1 为什么 Java 代码可以做到一次编译,到处运行?
编译生成的 .class 文件与具体平台、系统无关。
这么做的目的,在可移植的同时兼顾执行效率。此外还加入了 JIT(just in time)编译器,把运行频繁的代码直接编译成与本地平台相关的机器码,需要时直接使用,不用再次翻译。
2.2 一个源文件可以生成多个 class 文件吗?
可以,源文件只要按规则定义了多个类,编译后会生成多个对应的 class 文件。
2.3 Java 源文件定义的类名必须与文件名一致吗?
不是,只有被 public 修饰的类名必须与源文件名一致。
Linux 基本使用和 web 程序部署
Linux 背景知识
Linux 是什么
Linux 是一个操作系统. 和 Windows 是 “并列” 的关系.
Unix & Linux 发展历程图
这俩大佬本来是想开发一个操作系统, 但是开发着开发着, 发现现有的编程语言不太好使, 于是俩人 一合计, 先整个编程语言出来吧. 于是C 语言 就诞生了.
Dennis Ritchie 大佬 2011 年就去天堂写代码了. Ken Tompson 大佬后来在 google, 又参与发明 了 Go语言.
点击立即认证, 按照系统提示, 完成实名认证即可(认证速度很快).
4. 购买完成后, 可以在控制台中找到自己买的服务器. 点进去能够看到服务器的 IP 地址.
XShell 提供了两种授权方式.
邮箱中收到的内容形如:
如果 unzip 命令找不到, 则先 yum install unzip
即可.
在tomcat文件目录下apache-tomcat-8.5.47/bin
如果进程存在或者端口状态正确(LISTEN状态)或者能够访问到默认主页, 说明启动成功.
tomcat更改端口号
详见:
5) Tomcat 的目录结构
Linux 的 Tomcat 目录结构和 Windows 完全一致. (就是同一个 zip 包解压缩出来的)
使用 vim 或 less 查看该文件内容即可.
工作中涉及到的 “环境”
把程序拷贝安装到生产环境上, 这个过程称为 “部署”. 也叫 “上线”. 这个过程需要拷贝对应的 .class 文件和依赖的资源文件(各种配置文件, html等) 一旦程序部署成功, 那么这个程序就能被外网中千千万万的普通用户访问到.
换句话说, 如果程序有 BUG, 这个 BUG 也就被千千万万的用户看到了.
部署过程至关重要, 属于程序开发中最重要的一环. 一旦部署出现问题, 极有可能导致严重的事故(服务器 不可用之类的).
为了防止部署出错, 一般公司内部都有一些自动化部署工具(如 Jenkins 等). 当前我们先使用手工部署的 方式来完成部署.
将本地代码上传到 github / 码云上
过程略, 参考之前的 git 使用过程.
按照之前的数据库建表脚本, 在服务器上运行, 建立相同的表结构.
切换到项目的主目录(包含 pom.xml的目录), 使用 mvn 打包项目
此时在 target 目录下就会生成对应的 war 包.
曾经我们主要是在 IDEA 中通过图形化工具来使用 mvn. 事实上 mvn 本质是一个基于命令行的工具.
曾经在 IDEA 上进行的 mvn 操作在 Linux 中同样也可以通过命令行来完成.
将war 包拷贝到 Tomcat 的 webapps 目录中.
稍等片刻, Tomcat 会自动解压缩 war 包, 完成部署.
注意: 如果该项目之前部署过, 需要先删除之前的包.
在浏览器上访问项目的链接. (按照项目的功能进行验证).
1. 验证账户注册登录
2. 验证展示博客列表
3. 验证新增博客
4. 验证展示博客内容
5. …
注意事项:
作者 | 王磊
来源 | Java中文社群(ID:javacn666)
Java 语言中无论是线程还是线程池,默认都是用户线程,因此用户线程也被称为普通线程。
以线程为例,想要查看线程是否为守护线程只需通过调用 isDaemon()
方法查询即可,如果查询的值为 false
则表示不为守护线程,自然也就属于用户线程了,如下代码所示:
以上程序的执行结果为:
从上述结果可以看出,默认情况下主线程和创建的新线程都为用户线程。
PS:Thread.currentThread() 的意思是获取执行当前代码的线程实例。
守护线程(Daemon Thread)也被称之为后台线程或服务线程,守护线程是为用户线程服务的,当程序中的用户线程全部执行结束之后,守护线程也会跟随结束。
守护线程的角色就像“服务员”,而用户线程的角色就像“顾客”,当“顾客”全部走了之后(全部执行结束),那“服务员”(守护线程)也就没有了存在的意义,所以当一个程序中的全部用户线程都结束执行之后,那么无论守护线程是否还在工作都会随着用户线程一块结束,整个程序也会随之结束运行。
那如何将默认的用户线程修改为守护线程呢?
这个问题要分为两种情况来回答,首先如果是线程,则可以通过设置 setDaemon(true)
方法将用户线程直接修改为守护线程,而如果是线程池则需要通过 ThreadFactory
将线程池中的每个线程都为守护线程才行,接下来我们分别来实现一下。
如果使用的是线程,可以通过 setDaemon(true)
方法将线程类型更改为守护线程,如下代码所示:
以上程序的执行结果为:
要把线程池设置为守护线程相对来说麻烦一些,需要将线程池中的所有线程都设置成守护线程,这个时候就需要使用 ThreadFactory
来定义线程池中每个线程的线程类型了,具体实现代码如下:
如下图所示:
如上图所示,可以看出,整个程序中有 10 个守护线程都是我创建的。其他几种创建线程池的设置方式类似,都是通过 ThreadFactory
统一设置的,这里就不一一列举了。
通过前面的学习我们可以创建两种不同的线程类型了,那二者有什么差异呢?接下来我们使用一个小示例来看一下。
下面我们创建一个线程,分别将这个线程设置为用户线程和守护线程,在每个线程中执行一个 for
循环,总共执行 10 次信息打印,每次打印之后休眠 100 毫秒,来观察程序的运行结果。
新建的线程默认就是用户线程,因此我们无需对线程进行任何特殊的处理,执行 for
循环即可(总共执行 10 次信息打印,每次打印之后休眠 100 毫秒),实现代码如下:
以上程序执行结果如下:
从上述结果可以看出,当程序执行完 10 次打印之后才会正常结束进程。
以上程序执行结果如下:
从上述结果可以看出,当线程设置为守护线程之后,整个程序不会等守护线程 for
循环 10 次之后再进行关闭,而是当主线程结束之后,守护线程只执行了一次循环就结束运行了,由此可以看出守护线程和用户线程的不同。
守护线程是为用户线程服务的,当一个程序中的所有用户线程都执行完成之后程序就会结束运行,程序结束运行时不会管守护线程是否正在运行,由此我们可以看出守护线程在 Java 体系中权重是比较低的。
守护线程的使用需要注意以下三个问题:
守护线程的设置 setDaemon(true)
必须要放在线程的 start()
之前,否则程序会报错。
在守护线程中创建的所有子线程都是守护线程。
使用 jojn()
方法会等待一个线程执行完,无论此线程是用户线程还是守护线程。
接下来我们分别演示一下,以上的注意事项。
当我们将 setDaemon(true)
设置在 start()
之后,如下代码所示:
以上程序执行结果如下:
从上述结果可以看出,当我们将 setDaemon(true)
设置在 start()
之后,不但程序的执行会报错,而且设置的守护线程也不会生效。
以上程序执行结果如下:
从上述结果可以看出,守护线程中创建的子线程,默认情况下也属于守护线程。
通过 3.2 部分的内容我们可以看出,默认情况下程序结束并不会等待守护线程执行完,而当我们调用线程的等待方法 join()
时,执行的结果就会和 3.2 的结果有所不同,下面我们一起来看吧,示例代码如下:
以上程序执行结果如下:
通过上述结果我们可以看出,即使是守护线程,当程序中调用 join()
方法时,程序依然会等待守护线程执行完成之后再结束进程。
守护线程的典型应用场景就是垃圾回收线程,当然还有一些场景也非常适合使用守护线程,比如服务器端的健康检测功能,对于一个服务器来说健康检测功能属于非核心非主流的服务业务,像这种为了主要业务服务的业务功能就非常合适使用守护线程,当程序中的主要业务都执行完成之后,服务业务也会跟随者一起销毁。
首先来说,线程的类型(用户线程或守护线程)并不影响线程执行的优先级,如下代码所示,定义一个用户线程和守护线程,分别执行 10 万次循环,通过观察最后的打印结果来确认线程类型对程序执行优先级的影响。
以上程序执行结果如下:
通过上述结果可以看出,线程的类型不管是守护线程还是用户线程对程序执行的优先级是没有任何影响的,而当我们将 t2
的优先级调整为最大时,整个程序的运行结果就完全不同了,如下代码所示:
以上程序执行结果如下:
通过上述的结果可以看出,程序的类型和程序执行的优先级是没有任何关系,当新创建的线程默认的优先级都是 5 时,无论是守护线程还是用户线程,它们执行的优先级都是相同的,当将二者的优先级设置不同时,执行的结果也会随之改变(优先级设置的越高,最早被执行的概率也越大)。
在 Java 语言中线程分为用户线程和守护线程,守护线程是用来为用户线程服务的,当一个程序中的所有用户线程都结束之后,无论守护线程是否在工作都会跟随用户线程一起结束。守护线程从业务逻辑层面来看权重比较低,但对于线程调度器来说无论是守护线程还是用户线程,在优先级相同的情况下被执行的概率都是相同的。守护线程的经典使用场景是垃圾回收线程,守护线程中创建的线程默认情况下也都是守护线程。
关注公号「Java中文社群」查看更多有意思、涨知识的并发编程文章。
原创不易,点个赞再走呗~
gg修改器框架官网下载中文,GG修改器框架官网下载,打造游戏优化利器 大小:16.86MB3,939人安装 对于热爱游戏的人来说,游戏卡顿卡死是一个常见而又令人头痛的问题。GG修改器框架是……
下载gg修改器免root版u型,GG修改器免Root版U型游戏修改神器 大小:17.45MB3,802人安装 作为一名游戏玩家,我们总会遇到一些困难,比如闯关难度太大、游戏元素不足等。甚至……
下载gg修改器不需root_gg修改器 大小:13.39MB4,951人安装 大家好,今天小编为大家分享关于gg修改器不需root_gg修改器的内容,赶快来一起来看……
下载gg修改器免root链接_gg修改器免root版链接 大小:5.92MB4,764人安装 大家好,今天小编为大家分享关于gg修改器免root链接_gg修改器免root版链接的内容,……
下载gg修改器免root正版,gg修改器免root正版让游戏更好玩 大小:7.54MB3,747人安装 现在的手机游戏越来越火爆,各种类型的游戏层出不穷。但是很多游戏的难度都很高,需……
下载光遇gg修改器root_光遇gg修改器怎么刷蜡烛 大小:14.02MB4,945人安装 大家好,今天小编为大家分享关于光遇gg修改器root_光遇gg修改器怎么刷蜡烛的内容,……
下载gg修改器最新版中文版下载_gg修改器最新版 大小:19.13MB4,904人安装 大家好,今天小编为大家分享关于gg修改器最新版中文版下载_gg修改器最新版的内容,……
下载gg32位修改器最新,GG32位修改器最新版,你值得拥有的超级工具! 大小:3.55MB3,794人安装 在人们越来越需要自己打造娱乐和游戏的时代,一款专门用于修改游戏的软件便日益受到……
下载gg修改器中文下载OPPO_gg修改器中文下载官网 大小:7.41MB4,892人安装 大家好,今天小编为大家分享关于gg修改器中文下载OPPO_gg修改器中文下载官网的内容……
下载2020最新版gg修改器,【2020最新版gg修改器】强劲能力让你轻松登顶游戏巅峰 大小:13.35MB3,669人安装 gg修改器是一款全新升级的游戏辅助工具,它可以帮助玩家真实的体验到游戏的高潮和乐……
下载