全栈web开发所需要的知识

P.S. 这只是一个备忘录,避免未来转行忘记现在所学会的一切,所以把它记录下来!

最后更新时间:2024-11-07(未完待补充)

需要会的编程语言一览

编程语言:java、javascript、typescript、css、sass/scss、html、sql、lua、c#、

了解或者会一点的编程语言:C、C++、Go、Python


表达式:正则表达式、

数据库基础

数据库安装、数据库配置,(DDL、DCL、DML),SQL,存储过程,触发器,视图,SELECT查询,子查询,左/右/内/外连接查询,多表关联查询,分组统计查询,查询排序。Update更新,Delete删除,逻辑删除,闪回查询,截断表,分析执行计划,数据库内置函数,SQL性能优化,数据类型转换,数据库引擎,数据库自增id,字段默认值,字段效验,数据库主键(包括隐藏主键),外键关联,索引(聚合索引、非聚合索引),数据库用户/用户权限管理,数据备份恢复,数据库异常修复,数据库灾备,数据库日志查看。

mysql专属技术:

  • innodb数据库引擎(这个不是专属的,很多数据库都有),myisam数据库引擎
  • replace into,update/delete根limit语句,跨库select/update,ON DUPLICATE KEY语句。
  • mysqldump数据库备份工具。
  • mysqlcheck数据库检查/修复工具。

oracle一些专属技术:

  • nvl函数
  • ROWID、ROWNUM伪列

还有数据库连接工具:Navicate、Dberver、Studio3T、RedisManage、redis-client(redis自带的命令行客户端工具)。

需要掌握/了解的数据库

  • 常用关系型数据库:Mysql,MariaDB,Oracle,PostgreSQL
  • 可嵌入式轻量级关系型数据库:Sqlite
  • 用于处理大量数据查询的关系型数据库:Clickhouse
  • 可用于缓存或快速key-value查询的NoSQL数据库:Redis(RDB存储技术)
  • 文档型NoSQL数据库:MongoDB
  • 支持分布式的搜索引擎:Elasticsearch
  • 数据库语言:SQL、PL/SQL(Oracle)、Bson(MongoDB)

数据库/spring事务相关技术

  • 事务相关:
    • 事务传播方式:
      • REQUIRED:已存在则使用已有的,否则新建(默认)
      • SUPPORTS:当前存在事务则加入,否则以非事务方式执行
      • MANDATORY:当前存在事务则加入,否则抛出异常
      • REQUIRES_NEW:总是创建一个新事务执行,如果已存在则挂起。
      • NOT_SUPPORTED:以非事务方式执行,如果当前存在事务则挂起。
      • NEVER:一直以非事务方式执行,如果存在则抛出异常。
      • NESTED:如果存在事务则创建一个嵌套事务,否则创建一个新事务。
    • 事务隔离级别:
      • Read Uncommitted:未提交读。最低的隔离级别,会读取没有提交的数据,会导致脏读幻读不可重复读。
      • Read Committed:已提交读。允许读取已经提交的数据。会导致幻读和不可重复读。
      • Repeatable Read(部分数据库的默认级别):可重复读。对同一个字段多次读取结果是一样的,但是依然可能产生幻读。
      • Serializable:串行化,最高隔离级别,所有事务依次执行,一个结束执行另外一个。
    • 脏读/幻读/不可重复读问题
      • 脏读:读取到的数据是未提交的,程序认为是已经有了,但是可能那边事务回滚了,导致实际数据不存在。
      • 不可重复读:第一次读取一条数据拿到结果A,但是事务还没结束另外一个请求把这条数据改了,当前事务第二次读取这条数据,结果和之前的A不一样,这就是不可重复读问题。
      • 幻读:获取表中所有数据一共10条,另外一个事务加入了一条新数据,这个时候在读取数据变成11条数据了,这就是幻读。

需要掌握/了解的中间件:

  • 文件服务:FastDFS、Minio
  • java服务器:Tomcat、jetty(可以了解weblogic和websphere)
  • 发布订阅推送消息系统:RabbitMQ、Kafka
  • 反向代理服务器/web前端页面服务器:nginx
  • 容器化管理服务工具:docker
  • 容器编排工具:docker-compose、k8s、rancher
  • 配置中心:nacos、apollo、spring cloud config
  • 分布式协调框架:eureka(AP)、zookeeper(CP)

docker需要掌握的技术

Dockerfile文件编写,docker包构建命令,docker镜像导入导出删除,docker镜像详情信息查看,docker容器启动停止重启删除,docker容器进入,docker网络配置和删除,docker环境变量配置,docker启动命令配置,docker端口映射,docker文件挂载,docker cpu/内存使用限制,docker重启策略和异常通知,docker日志记录和日志大小限制,docker健康检测,docker内外文件复制,docker镜像tar包结构原理,docker中心仓库和docker私有仓库搭建以及登录docekr服务器,arm、x86下docker的区别,docker中使用N卡gpu。

docker命令记录:

  • docker exec -it xxxx /bin/bash
  • docker save xxx:xxx > xx.tar
  • docker load < ./xx.tar
  • docker pull xxx:xxx
  • docker push
  • docker inspect 镜像id/镜像名字:版本号/docker进程名字/docker进程id
  • docker run -itd [--name xxx -p xx:xx -p xx:xx] xxx [commands]
  • docker stop xxx
  • docker start xx
  • docker restart xx
  • docker rm xx
  • docker rmi xxx
  • docker network ls
  • docker network rm
  • docker ps [--no-trunc]
  • docker kill
  • docker attach
  • docker images
  • docker version
  • docker logs [-f --tail 1] xxxx

docker-compose命令记录:

  • docker-compose [-f xxxx/xx/docker-compose.yml] down [-v]
  • docker-compose [-f xxxx/xx/docker-compose.yml] up [-d]
  • docker-compose restart
  • docker-compose logs [-f --tail 1]

java基础

