首页 文章 精选 留言 我的

精选列表

搜索[禅道],共6192篇文章
优秀的个人博客,低调大师

芋道 ruoyi-vue-pro v1.0.0 正式版发布!肝了小半年,不容易~

项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro 更新说明: 第一个版本,基于RuoYi-Vue重构,主要是三个方面: 代码的重构 技术选型的调整 后台功能的新增 因此,v1.0.0的更新日志,分成这三方面来写。 代码的重构 调整整体代码结构,将多个 Maven Module 合并为单个,使用 Java package 进行拆分隔离,如图所示。原因是:随着业务逻辑的逐步复杂,多个 Maven Module 的依赖关系的管理,会是一个很大的问题。 拆分framework为多个 Maven Module,按照Web、Security、MyBatis、Redis等不同组件,进行封装与拓展。 基于JUnit5与Mockito,实现单元测试,保证功能的正确性,与代码的可维护性。一直自动化,一直爽! 增加 SpringBoot 多环境的配置文件,提供完善的deploy.sh部署脚本,以及Jenkins 部署教程。 优化Spring Security实现权限的代码,提升可读性和维护性。 增加本地缓存(菜单、角色、数据字典等等),提升性能。通过 Redis 订阅发布,实现缓存的实时刷新。 增加VO类,作为 API 接口的响应对象,避免数据库实体与前端的直接耦合。 优化操作日志,支持读取 Swagger 作为日志的内容。 优化定时任务,支持执行失败的重试,更完善的执行日志。 优化codegen代码生成器,在原先生成 Controller、Service、Mapper、数据库实体、Vue 代码的基础上,额外生成 VO、单元测试的代码。 调整文件改用数据库存储,而不是文件系统。原因是,项目在部署多个服务节点时,文件需要做同步。未来,会增加 aliyun、七牛云等存储云服务。 去除原有数据库的连表查询、递归查询,改为单表操作的方式,多次读取 + 内存拼接。 优化 Java 代码的格式,解决 IDEA 代码告警的问题。 后台功能的新增 增加 API访问与异常日志,方便排查线上 API 的问题。 增加全局错误码,统一业务异常的管理。管理后台会支持错误码的管理,支持提示文案的可配置化。 增加短信模块,提供短信渠道、短息模板、短信日志的管理,对接 aliyun、云片等主流短信平台。 增加 RedisKey的管理,知道项目中使用到的 Redis Key 的格式、数据类型、过期时间、描述等等信息。 技术选型的调整 将 Spring Boot 版本,从 2.1.3 升级到 2.4.5 最新。 增加bom文件,统一 Maven 的依赖管理。 引入MyBatis Plus组件,简化 MyBatis 使用,提升开发效率。 引入Redisson组件,作为 Redis 的客户端,提供更强大的 Redis 操作。 基于 Redis 实现分布式消息队列的功能。接入 RedisPub/Sub实现广播消费,接入 RedisStream实现集群消费。 去除fastjson,统一使用Jackson作为 JSON 库,老爆安全漏洞的悲伤。 引入MapStruct组件,实现数据库实体与 VO 类之间的转换。 引入Lombok组件,生成 setter、getter 等常用方法,去除冗余代码。 引入 SpringAsync功能,实现异步任务。例如说,异步记录 API 访问日志、管理员操作日志等等。 魔改Apollo组件,接入本地数据库,实现内嵌的配置中心。通俗的说,我们可以将原本添加到application.yaml的配置项,改为添加到数据库中,项目启动会进行读取。 引入Hutool组件,去除大量重复的工具类,也避免原本 Util 存在一些 bug 的问题。 引入Screw组件,实现数据库文档的生成,虽然好像现在用途较少。 引入EasyExcel,提供 Excel 的导入与导出的功能。 实现Idempotent组件,实现幂等的功能,可以用来解决 HTTP 重复请求的问题。 引入Lock4J,实现声明式的分布式锁的功能。虽然 Redisson 内置了分布式锁的功能,但是通过注解声明一个@Lock4j注解的使用方式,更加便利,且满足绝大多数场景。 去除原有的服务监控,使用SpringBoot Admin替代,提供更完整的监控能力。 引入SkyWalking组件,实现链路追踪和日志服务的功能。通过链路追踪,我们可以看到一个 API 请求涉及到的 MySQL、Redis 等操作;通过日志服务,我们可以方便的看到每个服务实例的日志。 引入Resilience4j组件,实现限流、熔断等功能,保证服务的稳定性。 引入Knife4j,美化接口文档。原本所有 API 接口文档是缺失的,已经全部补全,可见http://api-dashboard.yudao.iocoder.cn/doc.html地址。

优秀的个人博客,低调大师

【API进阶之路】因为不会创建云服务器,我被实习生摆了一道

