承上启下 - 要来了,暑假实习


百度实习

去年年末拿到了百度上海研发中心的实习offer,当时还在期中考试。不过毕竟机会难得,还是在考完期中之后毅然决然的翘掉了之后的课,只身来到了上海。当然,中间省略掉了,向各方打探该不该出去实习,以及试探辅导员关于实习的态度的等情节…

面试、意外、处分,什么的讲过太多次了,不提了。还是得静静来想想收获了什么。

1.大公司的氛围

百度被黑得再惨他目前也是国内一线互联网公司。且不考虑我们接触不到的高层决策等方面,仅仅作为一名底层的技术岗实习生所看到、感受到的来说,百度的确拥有一个互联网大厂应有的环境。

入职前听到有学长提起过三大厂的新人培养机制,百度的新人培养机制是很不错的。这里我无法和其他两厂进行比较,毕竟目前只待过一家,不过百度的实习生培养机制的确很好。

在我拿到offer后因为期中考试推迟入职时间的时候,主管茜姐就打了个电话(当时甚至错当成了HR…)表示没问题,同时说关于个人的培养计划已经定好了。从个人的体验来看,主要是根据当前的部门的业务需求拟定培养计划,由导师带领先熟悉部门,熟悉项目,这段时间不进行什么业务上的工作,基本是看文档,配环境,记笔记。之后导师带领给你分配写小任务上手,比如修改bug,增加个小功能这样。后面再到就是和其他组人一起做些对接的任务等等。大概就这样,不过可能个其他的公司也是差不多的流程吧。

不过上面说的主要是工作时的,就像阿里学院和腾讯大学,百度也有自己的内部学习库,里面有着丰富的学习资料,涉及到各个技术领域。同时经常会收到技术分享会,技术交流会的邮件通知,虽然很惭愧,我一次也没去过…想想还是有些遗憾的…

还有很多很多的感受,比如一个不打卡的公司,真的需要一定的自制力来使自己保持学习的热情和竞争力。一个完善的内部交流机制,保证了执行的效率和按部就班。

技术上的提升不好泛泛而谈,这里也就不提了。

第一次实习经历中间有些不愉快但是最后结局还是好的,感谢百度上研的各位~

2.独居生活

实习时的独居生活真是让我百感交集。

曾经尝试过一个人去凤凰,这次又一个人来到了上海。我显然低估了自己对陌生环境的抵触。

当时投简历时,没管那么多,毕竟机会比较难得,也很感激凯宁学长的热心帮助,部门是在上海的研发中心。而在上海的小伙伴没有那么多,几个一起拿到百度offer都去了北京,真是 一个人寂寞如雪。

到达的第一天,下着雨,魔都11月的雨啊,淅淅沥沥,淋在身上淋了一个透心凉。拖着行李箱,到站的时候正赶上上班高峰,看着满满的一车人,拖着个行李箱的我没好意思跟他们挤,站了一会,等到人稍微少了一些,拖着行李想坐上了地铁,准确说是站着,怎么可能有位置给你坐。

然后就是人生中第一次和万恶的房屋中介打交道了。果然,网上的信息都是假的,一切以实物为准,图片仅供参考这句倒是真的。最后租到了一间1500的房子,装修比较简陋,虽然和房东一起,但是房东听口音就知道是外地来的。也是图便宜,另外一家1700,装修好,甚至合租的还有妹子。现在想想有点小后悔。

整个房子就我和房东两家,还有孩子,睡得比较早,一开始想着反正就每天上下班,房子也就是个放床睡觉的地方。后来渐渐发现,每天回来之后,整个房子黑黑的,回到房间打开灯,看着房间里简陋的摆设,真的一种孤独感袭来。尤其是在到达的第一晚,被子还没到,我是把所有的衣服都拿出来蜷缩在床上过了一夜,然后爬起来就去报道入职了。在之后的阴雨绵绵的周末里,天气不好也只能宅在房间里,渐渐的觉得宅是真的可能宅出病了。(托尔带着康娜倒是带给我一丝慰藉…)

我是不会再想去过一遍这种生活了。可能也是性格问题,在陌生的环境里总是小心翼翼,虽然希望融入环境,却总在一开始的时候不得其法(这个问题直接反应到我和妹子聊天不太会找话题啊喂…)


离职归来

最后无奈之下趁着清明节假期又去上海办了个离职,结束了人生的第一次实习。

实习归来之后的一段时间还真是有点颓废的,可以说是变懒了,而这时周围的同学却都开始紧张起来了。毕竟已经大三下了啊。看到周围的同学,考研的开始组成图书馆小分队,天天泡在图书馆;工作开始关注各路的招聘信息,开始“站队”前端后端;保研的同学也在时刻关注着各路的信息,并争取在最后一个学期为名次再战一次;出国的可能还在备考雅思托福,也可能忙着发论文申学校。这些改变渐渐在身边发生,而这时的我却一说是有些麻木。