JSE、JEE、JME
java基本语法,50+关键字用法,包装类,IO流(字节流、字符流、打印流、扫描流、缓冲流),对象序列化,NIO/AIO,NET(B/S协议、C/S协议,TCP、UDP),多线程,线程池,反射(还原类结构,实例化对象,跳过构造方法实例化对象),类加载器(远处网络class类加载,动态加载卸载类),异常捕捉,Annotation注解,函数式编程(Lambda表达式,方法引用,函数式接口),集合框架(Iterator、Collection、List、Set、Map、Enumeartion、Vector、Struct、Concurrent*线程安全的集合框架,CopyOnWriteArrayList、...),JDBC(包括事务控制,控制脏读幻读),枚举,泛型,比较器,时间日期,时区概念/统一项目时区,正则表达式,多语言/国际化程序,Stream流,动态代理类,字符串/可变字符串,大数值类(BigInteger、BigDecimal),文件监控类Watcher,,java调用本地程序,JNI,swing/awt,对象克隆,XML/JSON,JVM内存模型(方法区、静态区、栈内存、堆内存),GC(G1、ZGC),java启动参数,javadoc文档注释,package-info/module-info。
主线程,守护线程。ThreadLocal,InheritableThreadLocal。

Java Agent代码注入,volatile多线程可见性原理,cpu行缓存,CAS自旋锁。SPI服务发现机制(jdbc是一个例子)

java配套技术

  • eclipse/idea:java开发工具。还有myeclipse,集成了大量插件,不过没啥必要,spring的eclipse插件是免费的,用eclilpse+spring tools插件即可。
  • maven/gradle:项目管理工具+项目依赖包管理工具(打包构建也是用他)
  • git/svn:代码版本管理工具。(.gitignore忽略文件编写)
  • TortoiseGit/TortoiseSVN:有可视化界面的git/svn操作软件(最常用的)
  • junit:单元测试库。
  • jenkins:自动化持续集成工具(让某一个或某一套流程自动化完成)
  • sonarQube/sonarLint:代码检查工具(查bug、漏洞、优化建议),代码检查插件(适用于开发工具)
  • gitlab:可搭建私有代码仓库(共有的有github和gitee)
  • tomcat:java项目部署服务器
  • openjdk:开源免费版本的jdk
  • ffmpeg:开源免费的视频处理库(包括但不限于转码、实施推流、提取图片、截取视频等),很多视频播放软件也是基于ffmpeg开发的。
  • openssl:用于生成ssl证书
  • JD-GUI:java代码反编译工具
  • jconsole:java自带的图形化界面的进程监控工具。(命令行版的有jmap、jstat等)
  • 数据库设计软件:powerDesigner(最常用)

java框架

  • spring:核心框架,包括各种第三方框架集成,IOC+AOP,项目生命周期管理,以及各种强大功能。具体包括:
    • spring:spring核心框架。
    • spring mvc:控制层controller核心框架。
    • springboot:简化web开发的新一代框架,内置tomcat,去xml配置,更多生命周期管理和扩展功能。更多自动注入自动适配功能。springboot也有自己的一套SPI更好用(spring.factories)。
    • springjdbc:jdbc框架
    • spring security:web安全框架
    • spring aop:AOP代理设计模式框架。
    • spring data:JPA框架,简化各种数据库访问。(jpaRepository方法命名规则)
    • spring cloud:微服务框架
    • springfox:接口文档生成框架
    • springtest单元测试框架
    • spring-websocket:websocket框架
  • mybatis:半轻半重的最好用的jdbc框架之一。
  • PageHelper:mybatis的分页插件(不过要是直接用mybatis-plus就不需要这个了)
  • mybatis-plus:mybatis的加强版,减少sql配置,自动化实现更多sql操作。
  • shiro:web安全、权限框架,和spring security功能类似。
  • flyway:自动管理数据库sql版本。
  • validation-api:参数验证框架,一般用在controller上。用配置实现参数效验。
  • httpclient/okhttp:http请求框架。
  • swagger:接口文档框架。
  • jackson:最好用的json框架之一。除此之外其他json框架还有(Gson、FastJson)
  • druid:对运维管理非常有好多数据库连接池框架。
  • HikariCP:spring内置的轻量级性能好的数据库连接池框架。
  • 工具库:
    • apache-common:apache常用工具库
    • apache-io:apache IO工具库
    • apache-net:apache网络工具库
    • apache-fileupload:apache http文件上传工具库
    • apache-codec:apache的编解码工具库
    • spring utils:spring工具库
    • hutool:也是一个包含了很多常用操作的工具库
  • cglib/javassist/asm:动态生成java类的库,从左到右使用越来越难,但也越来越灵活。
  • lombok:用注解方式自动生成实体类setter、getter方法等各种常用方法/属性的框架,可以极大的提高代码开发效率。
  • redission:非常好用的redis连接框架,而且支持基于redis的很多分布式锁功能。
  • javacv:java集成ffmpeg的框架之一。
  • feign:RPC框架,通过接口和注解可以实现http接口调用操作,本身也是spring cloud生态框架中的一个。类似的RPC框架还有dubbo。
  • ribbon:一般配合feign使用,可以实现负载均衡和服务发现,feign只需要配置一个key,ribbon会根据key找到合适的ip进行请求。
  • slf4j:统一的日志框架。他主要是一个抽象出来的公共日志操作,避免切换日志框架带来的修改代码复杂的问题。他一般和其他日志框架配合使用。
  • log4j、log4j2、logback:日志框架,logback是spring自带的。
  • netty:这是一个简化了NIO网络编程的框架。
  • jasypt:这是一个可以让springboot的配置文件中配置密文的框架。从Environment中获取配置时,会自动将密文转换为明文。这个框架是为了提高服务部署时配置文件的安全问题,不出现明文。
  • poi:java读写excel的框架
  • protobuf-java:java中使用protobuf协议的框架。
  • jnotify:一个基于JNI调用底层逻辑的文件监控库。用下来感觉底层原理和watch类差不多,都会占用监视器数量,达到上限也会报错。不过他不会堵塞删除。(api很好用,但是jar没法直接用,因为so和dll没有自动加载,还得自己重写里面有问题的类重新加载)

