获得徽章 0
MPA即多页应用,是从服务器加载多个 HTML 页面的应用程序。每个页面都彼此独立,有自己的 URL。当单击 a 标签链接导航到另一个页面时,浏览器将向服务器发送请求并加载新页面。例如,传统的模板技术如JSP、Python、Django 等都是基于 MPA 的框架,包括目前比较火的 Astro 也是采用的 MPA 方案。
SPA 即单页应用,它只有一个不包含具体页面内容的 HTML,当浏览器拿到这份 HTML 之后,会请求页面所需的 JavaScript 代码,通过执行 JavaScript 代码完成 DOM 树的构建和 DOM 的事件绑定,从而让页面可以交互。如现在使用的大多数 Vue、React 中后台应用都是 SPA 应用。
在 MPA 中,服务器将响应完整的 HTML 页面给浏览器,但是 SPA 需要先请求客户端的 JS Bundle 然后执行 JS 以渲染页面。因此,MPA 中的页面的首屏加载性能比 SPA 更好。
MPA 中服务端会针对每个页面返回完整的 HTML 内容,对 SEO 更加友好;而 SPA 的页面内容则需要执行 JS 才能拉取到,不利于 SEO
MPA 在浏览器侧其实不需要路由,每个页面都在服务端都有一份 URL 地址,浏览器拿到 URL 直接请求服务端即可。
但 SPA 则不同,它需要 JS 掌管后续所有路由跳转的逻辑,因此会引入一些路由方案来管理前端的路由,比如基于 hashchange 事件或者浏览器 history API 来实现。
除了路由,SPA 另外一个复杂的点在于状态管理。SPA 当中所有路由的状态都是由 JS 进行管理,在不同的路由进行跳转时通过 JS 代码进行一些状态的流转,在页面的规模越来越大的时候,状态管理就变得越来越复杂了。因此,社区也诞生了不少的状态管理方案,如传统的 Redux、社区新秀 Valtio、Zustand 包括字节自研的 Reduck,都是为了解决 SPA 状态管理的问题,一方面降低操作的复杂度、另一方面引入一些规范和限制(比如 Redux 中的 action 机制)来提高项目可维护性。
#挑战每日一条沸点#
展开
评论
Java实现动态数组 #挑战每日一条沸点#
public class DiyList<T> {

private Object[] items;

private int size = 0;

public DiyList() {
items = new Object[16];
}

public T get(int index) {
if (index > size) {
throw new NoSuchElementException();
}
return (T) items[index];
}

public boolean add(T item) {
if (Objects.isNull(item)) {
throw new NullPointerException();
}

if (size >= items.length / 2) {
grow();
}

items[size++] = item;
return true;
}

private void grow() {
Object[] newItems = new Object[items.length * 2];
System.arraycopy(items, 0 , newItems, 0 , items.length);
items = newItems;
}

public int size() {
return size;
}

}
展开
评论
#挑战每日一条沸点#
Go语言实现TCP通信
TCP协议
TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字节流的传输层(Transport layer)通信协议,因为是面向连接的协议,数据像水流一样传输,会存在黏包问题。
一个TCP服务端可以同时连接很多个客户端,例如世界各地的用户使用自己电脑上的浏览器访问淘宝网。因为Go语言中创建多个goroutine实现并发非常方便和高效,所以我们可以每建立一次链接就创建一个goroutine去处理。
我们使用Go语言的net包实现的TCP服务端代码如下:
func process(conn net.Conn) {
defer conn.Close() // 关闭连接
for {
reader := bufio.NewReader(conn)
var buf [128]byte
n, err := reader.Read(buf[:]) // 读取数据
if err != nil {
fmt.Println("read from client failed, err:", err)
break
}
recvStr := string(buf[:n])
fmt.Println("收到client端发来的数据:", recvStr)
conn.Write([]byte(recvStr)) // 发送数据
}
}
func main() {
listen, err := net.Listen("tcp", "127.0.0.1:20000")
if err != nil {
fmt.Println("listen failed, err:", err)
return
}
for {
conn, err := listen.Accept() // 建立连接
if err != nil {
fmt.Println("accept failed, err:", err)
continue
}
go process(conn) // 启动一个goroutine处理连接
}
}
展开
评论
学习Go后端开发的路线如下:
1. 学习Go编程语言的基础知识,包括语法、数据类型和控制结构。
2. 理解如何在Go中使用包和导入。
3. 探索Go中的并发和goroutine的概念。
4. 研究Go的标准库,其中包括网络、文件处理等功能。
5. 使用Gin或Echo等框架深入学习Go的Web开发。
6. 学习使用GORM或SQLx等库在Go中进行数据库集成。
7. 熟悉Go中的测试和调试技术。
8. 通过构建小项目和练习编码挑战来提升技能。
9. 保持与Go社区资源的联系,如博客、论坛和会议。
#挑战每日一条沸点#
展开
评论
#挑战每日一条沸点#
1.什么是数据库
数据库(Database)就是按照数据结构来组织,存储和管理数据的仓库