麻木,懵逼了一阵子,这时候各大厂自然没有等待懵逼的我。蓝杰群里的诸位学长学姐大开内推通道,而这些我差不多都错过了,任机会流失。再醒悟时,阿里的内推也快要截至了。这时周围一些人已经拿到了阿里,腾讯的实习offer,这才觉得自己真的掉队了。开始各种疯投简历,见到一个邮箱就把简历发过去,看到哪里有面试机会也去凑一凑。中间腾讯的霸面挂掉了,这一次给我的打击挺大的。我和室友一起去面同样的岗位,而室友打败了我得到了下一轮面试机会。而从简历上客观来看,室友的简历在经历上都要逊色。而最后我还是输了,那天晚上没收到复试的通知,心情很乱,觉得自己前段时间的麻木和懵逼现在看来更像是一种莫名其妙的自大。

之后的日子,也挂过笔试,也沮丧过,不过总还是抱着希望和信心。后面顺利拿到了热璞的offer,有了一个“保底”之后,我却丝毫不减投简历的热情。再到后面就是拿到了格灵深瞳的offer,听胡总说是在颐和园办公还唬了我一下。

拿到offer后这次稍微安心一些了,不过在胡总的宣(hu)传(you)之下,让我找天晚上建个群传授一下人生经验…看着群里的很多都是已经毕业的传说中的学长学姐,自己那点东西真是拿不上台面。自己渐渐也成为了学弟学妹眼中的大神学长,自己却是最了解自己几斤几两的。格灵深瞳据说是个藤校C9遍地的公司,来吧,求虐。


暑期实习

苟活过了考试周,处在考试周和小学期的夹缝中。老苗收拾了东西奔向了帝都,本来打算和老苗合租一下当个室友,后面又拉上了鲲总。三个人就比较美滋滋了,虽然觉得就我的情况最尴尬。

鲲总是软件年级第一,准备保研清华,出来实习只是为了体验生活(非原话…),而且软件大四是实习抵学分的。

老苗是外语院的…是他湖的信安会长,不了解他们的实习政策,不过应该比我们好说话得多,而且没小学期。

我是身背处分的他湖学子,我们学院又提倡“精神鼓励”实习,就是那种喊着“你们一定要出去实习,你们全都要出去实习”,然后就是不准你假的那种。大概是类似神交的精神实习。所以我真的不知道我这次的实习之旅是什么样的结局。不过现在谈这个太早了,还是好好期待吧。

老苗去的最早,张罗着找房子,与中介斗智斗勇,还碰到了北京十大黑中介。在将要确定之后,又被中介摆了一道,这时鲲总前去助阵。终于在二位dalao的不懈努力之下,房子安排妥当。环境比上次高到不知道哪里去,不过离公司有点远就是了…后面去了得尝试一下各种路线,找个最优解…

渐渐开始期待即将到来的实习生活。这次实习不会是一个终点,也希望能够成为自己的又一次蜕变,就是这样。

洋洋洒洒,断断续续码了一下午加一个晚上。(承上启下,满分!)

Hello World.

再见Wordpress

​ 原来本站是挂在阿里云虚拟主机上,使用 宇宙第一CMS(划掉)的Wordpress构建。

​ 建起来一年多了东西却寥寥无几,有营养的就更少了。真是太堕落了,反观某dalao老苗倒是干货湿货(???)满满,真是肥肠惭愧。

​ 正巧觉得Wordpress太笨重了,同时考完试了在等小学期的咸鱼的这几天把博客从用Wordpress构建美滋滋地换到Hexo

​ 之前的文章只保留部分。就这样,希望这次可以时常记得更新。

​ ——pixiv 坐生

写个JVM构建工具相关的吧(总是要写点什么的)

Ant、Maven、Gradle的东西在笔记里放了好久了,现在拿出来写写。


在两只狼和一只狗的时代。

人们编译和运行还是靠着重复敲打着gcc和javac,这显然是件不够”优雅”的事情。于是,上帝说,要有光,世界便有了光——make出来。

make帮助人们批量的编译文件,或者说是构建工程。

而作为一个主要写Java的程序员,也有JVM生态圈中的构建工具。

主要是3个Ant、Maven、Gradle

Ant

Apache Ant是一款基于Java的构建工具,Java实现,也意味着有很好的跨平台性。开始是转为tomcat设计的,使用xml,比makefile更加简洁,后被广泛应用。

1.安装与配置

在这里找到相应的压缩包,下载解压就好了,然后配置环境变量。没什么不同的。当然,之前也得配好jdk。

之后呼出cmd,输入ant -version。可显示版本号就可以了。

2.构建ant实例

让我们脱离ide,用回最原始的javac和java。

例如这里

1
2
3
4
cd workspace
md anttest & cd anttest
md src & md bin &cd src #src 放置源代码,bin放置.class文件
notepad HelloAnt.java

之后随便写点

1
2
3
4
5
public class HelloAnt {
public static void main(String[] args) {
System.out.println("Hello Ant!");
}
}

紧接着

1
2
3
#在项目路径 anttest下
javac -sourcepath src -d bin src\HelloAnt.java #两个参数是指明源代码路径和.class文件路径 最后是编译的目标文件
java -cp bin HelloAnt #-cp即 classpath 执行