需要了解的JSR规范提案

  • JSR303:这是最常用的标准化参数验证规范。例如spring内置了hibernate-validator包实现JSR303规范。只需要给实体类设置注解,然后再通过特定的类进行检查就可以自动实现参数效验和抛出异常。springmvc的参数则会自动对接口参数进行效验无需自己再去编写验证代码。

spring框架需要掌握的技术

tag: 以springboot为主

[spring]配置优先级:

支持读取的配置文件:

  • application.yml
  • application-{profile}.yml
  • application.properties
  • application-{profile}.properties
  • config/application.yml
  • config/application-{profile}.yml
  • config/application.properties
  • config/application-{profile}.properties

配置加载优先级:

  1. 命令行参数
  2. JNDI配置
  3. java系统属性:System.getProperties()
  4. 操作系统环境变量
  5. RandomValuePropertySource 配置的 random.* 属性值。
  6. jar包外部配置文件(有些顺序没验证过):
    5.1. application-{profile}.properties
    5.2. application-{profile}.yml
    5.3. application.properties
    5.4. application.yml
    5.5. config/application-{profile}.properties
    5.6. config/application-{profile}.yml
    5.7. config/application.properties
    5.8. config/application.yml
  7. jar包内classpath下配置文件(有些顺序没验证过):
    6.1. classpath:application-{profile}.properties
    6.2. classpath:application-{profile}.yml
    6.3. classpath:application.properties
    6.4. classpath:application.yml
    6.5. classpath:config/application-{profile}.properties
    6.6. classpath:config/application-{profile}.yml
    6.7. classpath:config/application.properties
    6.8. classpath:config/application.yml

[spring]常用注解

  • @SpringBootApplication
  • @Component,@Service,@Repository,@Controller,@RestController,@ControllerAdvice,@RestControllerAdvice,@Configurable
  • @Order,@Primary
  • @Import,@ImportAutoConfiguration,@ConfigurationProperties,@EnableConfigurationProperties
  • @RequestMapping,@GetMapping,@PostMapping,@PutMapping,@DeleteMapping,@RequestBody,@ResponseBody,@RequestParam,@PathVariable,@RequestPart,@RequestHeader
  • @ExceptionHandler
  • @Autowired,@Qualifier,@Value,@Lazy,@DependsOn
  • @ConditionalOnProperty,@ConditionalOnClass,@ConditionalOnMissingBean,@ConditionalOnMissingClass,@ConditionalOnSingleCandidate,@ConditionalOnNotWebApplication,@ConditionalOnResource,@Conditional
  • @AutoConfigureBefore,@AutoConfigureAfter,@AutoConfigureOrder
  • @EnableScheduling,@EnableAsync,@EnableWebSocket,@EnableCaching,@EnableWebSecurity

[spring]常用类

  • RestTemplate,JdbcTemplate,MongoTemplate,RabbitTemplate
  • ScriptUtils(可以解析执行sql文件的工具类)

[spring]生命周期

TODO
配置加载前,配置加载后,bean初始化前,bean初始化后,bean拦截器
在任何一个阶段注入代码。

[spring]bean的多种初始化方式以及autoconfig

TODO
import注解
autoconfig
@Bean
@Configuration
不同方式的优先级,以及import方式注入bean的特殊用法。

[spring]条件配置Conditional

TODO
条件注解控制是否启用bean
自定义条件类

[spring]自定义配置bean

TODO 自定义配置bean并且可以在application.yml配置文件里出现自动提示

[spring]包扫描

TODO 利用spring内置的包扫描类可以自己实现类的扫描逻辑。

[spring]spring aware

TODO 可以获取到一些bean,和直接注入差距不大。

[spring]banner

修改springboot启动时控制台打印的横幅logo。

[spring]其他需要掌握的技术

  • aspectj切入点表达式
  • OGNL表达式:通过配置一段字符串实现属性读取或方法调用,主要用在mybatis里
  • SPEL表达式:Spring自己实现的一套表达式,和ognl类似。

maven需要掌握的技术

nexus私服搭建。pom文件结构,多结构包管理(子父pom层级),包版本号统一替换命令,dependencyManagement定义子项目可选包的包版本,build配置项目结构,plugins插件配置,自定义maven插件,常用插件(编译插件、跳过单元测试插件,springboot打包插件,打包可通过java -jar命令启动包的插件,将所有依赖包class文件打到一起的插件,javadoc文档生成插件,java源码一起打包插件,推送项目发布maven中心仓库的插件),maven多个中心仓库地址配置,多profile配置。

mvn命令,跳过单元测试的命令,打包时自定义启动参数的命令,打包时指定profile的参数,统一修改版本号的命令,推送中心仓库的命令,仅install安装本地的命令。

jenkins需要掌握的技术或插件

  • Pipeline语法
  • Multijob project:父子项目插件(Multijob, Multiple SCMs plugin)
  • jenkins存储的密码密文可以在jenkins中使用groovy代码解密。
  • Qy Wechat Notification:企业微信小机器人推送构建消息插件
  • ThinBackup:配置备份插件
  • SonarQube Scanner:sonarqube代码扫描集成插件
  • Config File Provider:提供managed files功能,可以在jenkins中管理一些配置文件,构建的时候追加进去。
  • Role-based Authorization Strategy:基于任务名字进行权限控制的插件,支持角色功能。
  • 其他常用的docker、node、maven、git、...插件略
  • jenkins中变量使用${}替换。

nginx

其他nginx发行版本:openresty(集成了很多插件的nginx)