摘要:9个步骤通过API创建云服务器。 事情是这样的,公司成立了一个新项目,要给项目建官网,并搭建一个web服务器。按照我的习惯,搭建一个本地虚拟机就好了,部署简单方便还好配置,云服务器嘛,写了10年代码,还是不习惯那玩意儿。 我这刚开始动手,就看见实习生屁颠屁颠地跑过来,我心想这小子肯定是想来学虚拟机搭建部署的,这么简单的事都不会,真是白瞎了他那985的学校了。 可是...万万没想到啊,小实习生跑到我老大那里邀功去了!!!远远地听见他说:“公司新项目跑在云服务器上了,以后可以根据访问量随时进行弹性扩展,安全稳定还快。” 啥?云服务器?这小子居然会配置云服务器?听完汇报,老大看向了我,带着小实习生往我这边走过来…… “哼,叫你邀功,撞枪口上了吧,我就说云服务器配置没那么容易,还不是得来找我~”这么想着有点得意,老大走过来拍拍我的肩膀,说:“你跟他学一下怎么配置云服务器,别再用虚拟机了,以后都是麻烦事。” 我...他...让我跟一个实习生学??? 实习生冲我微微一笑,就走了,没过一会扔给我一份文档,上面写着:“创建弹性云服务器流程详解”。打开粗略扫了一眼,代码都直接贴上来了?瞧不起谁?感觉有被冒犯到。 技术人嘛,看到代码还是没忍住跑一遍,等我发现bug或跑不通,再给他上上课! 首先免费领取了1台云服务器,然后开始跑代码 结果……真香。 内容是这样的: 通过API创建云服务器的9个步骤(以指定镜像方式创建云服务器为例) 步骤一:确定待创建云服务器所在的可用区。 1、查询可用区。 (1)接口相关信息 URI格式:GET /v2.1/{project_id}/os-availability-zone (2)请求示例 GET: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/os-availability-zone (3)响应示例 { "availabilityZoneInfo": [ { "hosts": null, "zoneState": { "available": true }, "zoneName":"zone_01" }, { "hosts": null, "zoneState": { "available": true }, "zoneName": "zone_01" } ] } 2、根据实际需要选择可用区,并记录可用区的zoneName。 步骤二:确定待创建云服务器的规格。 1、查询云服务器规格信息。 (1)接口相关信息 URI格式:GET/v2.1/{project_id}/flavors/detail{?minDisk,minRam,is_public,sort_key,sort_dir} 其中,“?”后的字段为查询规格时可选的查询检索参数。 (2)请求示例 GET: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/flavors/detail (3)响应示例 { "flavors": [ { "name": "c1.2xlarge", "links": [ { "href": "https://xxx/v2.1/74610f3a5ad941998e91f076297ecf27/flavors/c1.2xlarge", "rel": "self" }, { "href": "https://xxx/74610f3a5ad941998e91f076297ecf27/flavors/c1.2xlarge", "rel": "bookmark" } ], "ram": 8192, "OS-FLV-DISABLED:disabled": false, "vcpus": 8, "swap": "", "os-flavor-access:is_public": true, "rxtx_factor": 1, "OS-FLV-EXT-DATA:ephemeral": 0, "disk": 0, "id": "c1.2xlarge" } ] } 2、 根据实际需要选择规格,并记录规格的ID。 步骤三:确定待创建云服务器使用的镜像。 1、查询镜像。 (1)接口相关信息 URI格式:GET /v2.1/{project_id}/images/detail (2)请求示例 GET: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/images/detail (3)响应示例 { "images": [ { "OS-EXT-IMG-SIZE:size": 0, "metadata": { "__os_type": "Linux", "hw_vif_multiqueue_enabled": "true", "__imagetype": "gold", "__quick_start": "true", "virtual_env_type": "FusionCompute", "__support_xen": "true", "__support_kvm": "true", "__image_source_type": "uds", "__platform": "EulerOS", "__os_version": "EulerOS 2.2 64bit", "__os_bit": "64", "__isregistered": "false" }, "created": "2018-05-14T06:13:50Z", "minRam": 0, "name": "DBS-MySQL-Image_2.1.3.3", "progress": 100, "links": [ { "rel": "self", "href": "https://None/v2.1/74610f3a5ad941998e91f076297ecf27/images/11e8f727-d439-4ed1-b3b8-33f46c0379c4" }, { "rel": "bookmark", "href": "https://None/74610f3a5ad941998e91f076297ecf27/images/11e8f727-d439-4ed1-b3b8-33f46c0379c4" }, { "rel": "alternate", "href": "https://None/images/11e8f727-d439-4ed1-b3b8-33f46c0379c4", "type": "application/vnd.openstack.image" } ], "id": "11e8f727-d439-4ed1-b3b8-33f46c0379c4", "updated": "2018-05-14T06:13:52Z", "minDisk": 40, "status": "ACTIVE" } ] } 2、根据需要选择镜像,并记录镜像ID。 步骤四:确定云服务器的网络信息。 1、查询网络。 (1)接口相关信息 URI格式:GET /v2.1/{project_id}/os-networks (2)请求示例 GET: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/os-networks (3)响应示例 { "networks": [ { "id": "07a9557d-4256-48ae-847c-415a9c8f7ff6", "label": "b_tt3_td1b", "broadcast": null, "cidr": null, "dns1": null, "dns2": null, "gateway": null, "netmask": null, "cidr_v6": null, "gateway_v6": null, "netmask_v6": null } ] } 2、根据需要选择网络,并记录网络ID。 步骤五:设置密钥对登录方式。 如需设置为密码登录方式,请直接跳转至步骤七。 1、创建密钥对。 (1)接口相关信息 URI格式:POST /v2.1/{project_id}/os-keypairs (2)请求示例 POST: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/os-keypairs Body: { "keypair": { "type": "ssh", "name": "demo1", "user_id": "fake" } } (3)响应示例 { "keypair": { "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCrR5Gcwlh5ih7JOvzIUuQxS5qzWWPMYHeDXkDKSQ9W5pumOV05SiO3WCswnaQ5xMdOl31mNiHtwlwq9dJi7X6jJBB2shTD+00G5WuwkBbFU4CLvt1B44u0NUiaTJ35NAvW2/4XvpXm9OwiQ3B5ge6ZY7Esi38Unh+pkbhPkYxNBCK8yoOlojQhWs75abdxZBi811/8RwLcNiFiocA2RGxtRjBdpEScj+1TU+OcfZdQnr0AFbO11z7yxfIygwwzVTgUuJNbMbKHStQqRbklfMlHY4RBPQgb7RN/YaXKTQSXT84k+D9xlDNo7Wj4fwOJTOz/s/PvbIOqjRHt9D6Y4IKd Generated-by-Nova\n", "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAq0eRnMJYeYoeyTr8yFLkMUuas1ljzGB3g15AykkPVuabpjld\nOUojt1grMJ2kOcTHTpd9ZjYh7cJcKvXSYu1+oyQQdrIUw/tNBuVrsJAWxVOAi77d\nQeOLtDVImkyd+TQL1tv+F76V5vTsIkNweYHumWOxLIt/FJ4fqZG4T5GMTQQivMqD\npaI0IVrO+Wm3cWQYvNdf/EcC3DYhYqHANkRsbUYwXaREnI/tU1PjnH2XUJ69ABWz\ntdc+8sXyMoMMM1U4FLiTWzGyh0rUKkW5JXzJR2OEQT0IG+0Tf2Glyk0El0/OJPg/\ncZQzaO1o+H8DiUzs/7Pz72yDqo0R7fQ+mOCCnQIDAQABAoIBAA6/c9dGmK2mae4z\nyQ5KrOFdvC1TNhej+sZx+CwyzEJUSvSuHcvQCXFBAz8FY92hhvPKcX66jINXZ+4/\nCmWAQ5YyhcRiow0Y91HvsS0bywoknX3q6kxBFodmyyCWFkgd5iMTADb1Lx0a27Y7\njlS4Dl5gyiGmxUN2Ng24wWEAjE8ZNuI0lrtr5IZKp+s5IAi/rb5AG/mL7EzicE8c\nmGP+QAa+nzwhAwNhFwVID230xen/ZcoL1d77hxeARNqJUxoR25gwJd6Ebg2y9pDW\nVu6cbbzgdGUCfQYlMEoAamAkCswOsDpVDBXwQnt2A537n6Wq2bgYIKusHr9thtxP\n/5ubQLUCgYEA4zYuBG2vtLHnvce26P8o2j1xcJS9K0ozkah9JFl3hqFN0sAqLlz7\n/Fm1jA4kzHJS3d0UqP3AMDxY3HkIqCn4Be7lqeAAe2AfqkOZpt9MDNv4VwKe9sPb\nViW1qjL3FxziLC/YWTRNSlpwRjqJJGhA+UQt8rOia1k/zXmrEs7bXLcCgYEAwPsu\nK3j5QoAiziYVMYf5iCzWwAM9Ljpf9gw23lefTdIzhhfFtJplVRSyxRGU0UZ84GMI\nTd5zmcIF/1KUfhqmeiQzz6NIPEYEReahjpQ/sOH/Gk5Rwr3QwYPrwAu5x+kk/SRi\nKPkqw7APTR0sMQBcUq+ZYwGYLGPMdd1zUdLfb0sCgYBkuz11iydtxb3G/obSD2WO\nM9VaIycmzRPFzNwGRH/gOR0mhTluKp0wyJjbSd34oeqpH/2r2ivddrOysxoqa8jg\n4IQDZyLvj7MaKjQxrieqP89+y9Or9TMFo1xB46x2G8EN8/xHuA9YGnZSPFtWv72m\nhRqV0hv82amWsA0vHnRUSwKBgDsKHXvrTMbNkNhkykMXCH5iyWiBFSyZa1ZJMlgf\nknsqfdzeVPwF6E55QKAN2uuTlwzG/3ljPxahR1hvmUJjQN9JSBiUKbtW6GPCRVbr\nf/jLi1Iu99COZdluVKeybqn8Z/aSNP24DR9FM8kxzZ1IMPaTBmhFypp6BclhcLBt\nxTG1AoGAfcrkVbV1SOy7fECUtMpUECcw0yU4GWj3sR2RbII63C500RVYQlUpUaRR\naANbASHTVR4myOKtGSxEUhAQHlxFDwsDL7W3gzAqTFbEDp1xAAUyT/nkOAhQjEm4\nORFdDETeXLQG1KMUj+8AdnhfYp3JTdft6rmPpZEBUFiCAUMAvb0=\n-----END RSA PRIVATE KEY-----\n", "user_id": "f79791beca3c48159ac2553fff22e166", "name": "demo1", "fingerprint": "57:a7:a2:ed:5f:aa:e7:54:62:2e:bb:e7:92:22:cb:40" } } 2、导入密钥。 (1)接口相关信息 URI格式:POST /v2.1/{project_id}/os-keypairs (2)请求示例 POST: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/os-keypairs Body: { "keypair": { "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDY8wMTdBYiJgi62o6eShoOlSKx3CZ3cE6PHisDblfK3Y0Bg7EHV7iV9c74pqsrIhK0xuGUuO1NxDQWbkwLTPN4F9Iy5CIYohLuMIpbln6LDtfRPpdhEh3lxL8MM61gyfpKzeKkwkEpSFj27Rgh6zCyJgBpkA2A0HTP737UlitahL4faCWDIS+Vj6mbcfkWiMhuMCzTZgSKAZ4PfoG4B5HJhR52C6A4XLiQFT9heh9gnIsIG+uTogTKUbcJKuN7M6AraJpul6eHhV9YI4433sDmuiBF/njvreVPWwAHlAkgT9I8q1T/cfEFiwzXpdGbkK5O8NC7K+qNbbdKihlahONt Generated-by-Nova\n", "type": "ssh", "name": "demo2", "user_id": "fake" } } (3)响应示例 { "keypair": { "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDY8wMTdBYiJgi62o6eShoOlSKx3CZ3cE6PHisDblfK3Y0Bg7EHV7iV9c74pqsrIhK0xuGUuO1NxDQWbkwLTPN4F9Iy5CIYohLuMIpbln6LDtfRPpdhEh3lxL8MM61gyfpKzeKkwkEpSFj27Rgh6zCyJgBpkA2A0HTP737UlitahL4faCWDIS+Vj6mbcfkWiMhuMCzTZgSKAZ4PfoG4B5HJhR52C6A4XLiQFT9heh9gnIsIG+uTogTKUbcJKuN7M6AraJpul6eHhV9YI4433sDmuiBF/njvreVPWwAHlAkgT9I8q1T/cfEFiwzXpdGbkK5O8NC7K+qNbbdKihlahONt Generated-by-Nova\n", "user_id": "f79791beca3c48159ac2553fff22e166", "name": "demo2", "fingerprint": "dd:44:45:49:d9:f6:4f:c0:24:2d:81:aa:c4:4b:83:c2" } } 2、 记录响应消息体中的name信息。如本例中为“demo2”。 步骤六:创建密钥对登录鉴权的云服务器。 (1)接口相关信息 URI格式:POST /v2.1/{project_id}/servers 说明: 本示例是指定image创建云服务器,因此: ● block_device_mapping_v2.1中,“source_type”需设置为“image”,“uuid”设置为选择的镜像ID,“destination_type”设置为“volume”,“boot_index”设置为“0”。 ● “volume_size”应大于等于镜像元数据中指定的最小值。 (2)请求示例 POST: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/servers Body: { "server": { "flavorRef": "c1.large", "name": "zttestvm1", "block_device_mapping_v2.1": [{ "source_type": "image", "destination_type": "volume", "volume_type": "SATA", "volume_size": "40", "delete_on_termination": "true", "uuid": "11e8f727-d439-4ed1-b3b8-33f46c0379c4", "boot_index": "0" }], "networks": [{ "uuid": "fb68519f-a7c0-476e-98d4-2e4cf6de6def" }], "key_name": "demo2", "availability_zone": "az_test_01" } } (3)响应示例 { "server": { "security_groups": [ { "name": "default" } ], "OS-DCF:diskConfig": "MANUAL", "links": [ { "rel": "self", "href": "https://None/v2.1/74610f3a5ad941998e91f076297ecf27/servers/6d311127-bce1-48db-bf0f-cac9f8f7f077" }, { "rel": "bookmark", "href": "https://None/74610f3a5ad941998e91f076297ecf27/servers/6d311127-bce1-48db-bf0f-cac9f8f7f077" } ], "id": "6d311127-bce1-48db-bf0f-cac9f8f7f077", "adminPass": "WcC4QoVZPXpV" } } 步骤七:设置密码登录方式。 (1)使用非cloud-init镜像创建云服务器时,Windows和Linux系统都使用“adminPass”参数实现密码注入。 (2)使用cloud-init镜像创建云服务器时: l 对于Linux系统,只能使用“user_data”进行密码注入,“user_data”字符串长度小于65535,且必须是base64加密的; l 对于Windows系统,只能通过元数据“admin_pass”进行密码注入。 步骤八:创建密码方式登录鉴权的弹性云服务器。 说明: 本示例是指定image创建弹性云服务器,因此: (1)block_device_mapping_v2.1中,“source_type”需设置为“image”,“uuid”设置为选择的镜像ID,“destination_type”设置为“volume”,“boot_index”设置为“0”。 (2)“volume_size”应大于等于镜像元数据中指定的最小值。 1、创建非cloud-init镜像、密码方式登录鉴权的弹性云服务器。 (1)接口相关信息 URI格式:POST /v2.1/{project_id}/servers (2)请求示例 POST: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/servers Body: { "server": { "flavorRef": "c1.large", "name": "zttestvm1", "adminPass":"NOVAGLANCEI@123", "block_device_mapping_v2.1": [{ "source_type": "image", "destination_type": "volume", "volume_type": "SATA", "volume_size": "40", "delete_on_termination": "true", "uuid": "11e8f727-d439-4ed1-b3b8-33f46c0379c4", "boot_index": "0" }], "networks": [{ "uuid": "fb68519f-a7c0-476e-98d4-2e4cf6de6def" }], "availability_zone": "az_test_01" } } (3)响应示例 { "server": { "security_groups": [ { "name": "default" } ], "OS-DCF:diskConfig": "MANUAL", "links": [ { "rel": "self", "href": "https://None/v2.1/74610f3a5ad941998e91f076297ecf27/servers/73991cff-37c6-491a-9a8a-377397729fce" }, { "rel": "bookmark", "href": "https://None/74610f3a5ad941998e91f076297ecf27/servers/73991cff-37c6-491a-9a8a-377397729fce" } ], "id": "73991cff-37c6-491a-9a8a-377397729fce", "adminPass": "NOVAGLANCEI@123" } } 2、创建cloud-init镜像(以Linux为例)、密码方式登录鉴权的弹性云服务器。 (1)接口相关信息 URI格式:POST /v2.1/{project_id}/servers (2)请求示例 POST: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/servers Body: { "server": { "flavorRef": "c1.large", "name": "zttestvm2", "user_data":"IyEvYmluL2Jhc2gKZWNobyAncm9vdDokNiRuaERlcUIkajBkelVMbkFrbWo4bWlFREFzT0VONkVPdGg1RmdqWnQybUVWZVRocC5OVDJXelZVdzFuNzhnL3dNdDE0dVpSQ1V3LzhHS3VGdEViQ0lPQS5vN1BZQzEnIHwgY2hwYXNzd2QgLWU7", "block_device_mapping_v2.1": [{ "source_type": "image", "destination_type": "volume", "volume_type": "SATA", "volume_size": "40", "delete_on_termination": "true", "uuid": "11e8f727-d439-4ed1-b3b8-33f46c0379c4", "boot_index": "0" }], "networks": [{ "uuid": "fb68519f-a7c0-476e-98d4-2e4cf6de6def" }], "availability_zone": "az_test_01" } } (3)响应示例 { "server": { "security_groups": [ { "name": "default" } ], "OS-DCF:diskConfig": "MANUAL", "links": [ { "rel": "self", "href": "https://None/v2.1/74610f3a5ad941998e91f076297ecf27/servers/7c11f362-cc96-4306-85b6-b432a639ca5e" }, { "rel": "bookmark", "href": "https://None/74610f3a5ad941998e91f076297ecf27/servers/7c11f362-cc96-4306-85b6-b432a639ca5e" } ], "id": "7c11f362-cc96-4306-85b6-b432a639ca5e", "admin_pass": "J3xMSivHCuq5" } } 步骤九:确认云服务器创建成功。 (1)接口相关信息 URI格式:GET /v2.1/{project_id}/servers/{server_id} (2)请求示例 GET: https://{endpoint}/v2.1/74610f3a5ad941998e91f076297ecf27/servers/0c71c0da-8852-4c56-a1d1-3a9b9bcb6da6 其中: 0c71c0da-8852-4c56-a1d1-3a9b9bcb6da6为创建的云服务器UUID。 (3)响应示例 { "server": { "tenant_id": "74610f3a5ad941998e91f076297ecf27", "addresses": { "2a6f4aa6-d93e-45f5-a8cb-b030dbf8cd68": [ { "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:88:01:1b", "OS-EXT-IPS:type": "fixed", "addr": "192.168.2.192", "version": 4 } ] }, "metadata": {}, "OS-EXT-STS:task_state": null, "OS-DCF:diskConfig": "MANUAL", "OS-EXT-AZ:availability_zone": "az_test_01", "links": [ { "rel": "self", "href": "https://None/v2.1/74610f3a5ad941998e91f076297ecf27/servers/0c71c0da-8852-4c56-a1d1-3a9b9bcb6da6" }, { "rel": "bookmark", "href": "https://None/74610f3a5ad941998e91f076297ecf27/servers/0c71c0da-8852-4c56-a1d1-3a9b9bcb6da6" } ], "OS-EXT-STS:power_state": 1, "id": "0c71c0da-8852-4c56-a1d1-3a9b9bcb6da6", "os-extended-volumes:volumes_attached": [ { "id": "b551445a-e749-4d53-932a-638a455cb6c3" } ], "OS-EXT-SRV-ATTR:host": "pod1_test_01", "image": { "links": [ { "rel": "bookmark", "href": "https://None/74610f3a5ad941998e91f076297ecf27/images/11e8f727-d439-4ed1-b3b8-33f46c0379c4" } ], "id": "11e8f727-d439-4ed1-b3b8-33f46c0379c4" }, "OS-SRV-USG:terminated_at": null, "accessIPv4": "", "accessIPv6": "", "created": "2018-05-25T01:47:11Z", "hostId": "b2792bef989888d2df1f51bff81de5ac58a4117f4e9ec3059c1a0410", "OS-EXT-SRV-ATTR:hypervisor_hostname": "nova001@36", "key_name": null, "flavor": { "links": [ { "rel": "bookmark", "href": "https://None/74610f3a5ad941998e91f076297ecf27/flavors/c1.large" } ], "id": "c1.large" }, "security_groups": [ { "name": "default" } ], "config_drive": "", "OS-EXT-STS:vm_state": "active", "OS-EXT-SRV-ATTR:instance_name": "instance-001883cd", "user_id": "f79791beca3c48159ac2553fff22e166", "name": "zttestvm1", "progress": 0, "OS-SRV-USG:launched_at": "2018-05-25T01:47:55.755922", "updated": "2018-05-25T01:47:55Z", "status": "ACTIVE" } } 按照步骤指示,我很快完成了云服务器的搭建,不禁有些惊讶,这小子怎么懂这么多?等等...华为云API Explorer? 打开华为云API Explorer的官网,我好像打开了新世界的大门,有很多已配置好的环境和接口,直接调用调试就可以了,以后怕是没有什么能够难住我了! 目前API Explorer平台已开放EI企业智能、计算、应用服务、网络、软件开发平台、视频等70+云服务,共上线2000+个API、6000+个错误码。在前期试运行期间,华为云API Explorer平台上的API接口也已被多家企业成功接入。 点击查看详情:《华为云一站式API解决方案平台API Explorer上线》 据悉,华为云API Explorer平台在未来几个月会实现更多功能,比如支持SDK示例代码、CLI等特性,同时也会开放更多的云服务API接口,连接更多开发者实现创新、拓宽创新边界。 点击关注,第一时间了解华为云新鲜技术~

