前后端分离时,后端接口可不能太随意,目前后端接口编写大多遵循 RESTful 风格。做后端接口的公司这么多,如果大家都定义自己的规范,是不利于公司之间的合作的。如果大家都能遵循一个规范来开发接口,很明显相关人员都能省心不少。RESTful 就是一种非常流行的 HTTP 接口规范,简单明了,使用的人也多,用它准没错。规范的意义,就是提供标准,提高效率。汽车行业标准化程度已经很高了,软件行业还需努力!(图片来源于网络,版权归原作者所有)
互联网行业因为广为人知的高薪以及相对于传统工科行业更多的发展机会,最近几年涌入了越来越多的非计算机专业毕业的从业人员,校招 / 社招面试的时候,候选人往往也会被分为两种:科班和非科班,互联网科班一般特指大学就读计算机科学与技术或者软件专业,非科班则包含其他各大传统工科甚至是文科专业。某些大厂在招聘后端开发工程师时会严格要求科班背景,因为对于非科班的同学,一般都能胜任计算机网络应用层以上的工作(例如编写一个低并发的后台管理系统),但是对于计算机底层的知识往往是一片盲区。当对计算机网络了解甚少的非科班同学遇到线上问题时,或者网络通信相关的运维故障,往往会束手无策。所以了解计算机底层如何运作是非常有必要的,我们这里谈到的计算机底层知识,包括但不限于:计算机组成:CPU 运行的原理,内存、硬盘等各种硬件如何协调合作;操作系统:支撑后端框架的系统,具体做了哪些操作;编译原理:对于 Java 、C++ 这类高级语言,如何经过编译,转换为汇编语言以及二进制文件;计算机网络:计算机与计算机之间如何进行通信。从本小节开始,我们会开始学习计算机网络相关的面试题目,并且在熟悉题目的同时,掌握计算机网络的基本知识框架。
在理解这两种 Web 应用模式之前,我们需要先明确前端与后端的概念。前端负责页面的渲染、数据的展示,而后端负责处理用于展示的数据。通俗地讲,前端就是用户可以看到的东西,比如在一个天气预报页面中,用户所能看到的天气信息就是前端展示的。每天的天气不同,展示的数据也不一样,那么这些数据从何而来?答案是后端。我们之所以能看到实时更新的天气数据,是因为前后端配合作业实现的。后端在数据库查询相应时间的天气情况,查到数据后,进行相应的处理、包装,交由前端,前端获取数据后,根据提前设计好的样式,在相应位置填充后端发来的数据,这样一个天气预报页面就呈现在了用户眼前。天气预报页面
在前后端分离的 Web 应用中,后端此时扮演的角色只是提供前端所需的数据,不再负责样式的渲染。前端的展示样式,完全由前端负责,针对不同的终端,进行不同的渲染,这样不仅提高了用户体验,还在很大程度上降低了前后端的耦合度。由于不同终端所需的数据几乎一样,后端仅需专注于业务逻辑,为前端提供数据即可,不再需要适配不同终端,提供不同页面,这便大大降低了开发工作量。在前后端分离的应用模式中,我们通常将后端开发的每个视图都称为一个接口,或者API,前端通过访问接口来对数据进行增删改查。前后端分离模式示意图
深入了解前端控制器之前,先抛出一个问题:控制器是什么?别被控制器这个名字吓住。其实和原生 Servlet 开发中开发者自定义的 Servlet 的功能是一样的。当然,因为有 Spring 的加持,使用起来,是非常之轻量级的。Spring MVC 中的控制器有 2 类:中央控制器,或叫前端控制器: 由 Spring MVC 框架提供,对所有请求进行分流;用户控制器,或叫响应控制器: 由开发者实现,用来响应用户的具体请求。如登录请求、注册请求……前端控制器(DispatcherServlet)是 Spring MVC 中最核心的组件,相当于整个程序中的行政、调度中心。其它的组件都是它的附庸,为前端控制器提供相关的服务。Tips: DispatcherServlet 必须在 Spring MVC 项目启动时被创建。DispatcherServlet 的纯 JAVA 配置请查阅《纯 JAVA 搭建 Spring MVC 项目》章节内容。DispatcherServlet 的基本功能。
在前后端不分离的应用模式中,前端向 Web 服务器发送请求,Web 服务器根据请求内容,从数据库查询相应数据,将数据填充进模板渲染,渲染结果发回前端进行展示。在过去,人们访问互联网几乎都是通过 PC 浏览器,因而仅需开发适应 PC 显示的单终端页面(只在一种设备上使用,其他设备不使用或很少使用的页面)即可。如果仅开发单终端的网页应用,前后端不分离模式是较为普遍的开发模式,针对同一个页面,后端提供资源填充入前端模板相应的位置并渲染,展示给客户即可,无需考虑不同终端需要不同的数据类型、不同的展示效果。在这种场景下,前后端不分离模式不仅开发速度快,还便于开发人员直接调试页面。然而随着移动互联网的发展,Web 应用不再单单服务于 PC 端,同样的内容需要在不同的终端进行展示。而不同终端需要不同的渲染方式,如果仍然采用前后端不分离的应用模式,就需要后端为不同的前端渲染不同的页面进行适配,此时增加了许多冗余工作。前后端不分离模式示意图
我们知道,yarn 是跟 npm 很相似的前端依赖管理工具,不过他比 npm 更加方便高效,也更加简单。所以为了方便理解 Yarn 的使用及原理,可以先了解 npm 的用法,当然如果想直接学习 yarn ,相信大家只要认真努力,也一样可以学得会。加油!
前后端分离这种概念和技术,早就流行多年了。具体点说,前端编写 HTML 页面,然后通过 Ajax 请求后端接口;后端把接口封装成 API ,返回 JSON 格式的数据;前端接收到 JSON 返回数据后渲染到页面。前端工程师根本不需要懂后端,调用后端接口就行。后端使用 Spring Boot 控制器返回 JSON 十分简单,给方法添加个注解,就能将返回值序列化为 JSON 。前端干前端的活,后端干后端的活,职责分明,界限明确。这就是前后端分离的好处啊!
科学计算是当今科学的"第三支柱",科学计算是解决科学和工程问题的计算机数学模型所需的工具、技术和理论的集合。当下我们大多数人接触科学计算,都是由人工智能与机器学习开始的。人工智能 可以简单理解为机器学习与大数据。 而 机器学习 是实现人工智能的方法,是人工智能研究的核心技术,在大数据的支撑下,通过各种算法让机器对数据进行深层次的统计分析以进行“自学”。机器学习中数据是非常重要的,而数据收集、分析与建模等过程与科学计算是密不可分的。
定义:在了解什么是生产者与消费者时,我们可以先不从计算机专业的角度考虑什么是生产者与消费者,我们可以先来了解它们的字面意思。从生活角度考虑,生产者就是生产某某东西的人,而消费者就是消费某某东西的人,它们两个一个是生产,一个是消费,且保持着一种先生产后消费的关系。针对于计算机专业角度来说,生产者就是生产一条数据的手段或者途径,而消费者则是消费一条数据的手段或者途径。在 RabbitMQ 中,生产者指的就是具备生产一条消息能力的方法,消费者指的就是具备消费一条消息能力的方法。代码实现:那么我们如何在 RabbitMQ 中来定义一个生产者和一个消费者呢?接下来就让我们来看一下 RabbitMQ 中生产者与消费者的基础通用 API :在 RabbitMQ 中要想声明一个生产者,我们首先需要与 RabbitMQ Server 建立通信,即将我们的应用程序与 RabbitMQ 的服务器建立链接,如下代码所示:ConnectionFactory connectionFactory = new ConnectionFactory();connectionFactory.setHost("127.0.0.1");connectionFactory.setPort("5672");Connection connection = connectionFactory.newConnection();代码解释:第 1 行,我们实例化了一个 RabbitMQ 的链接工厂,这是与 RabbitMQ 服务器建立链接的必要基础操作。第 2-3 行,我们使用我们实例化的链接工厂中的 setHost 和 setPort 方法来设置我们需要链接的 RabbitMQ 服务器的 ip 地址,以及端口号,RabbitMQ 服务默认的端口号为 5672。第 4 行,在将 RabbitMQ 服务的 host 和 port 设置完毕后,我们使用 connectionFactory 的 newConnection 方法来创建出了一条链接,并返回我们连接 RabbitMQ 服务的 connection 信息。在建立好连接之后,我们就可以向 RabbitMQ 中发送消息了,如下代码所示:Channel channel = connection.createChannel();String msg = "Hello RabbitMQ";channel.basicPublish("", "test01", null, msg.getBytes());现阶段,在上段代码中,我们只需要了解最后一行代码所表示的含义即可。代码解释:第 3 行,我们使用了 channel 的 basicPublish 方法来将我们定义的 msg 消息投递到 RabbitMQ 中,其中, basicPublish 方法的第一个参数表示交换机的名称,第二个参数表示路由 Key 的名称,第三个参数表示消息所设置的参数,第四个参数表示将我们的 msg 数据转换为 bytes 之后再进行投递。通过上述代码,我们就实现了 RabbitMQ 的生产端,那消费端又该如何实现呢?代码实现:String queueName = "test01";channel.queueDeclare(queueName, true, false, false, null);DefaultConsumer defaultConsumer = new DefaultConsumer(channel);channel.basicConsume(queueName, true, defaultConsumer);代码解释:第 1 行,我们根据生产者声明的路由 Key ,定义了一个名为 queueName 的变量,来接收路由 Key 。第 2 行,我们使用 channel 的 queueDeclare 方法,来声明一个名为 queueName 的队列。第 3 行,我们对 RabbitMQ 中用来接收消息的 Consumer 进行初始化。第 4 行,我们使用 channel 的 basicConsume 方法,来讲我们投递到 RabbitMQ 中的消息进行消费。Tips 在这里,我们只是对 RabbitMQ 中如何实现生产端与消费端进行一个简单的了解,后续会进行深入介绍。
周末陪孩子玩新买的玩具枪,看到弹夹我乐了,这不就是一个栈容器吗!儿子问我什么是栈,我反问儿子,你装弹的顺序和子弹打出去的顺序有没有关联或规律呢?儿子想了一会说,最先装进去的子弹要等到最后才能被发射出去,而第一发子弹是最后一个装进去的!(图片来源于网络,版权归原作者所有)正像枪的弹夹一样,栈表示的是一个后进先出的对象,也叫堆栈。无需百度,直接打开 java.util.Stack 源码还能看到 Java 为此定义了一个专属单词 LIFO ,其实就是 last-in-first-out 的缩写。细心的小伙伴还会从源码中发现 Stack 其实是继承自 Vector ,上一节我们介绍了数组, Vector 就是可实现自动增长的对象数组,它支持线程的同步。所以我们可以发现,栈的本质也是数组。数据从栈顶压入,操作的时候先从栈顶取出。
使用 Spring Boot 后,开发人员心里美美的,再也不需要写一大堆的配置文件了。每天都能早早地下班,回家可以多打两把王者荣耀啦。但是每次开发完后端接口,使用 Postman 测试比较麻烦。差不多的接口地址,差不多的参数,每次测试都要输入一遍,挺烦心。另外前端那些家伙,完全不懂后端技术,天天要文档。就这么简简单单几个接口,还得给前端写。咦,能不能自动生成接口文档,然后自动生成测试界面呢。百度一搜 "Spring Boot 接口自动化测试",发现很多文章推荐使用 Swagger2 。哈哈,站在巨人的肩膀上果然好办事。
前后端分离模式逐渐成为主流,随之而来的问题也很突出。通常,后端服务开发完成,开发人员会写一份后端接口调用的说明文档。不同公司、不同项目甚至不同开发人员都有各自的喜好,因而开发好的后端服务,也是千奇百怪,前端开发人员为了使用使用后端服务,必须逐个对照说明文档才能知道调用方式。小型项目还好说,大型项目接口繁杂,如果仍然采用千奇百怪的接口调用方式,就会无形中增加开发难度。那么是否有一套接口开发规范,是否有一个见名知意的接口调用方式呢?答案是有的,这就是 RESTful 规范。后续内容,我们将正式开始学习 RESTful。
秋招开始时,本科生还处于大三阶段,一般还需要完成一些专业课,研究生则是在研二阶段,可能还在帮导师做项目。两者的时间都谈不上充裕,所以如何利用有限的时间收获最好的 Offer 就需要技巧。 同时,校招时 BAT(百度、阿里、腾讯)等大厂都会对参与校招的候选人进行评级,一般分为三档,也就是口口相传的白菜 Offer(评级普通),sp(Special Offer,评级优秀)、ssp(Super Special Offer,评级优秀),每档之间在年薪上可能会有3~10w的差距,而决定评级的,除了候选人的学历等硬件条件,最重要的就是在面试过程中的表现,也就是对于面试题目的剖析能力。 抛开简历书写、简历投递、Offer 谈薪这些模块,在本节内容中,我们的重点在于讲解后端校招中最经典、最高频的面试题,深入分析题目中最需要关注的知识点。在熟练掌握这些题解之后,对于面试中遇到的同类题目,我们能够给面试官良好的技术印象,以此助力同学们在校招中拿到心怡的 Offer。
在 Web 应用中,用户通过浏览器向服务器提交请求,服务器接收到请求后,对用户的请求进行处理,再将结果返回给用户。例如,使用 baidu 搜索引擎的过程如下:用户在 baidu 的搜索框中,输入关键字 “手机”,浏览器将关键字 “手机” 发送到 baidu 的服务器。baidu 服务器收到查询手机的请求,在数据库查找和手机相关的网页,按照与关键词的相关性进行排序,再将排序结果发送给用户。浏览器收到服务器的查询结果后,显示与 “手机” 相关的网页列表。在以上的 3 个步骤中,与用户交互的部分称之为前端,在服务器处理的用户请求的部分称为后端。Python 提供了大量的模块和框架可以用于后端开发。有很多知名的网站后端采用了 Python,例如,国内的豆瓣就是一个应用Python打造的非常成功的 Web 2.0 站点。
在当下,人工智能已经遍地开花。无论是我们手机上的应用还是交通监管,都离不开人工智能的身影。毫无疑问,在过去几十年里,人工智能是已经深入的改变了我们的生活方式与就业情景。在这个瞬息万变的竞争格局中,任何没有利用人工智能的机构都将被远远地甩在后面。无论是各个国家,还是各个公司组织,都在积极地向机器学习方向发展。也正是在这个人工智能的大潮之中,我们的机器学习行业才会如火如荼地发展。目前阶段,各个企业和组织对于我们机器学习领域的人才需求量都非常大,人工智能行业的发展前景非常广阔。在未来几年甚至十几年,机器学习领域的就业可以说是“最赚钱的行业”之一。作为 IT 工作者,我们应该抓住时代的潮流,用人工智能的技能来武装自己,学习如何进行机器学习的开发工作。在目前,最受欢迎的机器学习框架就是 TensorFLow 与 Pytorch,这两者都有着很广阔的前景。相比而来 TensorFlow 更加适用于工业生产,而 Pytorch 更加适用于科学研究。TensorFlow 无可厚非地能被认定为神经网络中最好用的库之一。它在训练深度神经网络方面有着得天独厚的优势。通过使用TensorFlow我们就可以快速地入门神经网络,大大降低了深度学习的开发成本和开发难度。
目前来说,大数据产业已经发展成为了一种新型服务产业,已经逐渐的延伸到科学和商业等领域,随着大数据技术的发展和应用产品的不断迭代更新,大数据中所蕴含的价值被不断的开采出来,同时,大数据分析行业的人才需求量也越来越大,行业中给出的待遇水平也相对较高。而 Python 语言中的 Pandas 库凭借着自身在大数据处理和分析中的简洁方便、稳定、高效等多方面的优势,在大数据领域中的位置越来越重要,也越来越被用户所认可,成为了大数据分析、人工智能等领域必不可少的选择。学习 Pandas 有以下这些你无法拒绝的理由:易于学习和使用;社区资源多且丰富;Pandas库成熟稳定;Pandas库功能丰富;提高数据分析生成力;就业前景广;薪资待遇高。总之,不管你是一名上班族,还一名科学的研究者,Pandas 的学习对你来说都是很有价值的,在工作和办公中随时都会接触到大量的数据,对于数据的处理和分析成为了必不可少的工作内容之一,Pandas 能大大的提高工作的效率。通过接下来进一步的接触和学习,Pandas 在数据处理和分析上的亮点一定会让你赞叹!
前面的章节,我们主要从什么是 Ajax、为什么要用 Ajax、Ajax 是如何实现的以及如何封装一个 Ajax来对 Ajax 做一个多方位的学习。从前面章节的学习中,相信同学们对 Ajax 都会有一个比较完整的概念了。那么,接下来的这个章节,我们着重列举一个示例,来讲述 Ajax 是如何进行前后端交互的。
整体来说,我们传统的实现用户登录功能的业务逻辑还是正确的, 不管我们再怎么对用户登录功能进行优化,这个传统的用户登录功能业务流程始终不会发生改变,发生改变的只是我们的代码实现层。那么,传统实现方案中存在的弊端,也就存在于我们的功能代码实现层上。弊端一 用户登录状态的处理对于上述代码来说,我们处理用户登录状态所采用的手段,是通过将用户登录成功后的数据存放在服务端中的 session 中,后续如果需要使用到用户登录状态,我们可以直接对 session 进行判断,并返回相应的判断结果。但是,这种模式如果遇到了前后端分离的项目,我们就无法再使用 session 了,因为前端框架不能直接操控我们后端的 session ,所以,我们就要把 session 替换掉,替换成前后端均可操控的手段来实现。弊端二 高并发环境下容易出现的问题如果我们的项目在使用过程中出现了用户激增的情况,即会有越来越多的人来访问我们的用户登录功能,如果我们只是采用上述的实现方式来处理,不会这种情况进行考虑,那么我们的用户登录功能就会在非常短的一段时间过后瘫痪,我们的用户登录功能不会再返回任何响应数据。这就是高并发环境下传统的用户登录功能最容易出现问题的地方,而这一地方则体现在用户登录前和用登录后的数据不一致问题上。即,在高并发环境下,我们的用户 A 进行了登录,与此同时,我们的用户 B 也进行了登录,这两个用户进行登录的时刻恰好重叠了,由于我们并没有对这种场景进行处理,所以,在这两个用户登录之后,就有可能出现返回给用户 A 的用户数据,其实是用户 B 的。除了数据不一致问题,还有一种问题也比较容易出现,那就是当我们的用户数激增时,同一时刻进行登录的用户也随之激增,我们的用户登录功能接口无法在一瞬间响应这么多的用户登录请求,导致了后续登录的用户只能等待,只能等待当先用户登录完成之后,才能进行登录。这个等待过程是不确定的,可能很长,也可能很短,这就对用户的体验造成了非常严重的不良影响。上述就是两个在传统用户登录功能中,出现的显而易见的问题,我们会对这两个功能进行优化,并且会使用 RabbitMQ 对第二个弊端进行优化。
使用浏览器访问网站的过程如下所示:浏览器向网站发出请求网站收到请求后,返回 HTML 文本作为响应内容在下图的例子中,服务器返回当前时间 (HTML 的格式)。使用浏览器访问网站时,显示的内容是动态的,每次都是当前时间,如下所示:在这个例子中,浏览器又被称为前端,服务器又被称为后端。后端收到请求后,做如下的工作:分析用户请求,获取请求的参数根据请求的参数进行处理,可能会读取数据库最终生成一段 HTML 文本返回给前端Python 作为一个通用的编程语言,能够完成以上的工作,由于其开发效率高,在 Web 后端开发中占有重要的一席之地。以下是慕课网的课程分类目录,在后端开发的分类中,Python 和 Django (Python 的 web 框架) 占有两个条目:
各位同学可能被市面上的一些“误解”错误地引导,认为曾经的网页三剑客其中个别成员现在评价不是很好,所以 Dreamweaver 就可能不值得学。在这里要告诉各位同学们,这种想法完完全全是有些人误会了 Dreamweaver 。说 Dreamweaver 不值得学的人大多数是缺少对 Dreamweaver 系统学习,或者对 Dreamweaver 的印象还停留在3年或几年之前。喜欢这样讲的人还有一部分是由于他们使用了 Dreamweaver 同类型的竞品工具,但工具的好坏,时间积淀会说明一切。Adobe 公司在网页设计的积淀就好比 PC 界的 MicroSoft ,汽车圈的 Tesla。所以,现在这个在我们面前的 Dreamweaver 早就已经具备了强大的功能,覆盖你的网页设计的方方面面。或许有同学会觉得,网页设计这个词和时髦的互联网公司里讲的前端/后端工程师比起来是十分老旧?不! Dreamweaver 能做目前前端工程师手下的大部分工作,而且绝对能够给你带来眼前一亮出色表现。
什么是级联操作?关系型数据库中由主外键维系的两张表,具有主从关系。如学生表和班级表,班级班是主表,学生表是从表。类似于删除某一个班级的信息,则需要先删除所在班的学生信息,再删除班级信息,这个操作就是级联操作。所谓级联操作,指操作一张表时,是否会牵连到与之有关联的其它表。现在,咱们是使用 Hibernate 进行数据操作,不可能还要劳驾自己亲力亲为吧。只需要做些简单配置,就可以让 Hibernate 自动做级联操作。进入班级类,修改代码如下:@OneToMany(targetEntity=Student.class,mappedBy="classRoom",cascade=CascadeType.REMOVE) public Set<Student> getStudents() { return students; }很简单,只需要使用 @OneToMany 的 cascade 属性,就能让 Hibernate 明白如何做级联操作。默认情况下,没有级联效应。cascade 是一个枚举类型:public enum CascadeType { ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH}ALL: 级联所有操作;PERSIST: 级联新增;MERGE: 级联更新或者新增;REMOVE: 级联删除;REFRESH: 级联刷新;DETACH: 级联分离。测试删除班级实例:HibernateTemplate<ClassRoom> hibernateTemplate = new HibernateTemplate<ClassRoom>(); hibernateTemplate.template(new Notify<ClassRoom>() { @Override public ClassRoom action(Session session) { ClassRoom classRoom=(ClassRoom)session.get(ClassRoom.class, new Integer(1)); session.delete(classRoom); return null; } });如果不添加 cascade 相关说明,因为有学生引用班级信息,班级信息是不能被删除的。添加后再测试,查看表中内容:班级以及班级所在学生信息全部删除!删除班级时能级联删除学生,反过来,删除学生能删除班级吗?想法很好,实践是检验真理的唯一手段,学生类中修改成如下代码:@ManyToOne(targetEntity=ClassRoom.class,cascade=CascadeType.REMOVE) @JoinColumn(name="classRoomId") public ClassRoom getClassRoom() { return classRoom; }测试实例:HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>(); hibernateTemplate.template(new Notify<Student>() { @Override public Student action(Session session) { Student stu=(Student)session.get(Student.class, new Integer(2)); session.delete(stu); return stu; } });结果很残酷!学生被删除了,班级也被删除了!级联级联,只要设置了级联,不管删除学生还是班级,只要在对应表中有引用关系的数据就会被删除。现在,学生类、班级类中的级联删除都打开了。如果对下面情形的数据(编号 1、2 的学生的班级编号都为 1)进行删除操作,则会发生什么事情?数据库中的数据如下:测试删除编号为 1 的学生:HibernateTemplate<Student> hibernateTemplate = new HibernateTemplate<Student>(); hibernateTemplate.template(new Notify<Student>() { @Override public Student action(Session session) { Student stu=(Student)session.get(Student.class, new Integer(1)); session.delete(stu); return stu; } });进入 MySql,查看一下:天呀!这是级联还是株连呀,太让人后怕,数据都没有了。删除学生时,会级联删除和学生有关的班级,班级删除时,又会查看学生表中是否还存在与班级有关联的学生,有,则一刀下去,连根拔起。Hibernate 有点刹不住车,产生了级联连锁反应。针对上面的测试,如果班级表的级联关闭,执行测试代码,请问结果又会怎样?本节课程,讲解了级联删除,级联添加的内容留到下节课继续展开。
微前端 尚处在发展时期,其核心概念和 微服务 相似。现阶段较为常用的微前端框架为 single-spa 和 qiankun,后者是基于前者实现的。该技术能做到 技术栈无关,即一个应用,能由多个不同技术的子应用构成,同时做到子应用的相互隔离,这里的隔离就可以选择采用 Web Components 实现。
知道了 PO 的 3 种状态。自然会问:不同状态下的对象对实际操作有什么实际指导意义?3 种状态中,持久化状态的意义最大,如果 PO 处于持久化状态,此时 PO 就具有持久化能力。所谓对象持久化能力,通俗理解:程序中的数据发生变化,会自动同步到数据库中。演示一段数据更新实例,更新之前先查询数据:try { transaction = session.beginTransaction(); //查询学生 Student stu=(Student)session.load(Student.class, new Integer(2)); //修改学生信息 //执行更新操作 transaction.commit();} catch (Exception e) { transaction.rollback();} finally { session.close();} 通过 Session 的 get() 方法查询出来的 stu 对象,此时就处于持久化状态。在” 修改学生信息 “的注释下添加一行代码:stu.setStuName("持久化状态就是这么牛"); 不需要调用 Session 中的任何其它方法,执行代码,程序中修改的数据立即同步到数据库中。这就是持久化状态的特点:通过 PO 自动同步程序与数据库中的数据。所谓对象持久化能力本质上还是 Session 给的。Session 记录对象是否处于持久化状态,并充当后台靠山。处于持久状态的对象与数据库之间的数据同步,只是不需要 Session 显示调用。除了 get()、load()方法。save()、update()、saveOrUpdate()、persis()、megre() 方法都可称为持久化方法。调用这些方法后,能让对象进入持久化状态,Session 记录并且默默维持 PO 中数据与数据库中数据的同步。
Netty 虽然可以开发客户端和服务端的应用,但是 Netty 和 WebSocket 结合则是另外一个不同的应用方向。应用方向一: 纯后端的应用,比如:框架、中间件通信等,则完全可以使用 Netty 来开发客户端和服务端,并且双方通过 TCP 协议来进行通信。应用方向二: 前端(浏览器)和服务端之间通信,并且想实现类似长连接的效果,那么 WebSocket 和 Netty 则是主流,并且这部分的应用场景非常的广泛和运用非常的多。因此,我们在学习完本章内容之后,我们就可以掌握这类的需求的开发(比如:聊天、消息推送),自己可以尝试去开发一款小程序在线聊天系统。当真实的开发当中,也许很多人直接使用 Spring 封装的 WebSocket 或者其它第三方的框架(比如:netty-socketio)去实现。本节我们主要讲解原生 Netty 来开发 WebSocket 协议格式的数据请求,毕竟会用和知道知其所以然还是有区别的。
网页有一个最优秀的特点就是它的跨平台性,一个前端程序员写出的页面,既可以运行在 Windows 的浏览器上、也可以运行在 MacOS 的浏览器上、还可以运行在 IOS 和安卓浏览器上。正是由于网页所具备的优异跨平台性扩展出了套壳网页的这种形式,比如看起来只是个 apk 的安卓程序,点击也能安装到手机中,但实际上里面的内容都是网页…还有现在红极一时的小程序,其实在很早以前小程序就已经火起来了,但这次疫情真的是把小程序彻底推向了一个巅峰:去商场要扫小程序二维码、坐高铁要扫小程序二维码、去麦当劳要用小程序点餐、去景点参观要用小程序预约、去看电影要用小程序订票…那么小程序其实是和前端技术是分不开的,虽然腾讯觉得自己搞的东西不能叫HTML、CSS,取而代之的是 WX(微信)ML、WX(微信)SS… 但其实还是换汤不换药,语法什么的都基本一致,好多东西甚至连名称都没改。而且我们现在做小程序也有那种多端小程序框架:uni-app、mpvue、taro等…这里用的都是 CSS 而不是 微信SS 。所以学会了移动端布局,不仅仅可以把学到的知识运用到移动端的网页上、还可以用到 React Native、小程序、快应用、Weex等这些前端演变出来的技术上。
Http 协议是前后端 API 接口交互的桥梁,不管你是前端开发,移动端开发,后端开发,它都是你工作必不可少的部分。在如今的生产环境中,为了快速实现逻辑业务的开发,往往这部分是被框架封装得很完整了,初学者就更加容易忽视它,以至于遇到问题无从下手。为什么我资源更新了,界面还是旧的,可能是 Http 缓存了;请求的参数该放路径还是 Body 中;接口报错了,返回的状态码看不懂;接口文档如何编写才是规范的;让 Http 协议规范自己的软件开发;虽然 Http 工具封装得很好用,但我必须搞懂它,要做工具的主人而不是奴隶,必要的时候自己造工具。
由于移动端设备尺寸差距非常大,有还在用好几年前手机的、有用高分辨率视网膜屏幕的、还有用屏幕超大的iPad的。有人可能会问:iPad也算移动端吗?其实并不是只有那种能装进兜里的才叫移动端,虽然说iPad或者其他一些平板电脑不会像手机那样被人随身携带,但下班回家或者放学回宿舍的时候,靠在沙发上拿出平板连上wifi,打开空调再来一杯果汁,是一天当中最幸福的时刻。平板电脑处于这么一个尴尬的位置:屏幕比不上笔记本、便携又比不过手机,但它毕竟是靠触摸来操作的,虽然也有外接键盘的功能,但大部分还是靠触摸来进行操作的。既然要靠触摸进行操作,常规的针对PC端写的网站就不太合适了,还是要为移动端写的网站比较靠谱。但如果设计移动端的时候并没有考虑到这么宽的屏幕,放在平板上就会变成这样:也就是说屏幕过小时会被压缩,而屏幕过大时又会被拉伸,响应式就是为了解决这一一种问题的:当然上图这个做的也不是特别的好,因为在拉伸的时候右侧会有空白区域,显得没有填满,真正好的应该是这样:无论屏幕宽窄,左右两侧始终没有缝隙,然后可以根据屏幕的大小来自动进行换行。
在互联网早期,网站的内容都是一些简单的、静态的页面,服务器后端生成网页内容,然后返回给浏览器,浏览器获取 html 文件之后就可以直接解析展示了,这种生成 HTML 文件的方式被称为服务器端渲染。而随着前端页面的复杂性提高,出现了基于 ajax 技术的前后端分离的开发模式,即后端不提供完整的 html 页面,而是提供一些 api 返回 json 格式的数据,前端调用后端的 API 获取 json 数据,在前端进行 html 页面的拼接,最后后展示在浏览器上,这种生成 HTML 文件的方式被称为客户端渲染。简单的使用 requests 库无法爬取客户端渲染的页面:requests 爬下来的页面内容并不包含真正的数据只能通过调用后端的 API 才能获取页面的数据有两种方式爬取客户端渲染的网页:分析网页的调用后端 API 的接口这种方法需要分析网站的 JavaScript 逻辑,找到调用后端 API 的的代码,分析 API 的相关参数。分析后再用爬虫模拟模拟调用后端 API,从而获取真正的数据。很多情况下,后端 API 的接口接口带着加密参数,有可能花很长时间也无法破解,从而无法调用后端 API。用模拟浏览器的方式来爬取数据在无法解析后端 API 的调用方式的情况下,有一种简单粗暴的方法:直接用模拟浏览器的方式来爬取,比如用 Selenium、Splash 等库模拟浏览器浏览网页,这样爬取到的网页内容包含有真实的数据。这种方法绕过分析 JavaScript 代码逻辑的过程,大大降低了难度。
随着互联网技术迅猛的发展,“LNMPR” 一词被越来越多的人熟悉,其中 “L”、“N”、“M”、“P”、“R"分别代表 “Linux”、“Nginx”、“MySQL”、PHP”、“Redis”,而 LNMPR 是后端开发工程师必备技能,学习 LNMPR 相关技术也是各大后端开发工程师提升自己竞争力的有效途径,而 MySQL 作为各大互联网企业重要的数据存储、管理技术,MySQL 数据库工程师的需求也越来越急迫,特别是对有经验的优秀人才需求量巨大。