nginx部署前端页面,nginx http反向代理,nginx TCP反向代理,nginx websocket反向代理,nginx限流、防刷、屏蔽ip、自定义错误页面。nginx负载均衡,一个ip处理多个host(ip相同,但是多个域名都指向同一个ip,根据访问域名不同,走不同的server),配置ssl(https),追加/修改请求头、响应头,发起子请求。nginx读取环境变量,nginx内置变量,反向代理location多种配置方法(正则、前缀匹配、精准匹配等),配置gzip压缩,取消gzip压缩,反向代理https网站(包括单向认证https和双向认证https),nginx不停机热更新

各种nginx插件:

  • lua插件:嵌入lua脚本修改请求信息。
  • sub_filter:替换返回值的内容

web开发解决方案

【全栈开发体系】
后端:jdk17+springboot3+mybatis-plus+flyway+jackson+hutool+springjdbc+springsecurity+feign+ribbon+...
前端:typescript+vue3+element-plus2+vite+vitepress+axios+vue-router+vuex+sass/scss+unocss

【不想关注在哪个服务器上部署,以及服务器缺少什么环境】
使用docker部署。

【不想关注硬件大小,资源限制,只关注有一堆机器自动调配】
k8s

【不希望现场自己执行sql,sql自动管理】
flyway

【需要分布式锁】
redis+redission

【需要集中管理配置】
使用配置中心

需要自己能写出来的数据结构/算法

  • 数据结构:链表,堆栈,队列,二叉树,四叉树。
  • 排序算法:冒泡排序、快速排序等多种排序算法。
  • 数组操作:数组置换、二维数组旋转。
  • 最小生成树算法:prim

需要了解或者会写的一些算法

  • 动态规划算法(DP)
  • 贪心算法
  • 广度优先算法(BFS)
  • 深度优先算法(DFS)
  • 模拟退火算法(通常用于AI,寻找近似最优解)
  • 遗传算法(通常用于AI,逐渐完善最优解)

设计模式

开闭原则,MVC,MVVM,单例/多例,工厂设计模式,代理设计模式,动态代理设计模式,单一职责原则,单一出口原则。

其他设计模式都不需要特别去记,本质都是为了实现开闭原则,写多了自然就会了
生成器模式(Builder),原型模式(Clone/Copy),组合模式(无继承),适配器模式,观察者模式(+拦截器模式),责任链模式,状态模式,命令模式,...

html基础

dom基本结构、dom属性、html注释、"<!doctype html>"HTML5标记,<meta charset="utf-8">编码设置,title标题设置。
input表单(文本框、密码框、单选/复选框、下拉选择框、文件选择框、...)、视频/音频/图片播放组件(以及异常替换方法)。各种语义标签,meta头标签,iframe子页面,table表格,ul/ol列表,button按钮,canvas,shadow DOM(类似虚拟dom,html5原生支持的一种技术),noscript标签,js中对dom的增删改查各种操作。

基本的修改样式的元素(font/color/strong/s/i/...),这些再页面项目中不推荐使用,因为样式需要使用css统一设置。不过再很多doc文档注释中,可以使用这些。

以及需要了解xml中常用的一个标记:<![CDATA[ ]]>。里面中括号中的内容不会被解析器解析,整体会作为纯文本使用。

css基础

scss:css的超集。还有sass。css编写更简单,可以用嵌套、变量等语法。

margin/padding/border/outline边界样式,box-shadow阴影样式,color颜色样式,background-背景样式,font字体样式,animation动画样式,position/display结构样式,cursor鼠标样式,flex结构样式,height/width宽高样式,同理还有min-/max-最大最小宽高,@import导入不同css文件,"--"css变量,align对齐样式,字体过长显示样式,line-height行高样式,overflow*超出隐藏/滚动条样式,opacity透明度样式,user-select选择控制样式,visibility显示隐藏样式,z-index层叠顺序样式,pointer-events(可以忽略鼠标事件),

css选择器,class选择器、id选择器、属性选择器、多选选择器、全选选择器、选择器伪类(:active、::after、::before、:checked、...),兄弟选择器。

css函数,calc动态计算值函数,hsl颜色设置函数,var变量函数,...。

浏览器安全字体,浏览器安全颜色。

字体单位:px、em、rem、%、vw、vh

js基础(JavaScript)

ECMAScript各个版本标准区别(核心是ES5和ES6),所有关键字用法,单线程原理,setTimeout/setInterval协程,requestAnimationFrame(js动画/2d动画专用定时任务方法),闭包,根对象windows/global(node.js中是global),XMLHttpRequest/fetch发http请求,Promise异步编程,原型链(__proto__),数据类型,Number最大安全数值,apply、call、bind改变this,class相关语法糖(#私有属性/方法,constructor构造方法,static属性方法),function方法,new对象,var/let/const变量定义,JSON类,web work并发,LocalStorage/SessionStorage存储,Cookie操作,webDB,js反射,js变量冻结,defineProperties/defineProperty属性定义,Proxy对象代理,异常捕捉和自定义异常,函数式编程,数组/Set/Map集合框架,时间日期对象Date,正则,BigInt,import/export,await async语法糖,use strict严格模式,==和===的区别以及==判断原理(valueOf方法),方法对象toString,

Dom创建、搜索、销毁、删除、复制方法。html5原生虚拟dom。

各种浏览器事件:加载/关闭事件,鼠标点击移动事件,浏览器滚动事件,拖拽事件,输入/复制/粘贴事件,页签激活事件,动画执行事件,...
onxxx设置事件和addEventListener设置事件的区别,事件捕获和冒泡,阻止冒泡,

// 安全的使用requestAnimationFrame
window.requestAnimFrame = (function(){ 
   
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){ 
   
            window.setTimeout(callback, 1000 / 60);
          };
})();

ts基础(TypeScript)

class类、interface接口、enum枚举、泛型(多条件限制泛型),类/接口继承,namespace命名空间,