专业的数据库是专门对数据进行创建,访问,管理,搜索等操作的软件,比起我们自己用文件读写的方 式对象数据进行管理更加的方便,快速,安全

2,作用
对数据进行持久化的保存
方便数据的存储和查询,速度快,安全,方便
可以处理并发访问
更加安全的权限管理访问机制
展开
评论
链表的代码结构一般是这样的:

public class DiyLinked<T> {
private int size = 0;
private Node<T> item;

private static class Node<T> {
private T item;
private Node<T> next;
public Node(T t) {
item = t;
}
}
} #挑战每日一条沸点#
展开
评论
本篇文章将主要介绍 blob 及 text 数据类型的相关知识。

1. blob 类型
blob(binary large object) 是一个可以存储二进制文件的容器,主要用于存储二进制大对象,例如可以存储图片,音视频等文件。按照可存储容量大小不同来分类,blob 类型可分为以下四种: #挑战每日一条沸点#
展开
评论
#挑战每日一条沸点#
.mysql主从复制原理图

mysql主从复制原理是大厂后端的高频面试题,了解mysql主从复制原理非常有必要。

主从复制原理,简言之,就三步曲,如下:

主数据库有个bin-log二进制文件,纪录了所有增删改Sql语句。(binlog线程)

从数据库把主数据库的bin-log文件的sql语句复制过来。(io线程)

从数据库的relay-log重做日志文件中再执行一次这些sql语句。(Sql执行线程)

展开
评论
#挑战每日一条沸点#

        栈(stack)是一种线性数据结构,栈中的元素只能先入后出(First In Last Out,简称FILO)。最早进入的元素存放的位置叫作栈底(bottom),最后进入的元素存放的位置叫作栈顶(top)。 栈这种数据结构既可以用数组来实现,也可以用链表来实现。
展开
1
#挑战每日一条沸点#
「双向链表」

双链表以类似的方式工作,但还有一个引用字段,称为“prev”字段。有了这个额外的字段,您就能够知道当前结点的前一个结点。

展开
评论
#挑战每日一条沸点#
链表 Linked List

一种常见的基础数据结构,也是一种线性表,但是并不会按线性表的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。

链表在插入的时候可以达到 O(1) 的复杂度,比另一种线性表 —— 顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要 O(n)的时间,而顺序表相应的时间复杂度分别是 O(log n) 和 O(1)。

优缺点:



使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。



「链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。」

链表有很多种不同的类型:

单向链表

双向链表

循环链表

链表通常可以衍生出循环链表,静态链表,双链表等。对于链表使用,需要注意「头结点」的使用。

展开
评论
#挑战每日一条沸点#
分治法基本思想

一句话,对分治法概括它的话👇

将原问题划分成n个规模较小而结构与原问题相似的子问题,递归去解决这些子问题,然后依次再合并其结果,最后得到原问题的解。

那么具体的来说,我们似乎可以分成三个步骤👇

分解:将要解决的问题划分成若干规模较小的同类问题。

解决:当子问题划分得足够小时,用较简单的方法解决。

合并:按原问题的要求,将子问题的解逐层合并构成原问题的解。

其实思想还是不变的,将一个难以直接解决的大问题,分割成一些小规模的相同问题,以便各个击破,分而治之。

展开
评论
#挑战每日一条沸点#
插入排序

顾名思义:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

「时间复杂度: O(n*n)」

思路

从第一个元素开始,该元素可以认为已经被排序;

取出下一个元素,在已经排序的元素序列中从后向前扫描;

如果该元素(已排序)大于新元素,将该元素移到下一位置;

重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;

重复步骤2~5。

展开
评论
下一页
个人成就
文章被点赞 2
文章被阅读 2,171
掘力值 299
收藏集
0
关注标签
4
加入于