优秀的个人博客,低调大师

快看看这27道面试题!(含答案和思维导图)

前言 MyBatis是一个优秀的持久层ORM框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。Mybatis通过xml或注解的方式将要执行的statement配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。 关于MyBatis的知识点总结了个思维导图分享给大家 MyBatis 面试题 1、什么是 Mybatis?2、Mybaits 的优点:3、MyBatis 框架的缺点:4、MyBatis 框架适用场合:5、MyBatis 与 Hibernate 有哪些不同?6、#{}和${}的区别是什么?7、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?8、 模糊查询 like 语句该怎么写?9、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗?10、Mybatis 是如何进行分页的?分页插件的原理是什么?11、Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?12、如何执行批量插入?13、如何获取自动生成的(主)键值?14、在 mapper 中如何传递多个参数?15、Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql?16、Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,还有哪些标签?18、为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?19、 一对一、一对多的关联查询 ?20、MyBatis 实现一对一有几种方式?具体怎么操作的?21、MyBatis 实现一对多有几种方式,怎么操作的?22、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?23、Mybatis 的一级、二级缓存24、什么是 MyBatis 的接口绑定?有哪些实现方式?25、使用 MyBatis 的 mapper 接口调用时有哪些要求?26、Mapper 编写有哪几种方式?27、简述 Mybatis 的插件运行原理,以及如何编写一个插件 MyBatis 面试题答案解析 1、什么是 Mybatis? (1)Mybatis 是一个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高。(2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO 映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。(3)通过 xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。(从执行 sql 到返回 result 的过程)。 2、Mybaits 的优点: (1)基 于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML标签,支持编写动态 SQL 语句,并可重用。(2)与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接;(3)很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要JDBC 支持的数据库 MyBatis 都支持)。(4)能够与 Spring 很好的集成;(5)提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。 3、MyBatis 框架的缺点: (1)SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL 语句的功底有一定要求。(2)SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。 4、MyBatis 框架适用场合: (1)MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案。(2)对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选择。 5、MyBatis 与 Hibernate 有哪些不同? (1)Mybatis 和 hibernate 不同,它不完全是一个 ORM 框架,因为 MyBatis 需要程序员自己编写 Sql 语句。(2)Mybatis 直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是 mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套 sql 映射文件,工作量大。(3)Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。 6、#{}和${}的区别是什么? {}是预编译处理,${}是字符串替换。 Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的set 方法来赋值;Mybatis 在处理${}时,就是把${}替换成变量的值。使用#{}可以有效的防止 SQL 注入,提高系统安全性。 7、当实体类中的属性名和表中的字段名不一样 ,怎么办 ? 第 1 种: 通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。 <select id=”selectorder” parametertype=”int” resultetype=” me.gacl.domain.order”> select order_id id, order_no orderno ,order_price price form orders where order_id=#{id}; </select> 第 2 种: 通过来映射字段名和实体类属性名的一一对应的关系。 <select id="getOrder" parameterType="int" resultMap="orderresultmap"> select * from orders where order_id=#{id} </select> <resultMap type=”me.gacl.domain.order” id=”orderresultmap”> <!–用 id 属性来映射主键字段–> <id property=”id” column=”order_id”> <!–用 result 属性来映射非主键字段,property 为实体类属性名,column 为数据表中的属性–> <result property = “orderno” column =”order_no”/> <result property=”price” column=”order_price” /> </reslutMap> 8、 模糊查询 like 语句该怎么写? 第 1 种:在 Java 代码中添加 sql 通配符。 string wildcardname = “%smi%”; list<name> names = mapper.selectlike(wildcardname); <select id=”selectlike”> select * from foo where bar like #{value} </select> 第 2 种:在 sql 语句中拼接通配符,会引起 sql 注入 string wildcardname = “smi”; list<name> names = mapper.selectlike(wildcardname); <select id=”selectlike”> select * from foo where bar like "%"#{value}"%" </select> 9、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应,请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法,参数不同时,方法能重载吗? Dao 接口即 Mapper 接口。接口的全限名,就是映射文件中的 namespace 的值;接口的方法名,就是映射文件中 Mapper 的 Statement 的 id 值;接口方法内的参数,就是传递给 sql 的参数。Mapper 接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为 key 值,可唯一定位一个 MapperStatement。在 Mybatis 中,每一个、、、标签,都会被解析为一个MapperStatement 对象。举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到 namespace 为 com.mybatis3.mappers.StudentDao 下面 id 为findStudentById 的 MapperStatement。Mapper 接口里的方法,是不能重载的,因为是使用 全限名+方法名 的保存和寻找策略。Mapper 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK动态代理为 Mapper 接口生成代理对象 proxy,代理对象会拦截接口方法,转而执行 MapperStatement 所代表的 sql,然后将 sql 执行结果返回。 10、Mybatis 是如何进行分页的?分页插件的原理是什么? Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页。可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根 据 dialect 方言,添加对应的物理分页语句和物理分页参数。 11、Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式? 第一种是使用标签,逐一定义数据库列名和对象属性名之间的映射关系。第二种是使用 sql 列的别名功能,将列的别名书写为对象属性名。有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。 12、如何执行批量插入? 首先,创建一个简单的 insert 语句: <insert id=”insertname”> insert into names (name) values (#{ value } ) </insert> 然后在 java 代码中像下面这样执行批处理插入: list < string > names = new arraylist(); names.add(“fred”); names.add(“barney”); names.add(“betty”); names.add(“wilma”); // 注意这里 executortype.batch sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch); try { namemapper mapper = sqlsession.getmapper(namemapper.class); for (string name: names) { mapper.insertname(name); } sqlsession.commit(); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); throw e; } finally { sqlsession.close(); } 13、如何获取自动生成的(主)键值? insert 方法总是返回一个 int 值 ,这个值代表的是插入的行数。如果采用自增长策略,自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。示例: <insert id=”insertname” usegeneratedkeys=”true” keyproperty=” id”> insert into names (name) values (#{ name } ) </insert> name name = new name(); name.setname(“fred”); int rows = mapper.insertname(name); // 完成后,id 已经被设置到对象中 system.out.println(“rows inserted = ” + rows); system.out.println(“generated key value = ” + name.getid()); 14、在 mapper 中如何传递多个参数? 第一种:DAO 层的函数public UserselectUser(String name,String area);对应的 xml,#{0}代表接收的是 dao 层中的第一个参数,#{1}代表 dao 层中第二参数,更多参数一致往后加即可。 <select id="selectUser"resultMap="BaseResultMap"> select * fromuser_user_t whereuser_name = #{0} anduser_area=#{1} </select> 第二种: 使用 @param 注解: public interface usermapper { user selectuser(@param(“username”) string username,@param(“hashedpassword”) string hashedpassword); } 然后,就可以在 xml 像下面这样使用(推荐封装为一个 map,作为单个参数传递给mapper): <select id=”selectuser” resulttype=”user”> select id, username, hashedpassword from some_table where username = #{username} and hashedpassword = #{hashedpassword} </select> 第三种:多个参数封装成 map try { //映射文件的命名空间.SQL 片段的 ID,就可以调用对应的映射文件中的 SQL //由于我们的参数超过了两个,而方法中只有一个 Object 参数收集,因此 我们使用 Map 集合来装载我们的参数 Map < String, Object > map = new HashMap(); map.put("start", start); map.put("end", end); return sqlSession.selectList("StudentID.pagination", map); } catch (Exception e) { e.printStackTrace(); sqlSession.rollback(); throw e; } finally { MybatisUtil.closeSqlSession(); } 15、Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql? Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql,执行原理是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。Mybatis 提供了 9 种动态 sql 标签:trim | where | set | foreach | if | choose| when | otherwise | bind。 16、Xml 映射文件中,除了常见的 select|insert|updae|delete标签之外,还有哪些标签? 答:、、、、,加上动态 sql 的 9 个标签,其中为 sql 片段标签,通过标签引入 sql 片段,为不支持自增的主键生成策略标签。 17、Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复? 不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那么 id 不能重复;原因就是 namespace+id 是作为 Map的 key使用的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然也就不同。 18、为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里? Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。 19、 一对一、一对多的关联查询 ? <mapper namespace="com.lcb.mapping.userMapper"> <!--association 一对一关联查询 --> <select id="getClass" parameterType="int" resultMap="ClassesResultMap"> select * from class c,teacher t where c.teacher_id=t.t_id and c.c_id=#{id} </select> <resultMap type="com.lcb.user.Classes" id="ClassesResultMap"> <!-- 实体类的字段名和数据表的字段名映射 --> <id property="id" column="c_id"/> <result property="name" column="c_name"/> <association property="teacher" javaType="com.lcb.user.Teacher"> <id property="id" column="t_id"/> <result property="name" column="t_name"/> </association> </resultMap> <!--collection 一对多关联查询 --> <select id="getClass2" parameterType="int" resultMap="ClassesResultMap2"> select * from class c,teacher t,student s where c.teacher_id=t.t_id and c.c_id=s.class_id and c.c_id=#{id} </select> <resultMap type="com.lcb.user.Classes" id="ClassesResultMap2"> <id property="id" column="c_id"/> <result property="name" column="c_name"/> <association property="teacher" javaType="com.lcb.user.Teacher"> <id property="id" column="t_id"/> <result property="name" column="t_name"/> </association> <collection property="student" ofType="com.lcb.user.Student"> <id property="id" column="s_id"/> <result property="name" column="s_name"/> </collection> </resultMap> </mapper> 20、MyBatis 实现一对一有几种方式?具体怎么操作的? 有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap 里面配置 association 节点配置一对一的类就可以完成;嵌套查询是先查一个表,根据这个表里面的结果的 外键 id,去再另外一个表里面查询数据,也是通过 association 配置,但另外一个表的查询通过 select 属性配置。 21、MyBatis 实现一对多有几种方式,怎么操作的? 有联合查询和嵌套查询。联合查询是几个表联合查询,只查询一次,通过在resultMap 里面的 collection 节点配置一对多的类就可以完成;嵌套查询是先查一个表,根据这个表里面的 结果的外键 id,去再另外一个表里面查询数据,也是通过配置 collection,但另外一个表的查询通过 select 节点配置。 22、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么? 答:Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。 23、Mybatis 的一级、二级缓存: 1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ;3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。 24、什么是 MyBatis 的接口绑定?有哪些实现方式? 接口绑定,就是在 MyBatis 中任意定义接口,然后把接口里面的方法和 SQL 语句绑定, 我们直接调用接口方法就可以,这样比起原来了 SqlSession 提供的方法我们可以有更加灵活的选择和设置。接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上@Select、@Update 等注解,里面包含 Sql 语句来绑定;另外一种就是通过 xml里面写 SQL 来绑定, 在这种情况下,要指定 xml 映射文件里面的 namespace 必须为接口的全路径名。当 Sql 语句比较简单时候,用注解绑定, 当 SQL 语句比较复杂时候,用 xml 绑定,一般用 xml 绑定的比较多。 25、使用 MyBatis 的 mapper 接口调用时有哪些要求? (1)Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同;(2)Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的parameterType 的类型相同;(3)Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的resultType 的类型相同;(4)Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。 26、Mapper 编写有哪几种方式? 第一种:接口实现类继承 SqlSessionDaoSupport:使用此种方法需要编写mapper 接口,mapper 接口实现类、mapper.xml 文件。(1)在 sqlMapConfig.xml 中配置 mapper.xml 的位置 <mappers> <mapper resource="mapper.xml 文件的地址" /> <mapper resource="mapper.xml 文件的地址" /> </mappers> (2)定义 mapper 接口(3)实现类集成 SqlSessionDaoSupportmapper 方法中可以 this.getSqlSession()进行数据增删改查。(4)spring 配置 <bean id=" " class="mapper 接口的实现"> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> 第二种:使用 org.mybatis.spring.mapper.MapperFactoryBean:(1)在 sqlMapConfig.xml 中配置 mapper.xml 的位置,如果 mapper.xml 和mappre 接口的名称相同且在同一个目录,这里可以不用配置 <mappers> <mapper resource="mapper.xml 文件的地址" /> <mapper resource="mapper.xml 文件的地址" /> </mappers> (2)定义 mapper 接口:(3)mapper.xml 中的 namespace 为 mapper 接口的地址(4)mapper 接口中的方法名和 mapper.xml 中的定义的 statement 的 id 保持一致(5)Spring 中定义 <bean id="" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="mapper 接口地址" /> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> 第三种:使用 mapper 扫描器:(1)mapper.xml 文件编写:mapper.xml 中的 namespace 为 mapper 接口的地址;mapper 接口中的方法名和 mapper.xml 中的定义的 statement 的 id 保持一致;如果将 mapper.xml 和 mapper 接口的名称保持一致则不用在 sqlMapConfig.xml中进行配置。(2)定义 mapper 接口:注意 mapper.xml 的文件名和 mapper 的接口名称保持一致,且放在同一个目录(3)配置 mapper 扫描器: <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="mapper 接口包地址 "></property> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean> (4)使用扫描器后从 spring 容器中获取 mapper 的实现对象。 27、简述 Mybatis 的插件运行原理,以及如何编写一个插件。 答:Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。编写插件:实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。欢迎大家关注我的公种浩【程序员追风】,2019年多家公司java面试题整理了1000多道400多页pdf文档,文章都会在里面更新,整理的资料也会放在里面。 最后 欢迎大家一起交流,喜欢文章记得关注我点个赞哟,感谢支持!