js配套技术

  • vs code:前端项目开发工具。(此外还有HBuilder,HBuilderX)
  • node.js:可以运行js脚本的独立引擎。(它让一个脚本语言变成了一个独立的编程语言)
  • jsdoc:js中类似javadoc的可以生成代码文档的工具
  • nw.js:node+浏览器结合,非常好用的基于js语言的桌面应用开发工具
  • nwjc:nw.js中的一个工具,可以将js源代码编译成二进制原生代码,保护源代码。
  • electron:和nw.js功能基本一样,也是开发桌面应用的,了解不多,但是感觉nw.js更容易上手jian'd

需要掌握/了解的前端框架

  • 前端核心js框架:vue(3+)、react
  • 前端核心体系框架:element-ui(element-plus)、bootstrap、ace admin、uni-app(这个主要是开发手机app的)
  • 前端项目管理/打包构建框架:vite、webpack
  • 前端包管理框架:npm、yarn、pnpm
  • js框架:jquery、axios、vue、vuex、vue-router、vue-uuid、vue-i18n、codemirror、lodash(非常好用的前端工具库)、json5(让js支持json5标准)、echarts(各种图表框架)、pixi(强大的canvas渲染引擎,也可以用于做游戏)
  • jsDev框架:babel(将高版本的ES代码转换为低版本的ES代码)、terser(js代码压缩工具)、esbuild(新一代js代码压缩降低版本语法工具,可以彻底代替terser和babel)、obfuscator(js代码混淆工具)
  • css框架:uno-css
  • 基于浏览器+node技术开发桌面应用的工具:nw.js
  • 一些旧的技术:layer、layui

node中可以使用的一些特殊插件(也可以用于vite等工具构建js项目)

  1. rollup-plugin-terser(可以用esbuild代替这个):js压缩插件
  2. rollup-plugin-obfuscator:js混淆插件,js代码注入自我保护/自我防护逻辑。
  3. rollup/plugin-replace:js字符串替换插件(替换特定参数或敏感信息)
  4. rollup-plugin-strip:移出代码中的调试语句,如console.log等。

其他技术:

  • jwt(代替token的另外一种认知方式)
  • SSR 服务端渲染技术,借助node.js服务端渲染好html直接返回(对SEO友好,客户端电脑性能影响也不大,不存在刚进入白屏的问题)
  • SEO优化(让搜索引擎可以搜索到)

需要掌握/了解的浏览器技术

  • 浏览器:chrome、firefox、IE。(其他浏览器基本都是基于chrome,如edge)
  • 查看网页源代码:Ctrl+U
  • 浏览器最大请求数量限制。浏览器页面进程查看。
  • 浏览器最小字体限制。
  • 几种刷新模式的区别:F5、Ctrl+R、Ctrl+F5、鼠标点左上角刷新
  • chrome扩展开发。(任意页面注入任意css/js,跨域请求)
  • windows下通过注册注册表实现自定义浏览器协议扩展功能。
  • f12工具使用
    • console查看报错和执行命令。
    • network分析请求接口:参数、返回值,头信息,耗时,状态,重发/复制请求信息等。
    • 浏览器ui性能分析
    • 浏览器内存使用状况查看
    • element节点查看、修改、调试
    • js代码加断电,js变量debug修改。
    • 屏蔽debug断点、破解部分页面功能限制。(如不让复制,强制弹窗等)。
  • 浏览器缓存
  • 浏览器跨域限制,iframe跨域限制,localStorage跨域限制,http请求跨域限制,预检请求。
  • https域下不允许发出http请求。
  • 公网ip域下不允许发起私网ip的请求。(至于哪一段是公网ip,哪一段是私网ip,这个是业内约定俗成的,也是浏览器内置好的,比如192.168.xxx就是私网ip段)
  • CDN(加快静态资源获取)
  • 浏览器网络代理
  • web auth:浏览器自带的一种登录方式,其他很多url也有类似的方式,比如:
    • http://user:pass@192.168.1.1:80/xxx
    • ftp://user:pass@host:port/xxx
    • tcp://user:pass@xxxxxx
    • ...

需要明白的常见http状态码

  • 101:协议转换/正在请求中。通常是websocket请求会见到。
  • 200:成功
  • 201:成功。通常表示提交成功。
  • 204:服务器数据无变化,浏览器可以继续使用旧的数据。
  • 301:永久get重定向
  • 302:临时get重定向
  • 303:和302类似,可能是历史遗留,只有语义上的区别,303更偏向于重定向到你要请求的资源的描述页面。
  • 304:资源自上次请求没有变化,可以直接用浏览器缓存的。
  • 307:临时重定向,保留原来的请求参数和请求方法。所以支持post重定向。
  • 308:永久重定向,保留原来的请求参数和请求方法。所以支持post重定向。
  • 400:通常表示参数错误,请求无法被处理。
  • 401:没有指定用户名密码/需要登陆。
  • 403:没有权限。
  • 404:资源url不存在。
  • 405:请求方法不正确
  • 406:请求期望的accept和服务器返回的content-type不符。
  • 407:代理服务器没有登录验证
  • 408:请求超时
  • 413:请求体太大。
  • 414:请求url太长。
  • 500:服务器遇到未知异常。
  • 502:代理服务器正常,但是服务器挂了或者无法访问到。
  • 504:代理服务器正常,但是请求服务器超时。

需要明白的常用请求/响应头信息

content-type、content-encoding、content-length、accept、accept-language、accept-encoding、cookie、set-cookie、referer、user-agent、Authorization、cache-control、etag、last-modified、date、server、transfer-encoding、connection、host、Referrer-Policy、upgrade:websocket、

origin、access-control-allow-origin、Access-Control-Request-Method、Access-Control-Request-Headers、access-control-allow-credentials、

x-csrf-token

需要掌握的web安全问题