之后就可以看到Hello Ant了。(啊,上面似乎是废话。。

也尝试了使用直接打包成jar,不过还要手动写mainfest,这里不写了,直接用ant。

ant中核心的就是build.xml文件

build.xml的结构如下:

img

允许有且只有一个project元素,其中有多个target,每个target作为task的集合存在。

下面定义了四个target:

– clean 清除编译文件以及相关的目录

– compile 编译src中的文件 并放入指定的classpath

– jar 打包成jar

– run 运行

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
<?xml version="1.0" encoding="UTF-8"?>
<project name="anttest" default="run" basedir=".">
<description>Building Simple Java Applications Without An IDE</description>
<target name="clean" description="clean class file">
<delete dir ="exe"/>
</target>
<!--编译的target,执行编译命令-->
<target name="compile"
description="Compile the Java code.">
<mkdir dir ="bin"/>
<javac srcdir="src"
destdir="bin"
debug="true"
includeantruntime="false" />
</target>
<!--打包的命令,依赖于compile的target,即需要执行compile的-->
<target name ="jar" depends="compile"
description="to jar">
<mkdir dir ="exe"/>
<jar destfile = "exe/HelloAnt.jar" basedir ="bin">
<manifest>
<attribute name = "Main-Class" value = "HelloAnt"/>
</manifest>
</jar>
</target>
<target name="run" depends="clean,compile,jar"
description="Run the Java application.">
<java classname="HelloAnt" fork="true">
<classpath>
<pathelement path="bin"/>
</classpath>
</java>
</project>

target是自定义的,不是说一定会有这几个name,想要执行某一条target,可以键入

1
2
3
ant clean
ant run
ant #默认执行build.xml中name为run的target

img

xml中的元素,清晰明了,每一个target中定义了实现的命令。

xml中的元素,清晰明了,每一个target中定义了实现的命令。

关于这些标签可以去这里了解。

通过上面这个例子进行了简单项目的简单构建,在感受到简单清晰之后,也发现了一个问题,那就是随着模块的增加,bulid.xml会变得很大。

这也是ant一个很明显的缺点。

Ivy是Apache另外一个开源项目,主要解决构建中的依赖问题。他可以和Ant完美集成,所以常常一起使用,这里也放在Ant下面进行讨论。

上面的例子是个很简单的例子,也不需要有外部的依赖,如果需要用到外部的依赖可以使用ivy。

这里下载之后解压,把解压之后的ivy-x.x.x.jar文件copy到ant路径下的lib中就可以了。(也可以配置环境变来那个IVY_HOME

之后可以去ivy的路径下,去看ivy给出的示例。

在%IVY_HOME%\src\example\hello-ivy的位置执行ant,进行构建,这里有ivy.xml和build.xml。

img

可以看到从外部下载所依赖的文件,这些文件被缓存在用户.ivy2\cache目录下。

1
2
3
4
5
6
7
8
<!--ivy.xml-->
<ivy-module version="2.0">
<info organisation="org.apache" module="hello-ivy"/>
<dependencies>
<dependency org="commons-lang" name="commons-lang" rev="2.0"/>
<dependency org="commons-cli" name="commons-cli" rev="1.0"/>
</dependencies>
</ivy-module>

而在ant的build.xml中定义ivy任务实现调用ivy的功能,从而实现依赖管理的。只列出 调用ivy的功能

1
2
3
4
5
6
7
8
9
10
11
<target name="resolve" description="--> retreive dependencies with ivy">
<ivy:retrieve/>
</target>
<target name="report" depends="resolve" description="--> generates a report of dependencies">
<ivy:report todir="${build.dir}"/>
</target>
<target name="clean-cache" description="--> clean the ivy cache">
<ivy:cleancache />
</target>

只需要在build.xml中引入ivy的空间声明就可以。

3.eclipse和IntelliJ IDEA中也有相关的插件

….略了啊


Maven

maven,是在ant之后Apache又发布的另一个构建工具,旨在解决ant使用中的一些问题。不过maven还是使用了xml文件,当然,和ant相比,改变了很多。ant更像是把构建项目中的每一个任务都写下来,每个任务中进行哪些命令也都写进去。那么maven关心什么呢?

1 依赖的管理:仅仅通过jar包的几个属性,就能确定唯一的jar包,在指定的文件pom.xml中,只要写入这些依赖属性,就会自动下载并管理jar包。

2 项目的构建:内置很多的插件与生命周期,支持多种任务,比如校验、编译、测试、打包、部署、发布…

3 项目的知识管理:管理项目相关的其他内容,比如开发者信息,版本等等

1.安装配置环境

还是直接上手,下载配置环境。

2.构建简单的工程

1 mvn archetype:create -DgroupId=com.company.example -DartifactId=Example

这里的archetype是项目的模型,maven自身提供了一些项目模型,也可以通过archetype:generate进行选择。

groupId和artifactId分别是公司组织名和项目名称。当然也可以加上多包的定义,-Dpackage=com.company.hellomaven。

接着是maven的配置文件,maven对于工程的配置在pom.xml中。

那么pom.xml的POM是指什么?

POM(Project Object Model)是maven的核心思想。项目对象模型,这个文件中定义了工程的类型、名称、管理依赖关系、定制插件的行为。

当一个大项目被分成几个小项目,每个小项目拥有自己的pom文件,然后有一个共同的父项目。只有构建父项目就能构建所有子项目。

子项目的 POM 会继承父项目的 POM。另外,所有的 POM都继承了一个 Super-POM。Super-POM 设置了一些默认值,比如在上文提到的默认的目录结构,默认的插件等等,它遵循了惯例优于配置的原则。所以尽管我们的这个 POM 很简单,但是这只是你看得见的一部分。运行时候的 POM 要复杂的多。 如果你想看到运行时候的 POM 的全部内容的话,可以运行下面的命令:

1
$mvn help:effective-pom

关于pom.xml文件的编写,这里是一个pom.xml

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.honsen.test</groupId>
<artifactId>first-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<name>First Maven Project</name>
</project>

第一行指定文档的xml、版本和编码;

第二行即上面说到的每个pom.xml的核心元素——project

其中的几个元素——

1 modelVersion 这个元素指定了POM的版本,Maven2或者Maven3 都只能是4.0.0

2 groupId 是项目组的ID,一般是com.公司组织名.项目名(比如com.honsen.test)

3 artifactId 是该项目在项目组中的ID,比如当前的项目是项目组的一个代理项目,就可以叫做myproxy

4 version 是项目的版本号,用于维护项目的升级和发布

5 name 一般没有实际的用处,只是用于标识该项目

在pom文件中,通过groudId、artifactId、packaging、version等maven坐标来确定一个项目。

另外,一个工程总是需要依赖多个jar包,对于这种jar

包的管理,称之为“依赖管理”。而怎么确定jar包的坐标?maven是通过groupId,artifactId,以及version确定一个唯一的jar包。例如常用的一个Junit的声明是:

1
2
3
4
5
6
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>

那么这些jar的包从哪里获取?这里我称之为仓库。Maven中会涉及多种仓库。

1 工作空间,即我们的项目工程,这里面可能会放着pom.xml文件,这个pom.xml就是maven的配置文件

2 本地仓库,本地仓库用于存放jar包,其实Jar包并不是直接放入工作空间的,它是存放在本地仓库,然后在执行发布打包的时候,添加依赖路径

3 私库:私库是使用者自己搭建的maven仓库,用于缓解频繁从外网下载jar包资源的压力。而且使用私库作为缓存层,也相对安全一些。

4 共享仓库:书中所说的中央仓库或者一些常用的镜像网站都属于这种,国内比较著名的oschina以及163都是不错的maven仓库。

当我们在pom.xml中声明了依赖关系后

1 Maven在执行相关的任务时,会先去本地仓库查看是否有该资源,如果有的话,判断版本是否正确,如果一切都没问题则直接使用;否则,执行下一步

2 Maven会去配置的共享仓库中查找,如果找到就拷贝到本地仓库中;找不到则会给出相关的提示

3 Maven在本地如果搭建了私库,则会去私库中查找,找到就拷贝到本地仓库;找不到就会去共享仓库中查找,然后放入私库和本地库。有了私库,局域网内的开发者可以共享依赖,就不用每个人都去外网下载jar包,浪费带宽了。

关于本地仓库和共享仓库的配置都在settings.xml中,这个文件位于conf中,如果没有则拷贝一份即可。

1
<localRepository>F:\apache-maven-3.3.9\repo</localRepository>

共享仓库的地址配置:

1
2
3
4
5
6
7
8
<mirrors>
<mirror>
<id>CN</id>
<name>OSChina Central</name>
<url>http://maven.oschina.net/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>

Maven插件

我们用了 mvn archetype:generate 命令来生成一个项目。那么这里的 archetype:generate 是什么意思呢?archetype 是一个插件的名字,generate是目标(goal)的名字。这个命令的意思是告诉 maven 执行 archetype 插件的 generate 目标。插件目标通常会写成 pluginId:goalId

一个目标是一个工作单元,而插件则是一个或者多个目标的集合。比如说Jar插件,Compiler插件,Surefire插件等。从看名字就能知道,Jar 插件包含建立Jar文件的目标, Compiler 插件包含编译源代码和单元测试代码的目标。Surefire 插件的话,则是运行单元测试。

因为mvn 本身不会做太多的事情,它不知道怎么样编译或者怎么样打包。它把构建的任务交给插件去做。插件定义了常用的构建逻辑,能够被重复利用。这样做的好处是,一旦插件有了更新,那么所有的 maven 用户都能得到更新。

生命周期

上面提到了maven的插件,那么就不得不说maven的生命周期。 上面说到了maven本事不会做太多事情,是指maven的生命周期是抽象的,实际工作由插件完成。

运行的maven的每个步骤由它定义,相比较Ant需要自己去手工定义,一个固定的生命周期模板,预定义的行为让maven变得简单。而同时也一定失去了”灵活性”.

maven有三套相互独立的生命周期(之所以是相互独立,即你可以仅仅调用其中里面的一个):

clean:真正构建之前的清理工作;

default:构建本事的核心内柔,会有编译、测试、打包、部署等内容;

site:生成项目报告,站点,发布站点。

每套生命周期由一组阶段 (Phase)组成,例如

clean-|

|-pre-clean:执行一些需要在clean之前完成的工作

|-clean:移除所有上一次构建生成的文件

|-post-clean:执行一些需要在clean之后立刻完成的工作

mvn clean中的clean就是指clean这一套生命周期中的clean阶段,在一个生命周期中运行某个阶段,这个阶段之前的阶段都会被运行。就是mvn clean实际执行了pre-clean和clean。

同样的,

default-|

|-validate

|-generate-sources

|-process-sources

|-generate-resources

|-process-resources 复制并处理资源文件,至目标目录,准备打包。

|-compile 编译项目的源代码。

|-process-classes

|-generate-test-sources

|-process-test-sources

|-generate-test-resources

|-process-test-resources 复制并处理资源文件,至目标测试目录。

|-test-compile 编译测试源代码。

|-process-test-classes

|-test 使用合适的单元测试框架运行测试,这些测试代码不会被打包或部署。

|-prepare-package

|-package 接受编译好的代码,打包成可发布的格式,如 JAR ,WAR。

|-pre-integration-test

|-integration-test

|-post-integration-test

|-verify

|-install 将包安装至本地仓库,以让其它项目依赖。

|-deploy 将最终的包复制到远程的仓库,以让其它开发人员与项目共享。

site – |

|-pre-site 执行一些需要在生成站点文档之前完成的工作

|-site 生成项目的站点文档

|-post-site 执行一些需要在生成站点文档之后完成的工作,并且为部署做准备

|-site-deploy 将生成的站点文档部署到特定的服务器上

在是用eclipse时也会有maven的插件来帮助使用。


断断续续在笔记里整理了一段时间了,果然还是要po上来。

hibernate-in-idea

转到Intellij IDEA,折腾一下后写的


如果你在网上发现另一篇一毛一样的,来自leanote博客的,那也是我的


之前的那个项目用的是Spring+SpringMVC+Mybatis,用的IDE是myEclipse,而新接的这个项目就换了一种全新的姿势。

jetbrains全家桶才是王道。

虽然挺早就知道了Jetbrains全家桶的大名,不过还是一直用的eclipse,毕竟也是一个很不错的ide,免费且开源,各种插件用的飞起(毕竟是ide,装多了一定卡,,)不过据说用过intellij idea之后就不想再去用eclipse了(啧,这么叼?)

似乎废话多了

这次项目使用Spring+Struts+Hibernate,ide换成了intellij idea。

Intellij Idea的一些基本的配置和快捷键之前熟悉了,这里只说说配置Hibernate的问题。

之前的1.0版本学长用的是eclipse,所以我直接import到idea中并不是可以直接跑的,虽然idea人性化的支持直接引入eclipse(其实很多配置都要重新搞。

1.从创建一个支持Hibernate的工程开始

idea中原本就支持了很多的框架之类,所以我们在一开始只需要选上Hibernate这个选项,lib选择只要找到库文件就好。剩下起名字什么的不用多说,没什么特殊的

创建完之后是这样的

2.创建之后进行设置

如果一开始创建的时候并没有去勾Hibernate这个选项,不用慌,可以直接在File –>Project Structure的Facets模块中添加Hibernate

3.“编写”配置文件

我们需要编写Hibernate的配置文件hibernate.cfg.xml,而idea中有这个模板可以直接用。我们默认直接放在src目录下,当然我们还可以选择版本,这里是5.0的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xmlversion='1.0'encoding='utf-8'?>
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/HibernateConfigurationDTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<propertyname="connection.url"/>
<propertyname="connection.driver_class"/>
<propertyname="connection.username"/>
<propertyname="connection.password"/>
<!--DBschemawillbeupdatedifneeded-->
<!--<propertyname="hbm2ddl.auto">update</property>-->
</session-factory>
</hibernate-configuration>

4.0配置数据源

接下来进行数据库配置,找到侧边栏的database。如果找不到的话,就去view?–> Tool Windows? –> Database 点加号,添加一个数据库,这里用的是MySQL

也没什么特殊的,jdbc当然需要下载。

之后就这样的

5.直接映射生成pojo和hbm文件

在配置完数据源之后可以利用idea的工具自动生成pojo和hbm文件,也是省去了我们在编写这类重复性代码所花费的时间,也降低了编写出错概率,毕竟又是调bug最后发现是这样弱智的错误一定会抓狂的,总之大赞23333

这里我们呼出persistence模块,如果没有也请到view –> Tool Windows –> Persistence呼出。这里工具顾名思义是持久层的模块。通过这个工具建立映射

这个页面中我们可以可以选择数据源,也就是我们刚才配置的那个数据源,之后Package选择我们pojo文件的放置位置,也可以设置生成的实体类的名称,下面的Generation Setting设置实体类的内容和配置文件的生成。

效果是这样的

。。。。

今天的小葵花洪森课堂就到这里了,下课。

Java静态代码块的问题

自己测试的一点小例子,觉得有点充数的嫌疑


劳动节嘛就是劳动的节日(大雾

晚上把之前iteye里面的东西搬过来了,虽然很惭愧原本就没有写多少东西。

(不过搬完发现,之前写的东西真的看不下去啊,,TM,就搬一个好了


在查看别人代码的时候 看到了 static静态代码块 ?之后经过搜索和自己的亲试,下面贴出测试代码和解释。

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
public class TestA {
static {
System.out.println("父类--静态代码块");
}
public TestA() {
System.out.println("父类--构造方法");
}
{
System.out.println("父类--非静态代码块");
}
public static void main(String[] args) {
new TestB();
}
}
class TestB extends TestA {
static {
System.out.println("子类--静态代码块");
}
{
System.out.println("子类--非静态代码块");
}
public Test() {
System.out.println("子类--构造方法");
}
}

跑起来的结果是:

父类–静态代码块

子类–静态代码块

父类–非静态代码块

父类–构造方法

子类–非静态代码块

子类–构造方法

在这个代码中,代码的执行顺序,就是 在主类中首先执行static静态代码块中的代码,同理,之后在主函数中 建立了TestB对象,在执行构造函数之前,首先查看TestB中是否有static静态块,之后首先执行了静态代码块中的代码。当TestB的静态代码 块执行完毕之后,它接着又去看A有没有非静态代码块,如果有就执行A类的非静态代码块,A的非静态代码块执行完毕,接着执行A的构造方法;A的构造方法执 行完毕之后,它接着去看B有没有非静态代码块,如果有就执行B的非静态代码块。B类的非静态代码块执行完毕再去执行B类的构造方法,这个就是一个对象的初 始化顺序。
噫,,写出来了好像挺麻烦的。。大致就是 1静态代码块 ?–>2非静态代码块 ?–>3构造方法

然后进行了有一个测试:

这个测试是测试是否一定是静态块先执行。

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
public class TestA2 {
private static TestA2 a = new TestA2();
static {
System.out.println("父类--静态代码块");
}
public TestA2() {
System.out.println("父类--构造方法");
}
{
System.out.println("父类--非静态代码块");
}
public static void main(String[] args) {
new TestB2();
}
}
class TestB2 extends TestA2 {
private static TestB2 b = new TestB2();
static {
System.out.println("子类--静态代码块");
}
{
System.out.println("子类--非静态代码块");
}
public TestB2() {
System.out.println("子类--构造方法");
}
}

结果如下:

父类–非静态代码块

父类–构造方法

父类–静态代码块

父类–非静态代码块

父类–构造方法

子类–非静态代码块

子类–构造方法

子类–静态代码块

父类–非静态代码块

父类–构造方法

子类–非静态代码块

子类–构造方法

这里先new了一个 静态的对象

1
private static TestA2 a = new TestA2();

而 在静态代码块和创建静态对象时,是按照 代码的顺序执行的,就是说 需要执行完 这个创建对象的语句才能执行下面的 静态代码块中的语句。所以给人的感觉像是“跳过了”静态代码块,所以一开始是:1非静态代码块2构造方法。之后执行完了 创建对象的语句,继续执行,即静态代码块。之后就是在主类中创建一个TestB2对象,像上面的测试一样,不同的也只是在执行创建对象语句静态代码块和顺 序的问题。而执行了两次非静态代码和构造方法的原因就是,一次是创建静态对象时,一次是执行完静态方法后的执行。

总结:

对 象的初始化顺序:首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静 态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非 静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。总之一句话,静态代码块内容先执行,接着执行父类非静 态代码块和构造方法,然后执行子类非静态代码块和构造方法。

how2usespring

记得当时是胡总强行替我装逼之后我写的,写的很渣,不过还是不删了。

现在回归一下,这是当时做的一个商城的项目,用了Spring+SpringMVC+MyBatis,所以才有了这样的项目结构…


不过正好可以总结一下,顺带更新一下 小站 2333。不过这个文章并不算是Spring的入门指南(从入门到放弃)?,只是简单讲一下我们在项目中如何使用Spring框架的。

项目结构

首先来看看我们这个项目的结构(细节不讲)

config–项目的基本配置信息。调试日志的样式,jdbc的连接信息等配置文件

src–后台的源码部分

mqys–config ?定义一些常量接口之类的

–controller ?控制器

–entitys ?实体类

–mapper mapper层面(怎么翻译

–service ?– 服务层接口

–impl实例化方法

–utils ?工具包类

WebRoot–资源文件,前端文件

以上是我们项目的结构

开发流程

数据库层面—>service层面—>controller(前后台对接)

数据库层面

首先是entity层,oop嘛,把数据库中的每个表对应成一个实体类,比如Banner对应数据库中的t_banner。

里面是seter和getter方法

码完entity层之后,开始mapper层面,mapper层面是数据库对接的一层

每个mapper对应一个相应的entity

里面的结构大致是酱紫,Spring使用 标签给我们提供了很大的便利见下图(QQ截图没有括号 差评。。。然后自己画出来怎么又一丝猥琐,,,

在mapper层里进行了和数据库的对接,当然这里不必写一堆的方法,可以直接传一个sql语句,直接根据sql语句来实现重载的功能(mapper不要用重载,程序会不知道你调用的到底是哪个方法。

mapper层面结束之后,是service层

这里根据需要,划分成不同的service,例如AdService.java中是定义了所有广告类方法的接口,impl是接口方法的实现。

这里可以看到

标签对应,即通过标签来标识连接

具体的细节需要进行架构时多多考虑。

最后是controller层面,这时候和view层面的结合开发,前端人员写完html文件之后,后台人员(like me)拉上前端人员一起把html修改为jsp。

controller中可以通过返回map,对应到jsp

返回一个ModelAndView就是加载一个页面,在方法里通过service的方法调用来加载数据,并返回到页面上。所以一个ModelAndView方法对应一个前端页面。

讲道理的话

我讲的东西只是我们在项目中运用Spring框架的实例,属于强行上手型,更多知识和方法可以来这里看看。收工,滚去拆炸弹了

最后,在这里强烈谴责胡总这种强行替别人装逼的行为。。。果然这事还是不说的好

在VS中C++类的声明与定义

现在看着有点尴尬,不过还是老老实实一起迁移过来了…


貌似是第一篇关于代码的文章,有点惭愧啊。算了不扯了,直接进入正题。

第一篇是关于C++的,起因在于我们正在进行的数据结构课程,第一次实验课的内容是要我们用线性表来解决约瑟夫环问题。问题本身是不难的,难住我的却是如何写一个 链表的模板类。

约瑟夫环问题用链表来做更好一些,本来想实现一个线性表并不难,没想到 卡在了C++的模板类上Orz。。。最后无奈之下为了交作业,写了个int的链表急急忙忙交了上去。然后留着问题慢慢搞。下面贴出我第一次遇到的蛋疼的报错信息:

链接时错误了,这是什么意思,以前没遇到过。测试了一下,发现只要是SInglyList的函数在main函数中被调用都会报这种错,这特么就很尴尬了。说明函数定义的内容本身是没问题的,那错误会在哪里呢?向匡老师求救,觉得可能是构造函数的问题,导致建立对象的时候失败了,所以对象调用函数时自然会出现错误。

嗯,不愧匡老师,说的好像有那么一丝道理,我找了找我的构造函数

1
2
3
4
5
6
7
8
9
10
void init() {
SingleNode<E>* temp = new SingleNode<E>(NULL,NULL);
head = temp;
tail = head;
curr = head;
size = 0;
}
SinglyList() {
init();
}

我一度认为是初始化指针变量时的问题,然后一直思考自定义的变量初始化时的正确姿势Orz…

1
2
SingleNode<E>* temp;
temp = new SingleNode<E>(NULL,NULL);

然后换成了上面这个23333,C++prime白看了,不过的确排查的时候找出来一些地方写的不规范。。。

然而上面的这些都不是关键,当我觉得我的代码已经很完美的时候,还是报这样的蜜汁错误Orz…

于是我新开了一个工程慢慢的复制,运行,企图发现到底哪里出了问题。

在我一次实验中,在声明函数时先定义了一个内联函数print()然后其他的函数都是在另一个.cpp文件中定义的。结果发现只有调用这个内联函数的时候不会出错,啧,难道是只能内联函数可以?这特么不讲道理啊。我再写了一个函数定义在头文件中,当然,不是内联。然后调用这个函数就完美的运行了。。Orz

麻!萨!卡!定义和实现都只能放在头文件中?这不讲道理啊,之前在eclipse中写的套路都是声明在头文件中,定义在源文件中。一时无法解释这个问题,不过问题算是解决了,错误消除了。(我们只解决问题,不解释问题

默默贴几段代码

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
37
38
39
40
41
42
43
44
template<typename E>
class SinglyList{
public:
SinglyList() {
init();
}
~SinglyList() {
removeall();
}
void append(E);//追加
void insert(E);//插入
void remove();//移除当前结点
void alter(E);//修改当前结点的值
int currPos();//返回当前结点的位置
void moveToStart();//将当前结点移动到head
void moveToEnd();//将当前结点移动到tail
const E& getValue()const;//取得当前结点的值
void clear();//清除所有结点 并重新初始化链表
void print();//遍历打印所有结点的值
void next();//当前结点后移一位
void prev();//当前结点前移一位
private:
SingleNode<E>* head;//头节点 无数据
SingleNode<E>* tail;//尾结点 有数据
SingleNode<E>* curr;//
int size;
//初始化时 实例化一个结点,然后head、tail、curr都为它
void init() {
SingleNode<E>* temp;
temp = new SingleNode<E>(NULL,NULL);
head = temp;
tail = head;
curr = head;
size = 0;
}
void removeall() {
while (head != NULL) {
curr = head;
head = head->next;
delete curr;
}
}
};

黄总对此发表评论:因为 template 的代码都要在编译的时候根据类型参数去生成啊 如果分开写的话编译的时候代码还没产生于是就炸了

第一次阿里电面——所谓基础与实战

写下这个标题的原动力是前几天接到了一通来自 浙江杭州的电话。

嗯,是的没错,来自蚂蚁金服的电话面试,第一次面试,想想都有点小激动呢~(~o ̄▽ ̄)~o

虽然我显然是缺乏经验的,在刚开始进行自我介绍的时候就把自己是大二的事实说了出去 ( _ _)ノ|扶墙,不过面试的还算是顺利,不过也真的让我思考所谓基础与实战了。

在大学之前是没有基础和实战区别的概念的,因为都是为了考试的那种学习方式,如果强行说有,那也就是从理解概念到实际做题之间的。

而在来了湖大,入了CS坑之后,开始接触一个概念——“技术”。

起初的并不懂得技术到底是什么,并不懂得基础是指什么,而实战又是在干嘛。曾经有一段时间在岳麓山第一婚介所蓝杰那边得到一种思想(可能是我的片面理解),那就是很多时候暴力上手就好,不要老是想着什么自己没学过,自己是小白什么的。就是一个”敢”和一个”做”字,就算现在不会,做过之后你就是”专家”了。这大概就是我对实战的第一种印象,也正是深深觉得什么事情直接暴力上手就好,比如什么一下午学过C#(跟着胡总这么浪过,,),就这样忽略了另外一点——基础。

那时我从来没想过,也许我看到的那些暴力上手的先例中的学长学姐也是在做事中狠狠的打牢了基础,而不是仅仅是做出来这个东西。我们解决问题,而不解释问题,这句话曾经觉得好有道理的样子,竟然一度成为我搪塞别人的借口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
echo "Hey,这个是怎么配置的?"
echo "哦,你就这样再点这里,一路走下去就好了"
echo "哦,那这里是什么意思,为毛这么做,那样做不行吗?"
echo "......我们只解决问题,而不解释问题"
echo "啊,怎么报错了"
echo "额,我不知道啊,我当时这样是没错的"
echo "那怎解决啊,你不是懂了吗"
echo "......"
echo "Hey,这个是怎么配置的?"
echo "哦,你就这样再点这里,一路走下去就好了"
echo "哦,那这里是什么意思,为毛这么做,那样做不行吗?"
echo "......我们只解决问题,而不解释问题"
echo "啊,怎么报错了"
echo "额,我不知道啊,我当时这样是没错的"
echo "那怎解决啊,你不是懂了吗"
echo "......"

这特么就很尴尬了,如果对方是个妹子,那就更尴尬了Orz。。。。

本着急于实战的心,觉得重要的是敢做,做过一遍就会,觉得自己闷头学那些东西没有地方实践,就不知道书本上的东西和实际做起来有多少差别。正好我去了阳光100,与几个学长学姐接手了我第一个外包项目,做的时候并不顺利,Spring框架对于我是个全新的东西,对于网站的建设来说也是一点都不懂,靠着匡老师和百度外加墙外的指点,一点点爬过来了,算是把东西做出来,其中走了不少的弯路,很多东西都不懂导致很多东西重写了好多遍,一个小小的功能也搞个通宵,甚至有时候想实现这个功能都不知道应该用什么技术,以至于百度都不知道该百度什么,这样的效率真心很低。虽然我有精力和激情去熬夜,但是熬夜总归是不好,渐渐感觉到了所谓基础不牢的面临的窘迫。项目最后的结果我就不说了,最后做完之后,我又开始思考——我得到了什么。答案肯定是我得到了很多的经验,但是我真的搞懂了吗?我使用了一遍Spring框架,我使用了正版Oracle(啧啧啧,搞死我,fuck oracle)。然后最后的最后,我还是说不上来这些东西是怎么个结构,怎么个原理,如果这样,我大概只是个会Ctrl+C和Ctr+V的码农而已。

1
using namespace std;

说完了项目的问题,回到电面中,我虽然心里比较激动,但是说话还是比较淡定的。问的问题真的不难,首先问了我一个概率的问题,就是我们概率论老师在上课放的电影片段中的原题,,虽然感觉面试官似乎并不认同我给的那个答案。。关于Java的问题,果然问道了String和StringBuffer的问题233333,问了什么事堆,结果我怼了一大波栈的事。。整个的面试过程很是和谐,我自己也说了好多。最后面试官评价我,实力挺强的,但是基础不够扎实,还向我建议接下来的学习方向和重点,他多次向我强调了基础这两个字,虽然我想,我一开始的大二生的身份就让他有些惊讶,我估计是接不到二面的电话了,不过和面试官的聊天中也的确想到以后在技术上面发展的问题。

基础和实战并不冲突,如果我现在在学习数据结构,那我就不应该只看看书就完了,需要真正的敲一遍,说的很好做不出来是纸上谈兵,磕磕绊绊做出来说不出来是花拳绣腿,这两者我都不想要。毕竟我的目标既不是老师,又不是码农。