优秀的个人博客,低调大师

70道阿里百度高频Java面试题(框架+JVM+多线程+算法+数据库)

基础与框架 1.String类能被继承吗,为什么2.String,Stringbuffer,StringBuilder的区别?3.ArrayList和LinkedList有什么区别4.类的实例化顺序,比如父类静态数据,构造函数,字段,子类静态数据,构造函数,字段,他们的执行顺序5.用过哪些Map,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如hashcode,扩容等6.HashMap为什么get和set那么快,concurrentHashMap为什么能提高并发7.抽象类和接口的区别,类可以继承多个类么,接口可以继承多个接口么,类可以实现多个接口么8.什么情况下会发生栈内存溢出9.什么是nio,原理10.反射中,Class.forName和ClassLoader区别11.tomcat结构,类加载器流程12.讲讲Spring事务的传播属性,AOP原理,动态代理与cglib实现的区别,AOP有哪几种实现方式13.Spring的beanFactory和factoryBean的区别14.Spring加载流程15.Spring如何管理事务的 多线程 1.线城池的最大线程数目根据什么确定2.多线程的几种实现方式,什么是线程安全,什么是重排序3.volatile的原理,作用,能代替锁么4.sleep和wait的区别,以及wait的实现原理5.Lock与synchronized 的区别,synchronized 的原理,什么是自旋锁,偏向锁,轻量级锁,什么叫可重入锁,什么叫公平锁和非公平锁6.用过哪些原子类,他们的参数以及原理是什么7.用过哪些线程池,他们的原理简单概括下,构造函数的各个参数的含义,比如coreSize,maxsize等8.有一个第三方接口,有很多个线程去调用获取数据,现在规定每秒钟最多有10个线程同时调用它,如何做到。9.spring的controller是单例还是多例,怎么保证并发的安全10.用三个线程按顺序循环打印abc三个字母,比如abcabcabc11.ThreadLocal用过么,原理是什么,用的时候要注意什么12.如果让你实现一个并发安全的链表,你会怎么做 JVM相关 1.jvm中一次完整的GC流程(从ygc到fgc)是怎样的,重点讲讲对象如何晋升到老年代,几种主要的jvm参数等2.你知道哪几种垃圾收集器,各自的优缺点,重点讲下cms3.当出现了内存溢出,你怎么排错4.JVM内存模型的相关知识了解多少5.简单说说你了解的类加载器6.JAVA的反射机制 网络 1.http1.0和http1.1有什么区别2.TCP三次握手和四次挥手的流程,为什么断开连接要4次,如果握手只有两次,会出现什么3.TIME_WAIT和CLOSE_WAIT的区别4.说说你知道的几种HTTP响应码5.当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤6.Linux下IO模型有几种,各自的含义是什么7.TCP/IP如何保证可靠性,数据包有哪些数据组成8.架构设计与分布式:9.tomcat如何调优,各种参数的意义10.常见的缓存策略有哪些,你们项目中用到了什么缓存系统,如何设计的,Redis的使用要注意什么,持久化方式,内存设置,集群,淘汰策略等11.如何防止缓存雪崩12.用java自己实现一个LRU13.分布式集群下如何做到唯一序列号14.设计一个秒杀系统,30分钟没付款就自动关闭交易15.如何做一个分布式锁16.用过哪些MQ,怎么用的,和其他mq比较有什么优缺点,MQ的连接是线程安全的吗17.MQ系统的数据如何保证不丢失18.分布式事务的原理,如何使用分布式事务19.什么是一致性hash20.什么是restful,讲讲你理解的restful21.如何设计建立和保持100w的长连接?22.解释什么是MESI协议(缓存一致性)23.说说你知道的几种HASH算法,简单的也可以24.什么是paxos算法25.redis和memcached 的内存管理的区别26.一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新 算法 1、10亿个数字里里面找最小的10个2、有1亿个数字,其中有2个是重复的,快速找到它,时间和空间要最优3、2亿个随机生成的无序整数,找出中间大小的值4、遍历二叉树 数据库 1.数据库隔离级别有哪些,各自的含义是什么,MYsql默认的隔离级别是是什么,各个存储引擎优缺点2.高并发下,如何做到安全的修改同一行数据,乐观锁和悲观锁是什么,INNODB的行级锁有哪2种,解释其含义3.SQL优化的一般步骤是什么,怎么看执行计划,如何理解其中各个字段的含义,索引的原理?4.数据库会死锁吗,举一个死锁的例子,mysql怎么解决死锁5.MYsql的索引实现方式6.聚集索引和非聚集索引的区别7.数据库中 BTREE和B+tree区别 最后欢迎大家一起交流,喜欢文章记得点个赞哟,感谢支持!

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册