【安全漏洞】

  • XXE
  • XSS(前端别用不安全的动态参数生成html,富文本是比较容易出问题的地方,建议直接用markdown)
  • CSRF(csrf token解决方案)
  • SSRF(这个现在基本没有了,文件服务的文件没有人会去写执行的逻辑,而且也不会放在项目部署目录下了)
  • SQL注入(预编译处理),对于模糊搜索注入可以堆'%'和'_'等字符做转义。
  • 点击劫持
  • css注入(重要请求别用get方法)
  • ddos/tcp半连接(防火墙层面做配置)
  • 防代理(代理检测,安全https,双向认证https)

【网络安全】

  • 屏蔽不需要开放的端口
  • 接口返回值去掉服务器版本号,或者给一个错误的版本号。
  • 修改所有默认错误页面和错误返回值。
  • 防火墙配置禁止ICMP协议。

SSO

SSO(SingleSignOn)是一种单点登录认证中心技术的简称。主要目的是为了解决多个项目统一登陆认证的问题。

这里面还涉及到一个概念是CAS,这里容易搞混。因为自旋锁也叫CAS。不过这里的CAS是指(Central Authentication Service)中央认证服务器。

CAS有很多现成的框架。其本质的原理是:

  1. 访问任何一个服务器前需要判断是否存在用户token,如果没有则跳转到认证中心服务器页面进行登录。
  2. CAS服务器负责管理用户信息和授权信息,并提供登陆页面进行登录。
  3. 服务器跳转到CAS页面的时候,需要携带一个redirectUrl,表示登陆成功后跳回哪里。
  4. CAS登录完成后,CAS会返回给客户一个cookie(或者属于CAS自己的token,为了和后面的token区分开,这里就说cookie把),这样之后再访问CAS页面,因为cookie存在,说明已经登陆过就不用再登陆了。
  5. 之后CAS服务器内部会生成一个生命周期非常短(可能就几秒或者几分钟),并且只能读取一次(第二次读取就是失效了)的token。同时CAS服务器需要重定向到原服务器。
  • 这里重定向是一个安全难点,重定向有post和get两种方式,因为重定向过去的时候需要带上token。
  • post需要返回一个页面,页面存在一个form表单,token就是表单参数,返回后js触发自动提交然后进行post重定向,重定向到原始页面,提交这个表单信息。
  • get则是直接302重定向,但是这会导致token必须出现在url上。所以最好使用https。(由于token是一次性的临时token,所以被人看到影响不大,但是被程序截取可能会提前一步登录导致安全危险)
  1. 原服务器拿到token后,在服务器后台发起一个请求直接请求CAS服务器验证token的有效性,同时拿到用户的信息和授权信息。(这个过程是不经过客户端的)
  2. 之后token就失效了,也可以理解为CAS服务器就和原服务器没有关系了,CAS挂了都不影响。此时原服务器拿到用户信息后,需要自己缓存redis等缓存数据库,同时自己生成一个新的cookie/token返回给前端,之后就可以正常使用了。
  3. 之后如果再有其他服务器要登陆,跳转到CAS登录页面后,因为已经登陆过了,所以直接从第五步继续自动执行,就成功登录了。
  4. 至于用户中心如何可以知道一个用户能够拥有哪些权限,这就需要服务器对接CAS中心,将自己的权限列表同步给CAS服务器。管理人员就可以在CAS管理界面中进行用户权限配置了。

不过CAS技术还有一些变体,因为涉及到一些问题,如:

  • 只能统一登陆,不能统一登出。
  • 即使登陆过了,访问其他系统时依然要跳转CAS页面,不方便。

变体一(cookie+域名版):

  • 使用域名技术简化统一登陆:认证中心服务器的域名是顶级域名,如abc.com。其他所有子服务器都是子域名,如a.abc.com、b.abc.com。
  • 认知token使用cookie技术,而不要用jwt。cookie的一个特点是,在访问子域名服务器的时候,父域名上的cookie也会一起带上。所以只要所有服务器在后台使用统一的redis或者其他用户缓存数据库,那么只要父域名一登陆,子域名自动就有cookie了。(不用域名用ip的话不同服务器之间cookie是不能共享的)

需要掌握的其他相关编程技术

布隆过滤器

TODO(可以过滤掉大量无意义的请求避免)

linux基础/运维相关技术

arm32、arm64操作系统和x86、x86_64操作系统
ETL(数据库数据抽取转换工具)、shell脚本、linux ip配置、dns技术、防火墙配置(uwf)、电脑路由表配置(route)、服务器时间同步、文件系统(ext3、ext4、FAT、NTFS、...)、linux定时任务(crontab)、查看linux版本、查看cpu核数/使用情况、查看内存使用情况、查看io使用情况(iotop)。rpm包安装,deb包安装。yum、apt/apt-get包安装工具。

常用linux命令/shell语句:
apt、apt-get、alias、awk
bash
cd、cp、cat、clear、curl、chattr、chown、chmod、chgrp、cron、crontab
docker、docker-compose、date、dpkg、du、df
echo
free、find、ftp、file、fdisk(硬盘格式化命令)
gpasswd、grep、git
history、head、help、hostname
ifconfig、ifup、ifdown
jobs
kill、killall
ls、ln、less、ll、lsattr、lsof、lsblk
mv、more、make、mkdir、md5sum、man、mount/umount
netstat、ntpd、nvidia-smi
ping、passwd、ps、pwd
route、reboot、rm、rpm
sudo、su、sh、ssh、source、shutdown、systemctl(centos下是service)、scp、sed
tar、top、tail、touch、telnet、tty、traceroute、tracepath
uname、users、useradd、userdel、ufw
vi、vim
wget、watch、who、whoami、wc
yum
zip/unzip


  • 管道:xxx | xxx。例如 cat x | grep xx
  • 重定向:
    • xxx > a:标准输出重定向
    • xxx 2> a:标准错误输出重定向
    • xxx > a 2>1:让标准错误输出重定向到标准输出
    • xxx > /dev/null:/dev/null是一个固定路径文件,表示将输出重定向到虚无,就是丢弃的意思。
    • xxx < xxx:标准输入重定向,将一个文件输入到左侧命令作为输入
    • xxx <<< "xx":将右侧的字符串作为左侧的输入参数输入
    • xxx >> a:双箭头表示在原来的内容基础上累加,单箭头表示完全覆盖原有内容。
  • `xxx`:执行一段命令。例如xxx <<< cat a等同于 xxx < a
  • echo $xxx:输出一个环境变量,环境变量key前面要带上“$”
  • echo $?:输出上一个命令的返回状态码,0是成功,其他都是失败。

需要了解的windows cmd命令/bat语句

cd、call、cls、copy
dir、date、del
echo、exit
goto
help
mkdir、move
path、pwd
rd、rename
set、shutdown、start
tracert、tree、type


管道、重定向逻辑和linux shell基本一致。

  • 但是如果要重定向到虚无,需要使用关键字NUL。如echo a > NUL 2>&1
  • echo %xxx%:输出一个环境变量,环境变量key前后都要带上“%”

需要详细了解的协议/格式

  • 网络协议:http(s)1.1、http(s)2.0、http(s)3.0、websocket(ws),wss(websocket加密协议),ftp,sftp,TCP,UDP,ICMP。
  • 视频格式:flv、mp4、h264、h265
  • 图片格式:png、jpg、gif、ico、svg
  • 其他数据传输协议:protobuf(google搞得高性能传输协议,基于提前代码生成的技术实现,支持多种语言,需要编写proto协议文件,使用起来比较复杂)

【https协议部分原理】
首先RSA加解密速度很慢,所以https都是先用RSA来协商一个密钥,然后再使用这个密钥+对称加密算法来做后续传输加解密。
网站自己首先有一个私钥信息,公钥信息存储在证书里,证书有时间限制避免时间太久被暴力破解,同时为了避免私法不安全证书,或者代理服务器伪造证书,必须联网认证,只有固定的几个CA机构颁发的整数,才是合理的。操作系统内置了一些根证书来验证合法性。
公钥证书是公开的,会发给所有访问者,访问者需要使用公钥加密,然后服务器拿到后用私钥解密。首先协商一个密钥,这个密钥用RSA加密传输,两边都拿到后,后续再协商一个都支持的最好的堆成加密算法,然后用这个密钥进行后续内容加解密。
对于双向认知https来说,公钥私钥都不会传输,只有两边各自才知道。一般客户端是以类似U盘的外设需要插入电脑才可以访问特定网页。此时客户端发消息使用客户端的公钥加密,服务的的私钥解密。服务端返回消息用服务端公钥加密,客户端私钥解密。

需要知道的加密/hash算法

  • 对称加密算法:AES、DES
    • 加密模式:ECB,CBC,PCBC,CTS,CTR,OFB,CFB
    • 填充模式:PKCS5Padding,ZerosPadding,NoPadding,ISO10126Padding
    • 密钥长度:DES(56位)、AES(128位、192位、256位)
  • 非对称加密算法:RSA
  • hash散列算法:hash、cityhash、md5、sha1、sha256

需要知道的压缩算法

  • zip
  • rar4/5
  • zlib
  • gzip
  • deflate
  • LZ4(好像是速度最快的)
  • zstd
  • 7z
  • tar(这个只是合并打包,不含压缩)
  • iso

需要了解的操作系统

  • Windows、Windows Server
  • Linux:CentOS、RedHat、Ubuntu、Alpine(超轻量级linux框架,不到10mb,一般使用做docker镜像制作)
    还有shell脚本
  • Windows:bat脚本
  • Linux:sh/bat脚本

linux连接工具:xshell、putty
文件传输工具:scp、winscp、xftp

需要掌握的虚拟机工具

Oracle VM VirtualBox:免费开源的虚拟机软件。
VMware:收费的虚拟机软件


其他需要了解的技术
VMwareTools:可以让vmware虚拟机和宿主机交互更方便,比如可以直接拖拽文件进来或出去。


其他可以了解的沙盒软件
sandbox、360隔离沙箱、影子系统、冰点还原精灵

需要了解/掌握的国产化技术

  • 数据库:达梦数据库dm,人大金仓数据库。

需要了解到交换机/路由器/路由技术

  • 路由表(路由器有,每个电脑自己也有。设置路由表可以让电脑知道在请求哪个ip的时候走哪个网卡)
  • 路由器、三层交换机
  • 交换机广播、交换机vlan
  • 局域网安全问题

需要掌握的配置文件格式

properties,yml,json,xml

需要知道的文档语法

markdown(markdown编辑工具一般前端开发工具都支持,也可以用独立的typora或marktext(推荐这个))

需要掌握的其他软件、技术、工具

  • 高级记事本(文本编辑器):editplus、notepad++
  • http请求工具:postman、(浏览器里的XMHttpRequest和fetch)
  • 接口测试/压测工具:jmeter
  • 产品原型设计工具:Axure
  • 视频播放器(比ffmpeg容错性更好):vlc,格式工厂播放器
  • 远程电脑连接工具:todesk、向日葵、teamviewer
  • 邮件收发工具:foxmail
  • 企业微信群可以创建机器人,机器人关联一个url,给这个url发请求可以在微信群里用机器人发消息。(如jenkins有个插件可以配合企业微信机器人可以发部署信息)
  • 接口文档工具:yapi、showdoc
  • 项目、bug管理工具:禅道
  • 企业文档/项目跟踪管理工具:confluence、jira
  • 企业私有代码仓库管理:gitlab
  • 内网聊天工具:飞秋
  • windows下的抓包工具:Fiddler(http,可以模拟中间人攻击抓包https),wireshark(抓更底层的网络协议包)
  • 进程监控器:Procmon64
  • cpu负载、温度查看工具:Core Temp

需要明白的其他概念

  • 小端序和大端序的区别。例如int转byte,数字int32的16,小端序是[16,0,0,0],大端序是[0,0,0,16]
  • 编码:GBK、GB2312、ISO8859-1、UTF8、UTF16、UTF32、UTF8+bom、UnicodeBig (BE/LE)
  • vpn
  • 正向代理、反向代理区别。
  • groovy、kotlin是java语言的变种,编译的文件也可以在jvm上运行。
  • 协程、线程、进程的区别。
  • pdf文本域,可以用来作为pdf模板参数使用。(sejda是一个免费在线可以编辑pdf的网站)
  • AoS(数组结构体)、SoA(结构体数组)

已经遗忘了的技术

tag:这些要么是已经废弃的技术,要么是好久不用已经忘了

  • JSP、EL/JSTL
  • jsonp(前后端分离了,这个不需要了)
  • jfinal、DWR(我觉得现在应该没人用这个了吧)
  • hibernate(现在是直接用jpa了,思路是类似的)
  • struct
  • layerui(作者自己也放弃了)
  • IE8(已经不需要再兼容了,这个曾经被客户广泛使用的早就过期的浏览器)
  • dubbo(feign可读性更好,也更容易做日志)
  • java远程方法调用开发体系发展过程:CORBA、JAVA RMI、EJB、WebService(有些地方还在用)、AXIS->XFire->CXF、SOA、Dubbo、Feign。
  • DB2(主要是没机会用到)

其他一些奇怪的编程界知识

  • redis端口号是6379是因为6379在手机按键上对应MERZ,MERZ是意大利歌女Alessia Merz的名字,作者不喜欢他所以用了6379。
  • oracle创始人之一scott家里养了一只猫,猫的名字叫tiger。所以oracle数据库scott账户默认密码是tiger。
  • Java5版本名字是tiger版,因为设计师詹姆斯高斯林家里养了一只真的大老虎。
  • Java创始人是詹姆斯高斯林。
  • java火了之后微软设计了一套J++语言,但是被sun公司高侵权,最后改成了c#。
  • Java原本要被IBM收购,但是不知道因为什么最后被oracle的拉里埃里森给快速收购了。
  • oracle核心创始人拉里埃里森早期一直在对标微软,用oracle对抗sql server,定制化ERP/CRM对抗office,linux/unix对抗window server,收购SUN获得java对抗.net。收购BEA获得weblogic对抗IIS。
  • MySQL和MariaDB数据库的创始人给自己开发的两数据库起这个名字是因为他有两个女儿,一个叫My一个叫Maria。
  • 由于mysql被sun公司收购后长期保持不更新,所以原作者很生气继续开发了mariadb。
  • 比尔盖茨退学是因为抓住了一个创业的机会。1974年左右,intel推出了微处理器,爱德华罗伯茨(PC之父)制作出了第一个个人电脑。比尔盖茨和他的朋友保罗一人连夜编写了一段软件代码,另一个人坐飞机前去,最后他们的代码成功在上面运行,之后他们便退学开始专门为PC开发软件。
  • IBM发表了一个《关系数据库管理系统》的论文,oracle几个创始人抓住机会创办了oracle开发了oracle数据库。后来微软开发了sqlserver,IBM开发了DB2。
  • scott因为钱分配问题不满,后来退出了oracle。退出后自己用java开发了pointbase数据库,但是这个数据库没有太好的发展空间。后来和BEA公司合作,但是BEA后来被oracle收购了,所以pointbase数据库也就没啥发展了。
  • webshpere是IBM的,weblogic一开始是BEA的,后来被oracle收购变成oracle的了。
  • oracle从12C版本开始推出云服务,并在钢铁侠3中植入广告,一段台词是“启动oracle云服务”。
  • sun最初设计java语言是为了方便开发嵌入式程序,例如远程操控家电产品。
  • 林纳斯开发git是为了管理自己的linux项目。
  • 第一个浏览器Netscape是由网景公司开发,这个公司依靠浏览器在短短几个月就成功上市。此时的浏览器还需要钱。微软为了与之竞争反编译浏览器进行研究,自己开发了一个IE浏览器并且免费嵌入window操作系统。Netscape后来衰落最终变成了firefox。
  • 网景公司最初和sun公司合作,设计了javascript脚本语言,为的是乘上java这股热浪,同时javascript语法也参考了java语言的设计。
  • javascript诞生之初是为了将一些逻辑放到客户端去执行,减少服务器的压力。
  • 以前google在国内还可以用的时候,google.com域名大家记不住,但是可以记住baidu.com,所以google后来也搞了一个新域名叫guge.cn。
  • 早在dos操作系统时代,微软就开发了word软件。甚至支持在dos中执行如今word中能看到的很多操作,甚至是打印预览。
  • 惠普公司HP名字的来源是两个创始人:休利特、帕卡德。简称HP。
  • 惠普公司最早是建在一个车库里。
  • 惠普公司有一个人是沃兹尼亚克,也自己研发出了一种个人电脑,但是惠普公司并没有获得专利。后来沃兹尼亚克和乔布斯合作,创办苹果公司,开发出了AppleII型电脑。
  • 苹果公司的乔布斯曾经从百事可乐挖了一个高管过来,但是因为矛盾太多最后导致乔布斯被迫离开苹果。乔布斯离开后苹果公司开始衰败,乔布斯走的时候也带走了大量核心员工,并创办了NeXT公司,后来Apple收购了苹果乔布斯就又回到了平台。后来苹果公司面临破产,乔布斯说服了比尔盖茨给苹果公司一笔投资让苹果公司活了过来,最后苹果公司创造出了mac、iphone、appstore等产品。
  • bug之所以叫bug,是因为最早的计算机非常大,线路很粗,甚至可以钻进去虫子,而有一次故障就是钻进去了一个虫子,所以才叫做bug。
  • oracle收购java后开始搞各种版权收费,针对google貌似比较多,可能是因为这个原因,google的android架构从java换成了Kotlin。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容