北京天通苑网站建设h5类型的网站是怎么做的
2026/2/17 5:35:26 网站建设 项目流程
北京天通苑网站建设,h5类型的网站是怎么做的,吉林网站网站建设,商圈外卖网站怎么做📌 Java后端篇(15题) 1. 说说JVM的内存结构? 答案框架(记忆口诀:堆栈方本程) JVM内存分为5个区域: 堆(Heap):存放对象实例,是GC的主要区域,分为新生代(Eden、S0、S1)和老年代 栈(Stack):每个线程私有,存局部变量、方法调用,栈帧包含局部变量表、操作数…📌 Java后端篇(15题)1. 说说JVM的内存结构?答案框架(记忆口诀:堆栈方本程)JVM内存分为5个区域:堆(Heap):存放对象实例,是GC的主要区域,分为新生代(Eden、S0、S1)和老年代栈(Stack):每个线程私有,存局部变量、方法调用,栈帧包含局部变量表、操作数栈、动态链接、返回地址方法区(Method Area):存类信息、常量、静态变量,JDK8后叫元空间(Metaspace)使用直接内存本地方法栈:为Native方法服务程序计数器:线程私有,记录当前执行的字节码行号面试加分项:堆是线程共享的,栈是线程私有的;新生代和老年代比例默认1:22. Java的垃圾回收机制(GC)?答案框架(记忆:识别、算法、收集器)如何识别垃圾:引用计数法(循环引用问题)可达性分析算法:从GC Roots出发,不可达的对象是垃圾GC算法:标记-清除:产生碎片标记-整理:老年代用,整理内存复制算法:新生代用,Eden和Survivor区8:1:1分代收集:新生代复制,老年代标记整理常见收集器:Serial:单线程,适合客户端Parallel:多线程,吞吐量优先CMS:并发标记清除,停顿时间短G1:JDK9默认,面向服务端,可预测停顿ZGC:JDK11,超低延迟3. HashMap底层原理?JDK1.7和1.8的区别?底层结构:JDK1.7:数组+链表JDK1.8:数组+链表+红黑树(链表长度8且数组长度=64时转红黑树)put流程:计算key的hash值根据hash值找到数组下标如果位置为空,直接插入如果不为空,判断key是否相同,相同则覆盖value不同则遍历链表/红黑树插入关键参数:初始容量:16负载因子:0.75扩容:容量翻倍,重新hash(JDK1.8优化了rehash)1.7和1.8区别:1.7:头插法(并发可能死循环),先扩容后插入1.8:尾插法,先插入后扩容,引入红黑树4. ConcurrentHashMap实现原理?JDK1.7:分段锁(Segment数组),每个Segment是ReentrantLockJDK1.8:取消Segment,使用Node数组+CAS+synchronized锁粒度更细:锁住数组的某个位置(链表或红黑树头节点)put流程:CAS尝试插入,失败则synchronized锁住头节点为什么线程安全:初始化用CAS添加元素用synchronized锁住桶扩容时协助扩容(多线程)5. Spring Bean的生命周期?记忆口诀:实例化、填充、初始化、使用、销毁实例化:通过反射创建Bean实例属性填充:依赖注入(@Autowired)Aware接口回调:BeanNameAware、BeanFactoryAware等BeanPostProcessor前置处理:postProcessBeforeInitialization初始化:@PostConstruct、InitializingBean、init-methodBeanPostProcessor后置处理:postProcessAfterInitialization(AOP在这里)使用Bean销毁:@PreDestroy、DisposableBean、destroy-method面试加分项:循环依赖用三级缓存解决(单例、非构造器注入)6. Spring的事务传播机制?7种传播行为(记重点3个):必记:REQUIRED(默认):有事务加入,没有创建新的REQUIRES_NEW:总是创建新事务,挂起当前事务NESTED:嵌套事务,外层回滚内层也回滚,内层回滚外层可以不回滚其他:SUPPORTS:有就用,没有就非事务NOT_SUPPORTED:非事务执行,挂起当前事务MANDATORY:必须有事务,否则抛异常NEVER:必须非事务,否则抛异常失效场景:方法不是public同一类内部调用(没走代理)异常被catch没抛出抛出的不是RuntimeException或Error7. Spring Boot自动配置原理?核心注解:@SpringBootApplication=@Configuration+@EnableAutoConfiguration+@ComponentScan自动配置流程:@EnableAutoConfiguration导入AutoConfigurationImportSelector读取spring.factories文件的配置类全限定名通过@Conditional条件注解判断是否生效满足条件则加载配置类到容器常见@Conditional:@ConditionalOnClass:类存在@ConditionalOnMissingBean:Bean不存在@ConditionalOnProperty:配置属性匹配8. MySQL索引原理?为什么用B+树?索引类型:主键索引(聚簇索引):叶子节点存数据普通索引(二级索引):叶子节点存主键值,需要回表查询唯一索引、全文索引为什么用B+树:B+树vs二叉树:B+树高度低,磁盘IO次数少(百万数据3-4层)B+树vs B树:B+树非叶子节点不存数据,能存更多索引,扇出更大B+树叶子节点有链表,范围查询效率高B+树更稳定,查询都是从根到叶子面试加分项:聚簇索引:InnoDB主键索引非聚簇索引:MyISAM,叶子节点存地址回表:通过二级索引查到主键,再用主键查完整数据9. MySQL事务隔离级别?如何解决幻读?4种隔离级别(记忆:未读提不可串):读未提交(READ UNCOMMITTED):脏读、不可重复读、幻读都有读已提交(READ COMMITTED):解决脏读,Oracle默认可重复读(REPEATABLE READ):解决不可重复读,MySQL默认,通过MVCC+间隙锁解决幻读串行化(SERIALIZABLE):全部解决,但性能差问题定义:脏读:读到未提交的数据不可重复读:同一事务两次读数据不一致(其他事务UPDATE)幻读:同一事务两次查询记录数不一致(其他事务INSERT/DELETE)MySQL如何解决幻读:MVCC(多版本并发控制):快照读,读历史版本Next-Key Lock(记录锁+间隙锁):当前读,锁住范围10. Redis数据类型及应用场景?5种基本类型:String:缓存、计数器、分布式锁(SETNX)Hash:存对象,如用户信息List:消息队列、文章列表、LPUSH+RPOPSet:去重、共同好友、抽奖(SRANDMEMBER)ZSet(有序集合):排行榜、延时队列3种特殊类型:HyperLogLog:UV统计(基数统计)Bitmap:签到、布隆过滤器GEO:地理位置11. Redis持久化机制?两种方式:RDB(快照):优点:文件小,恢复快缺点:可能丢失最后一次快照后的数据触发:SAVE、BGSAVE、自动触发(save 900 1)AOF(Append Only File):优点:数据完整性好缺点:文件大,恢复慢策略:always(每次写)、everysec(每秒)、no(操作系统决定)混合持久化(4.0+):RDB作为基础,AOF记录增量兼顾恢复速度和数据安全12. Redis缓存穿透、击穿、雪崩?缓存穿透:查询不存在的数据,缓存和数据库都没有解决:布隆过滤器、缓存空值缓存击穿:热点key过期,大量请求打到数据库解决:热点数据永不过期、互斥锁(setnx)缓存雪崩:大量key同时过期或Redis宕机解决:过期时间加随机值、Redis集群、限流降级13. 分布式锁的实现方式?Redis实现:// 加锁:SETNX + 过期时间(原子性) SET lock_key unique_value NX PX 30000 // 解锁:Lua脚本保证原子性 if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end注意点:value要唯一(UUID),防止误删设置过期时间,防止死锁使用Redisson框架(看门狗机制)其他实现:Zookeeper:临时顺序节点数据库:乐观锁(version)、悲观锁(for update)14. 线程池核心参数及执行流程?7个核心参数:corePoolSize:核心线程数maximumPoolSize:最大线程数keepAliveTime:空闲线程存活时间unit:时间单位workQueue:阻塞队列threadFactory:线程工厂handler:拒绝策略执行流程:线程数 corePoolSize:创建核心线程线程数 = corePoolSize:放入队列队列满 线程数 maximumPoolSize:创建非核心线程线程数 = maximumPoolSize:执行拒绝策略4种拒绝策略:AbortPolicy:抛异常(默认)CallerRunsPolicy:调用者线程执行DiscardPolicy:直接丢弃DiscardOldestPolicy:丢弃最老的任务15. 消息队列如何保证消息不丢失?(以RabbitMQ为例)三个环节:1. 生产者-MQ:发送确认开启confirm机制,收到ack才算成功失败重试或记录日志2. MQ自身:持久化交换机、队列、消息都设置持久化durable=true3. MQ-消费者:手动ack关闭自动ack业务处理成功后手动确认失败后requeue或放入死信队列额外保障:消费端幂等性处理(防止重复消费)消息表记录状态,定时任务补偿🎨 React前端篇(15题)16. React的虚拟DOM和Diff算法?虚拟DOM:用JS对象描述真实DOM树,对比差异后批量更新Diff算法三大策略:Tree Diff:只比较同层节点,不跨层级Component Diff:同类型组件才对比Virtual DOM,不同类型直接替换Element Diff:同层元素通过key识别,移动而非重建key的作用:唯一标识,帮助React识别哪些元素改变不要用index作为key(顺序变化会导致全部重新渲染)React 18的并发渲染:Fiber架构:可中断的渲染时间切片:把渲染任务拆分,不阻塞主线程17. React Hooks为什么不能在条件语句中使用?原因:Hooks依赖调用顺序来维护状态React内部用链表存储Hooks,每次渲染按顺序调用:第一个useState对应链表第一个节点第二个useEffect对应第二个节点如果在条件语句中使用:// ❌ 错误示例 if (condition) { useState(0); // 可能不执行,打乱顺序 }链表顺序错乱,导致状态错乱规则:只在顶层调用Hooks只在React函数中调用Hooks18. useState和useReducer的区别?useState:适合简单状态直接更新值const [count, setCount] = useState(0); setCount(count + 1);useReducer:适合复杂状态逻辑通过dispatch(action)更新类似Redux,可预测的状态管理const [state, dispatch] = useReducer(reducer, initialState); dispatch({ type: 'increment' });使用场景:多个子值组成的复杂对象:useReducer下一个状态依赖前一个:useReducer简单的独立值:useState19. useEffect和useLayoutEffect的区别?执行时机:useEffect:异步执行,DOM更新后、浏览器绘制后useLayoutEffect:同步执行,DOM更新后、浏览器绘制前使用场景:useEffect:99%的场景,数据获取、订阅、副作用useLayoutEffect:需要同步测量DOM、避免闪烁(如动画、滚动位置)例子:// 会闪烁 useEffect(() = { ref.current.style.top = '100px'; // 先渲染再改样式 }, []); // 不会闪烁 useLayoutEffect(() = { ref.current.style.top = '100px'; // 渲染前就改样式 }, []);20. React性能优化手段?1. 避免不必要的渲染:React.memo:函数组件浅比较propsuseMemo:缓存计算结果useCallback:缓存函数引用PureComponent:类组件浅比较props和state2. 代码分割:React.lazy + Suspense:路由懒加载动态import()3. 虚拟列表:react-window、react-virtualized只渲染可见区域4. 合理使用key:列表渲染必须有唯一key不用index作key5. 避免内联对象和函数:// ❌ 每次渲染都创建新对象 Child style={ { color: 'red' }} / // ✅ 提取到外部 const style = { color: 'red' }; Child style={style} /21. React的状态管理方案对比?1. Redux:优点:可预测、时间旅行、中间件生态缺点:样板代码多、学习曲线陡适合:大型应用、复杂状态2. Zustand:优点:API简洁、无Provider包裹、性能好适合:中小型应用3. Mobx:优点:响应式、代码少缺点:不够明确、调试困难适合:快速开发4. Context + useReducer:优点:原生、无需引入库缺点:性能问题(Provider的value变化所有消费者重渲染)适合:轻量级状态共享5. Redux Toolkit(推荐):Redux的现代封装简化Redux代码内置immer、thunk22. 闭包陷阱及解决方案?问题:function Counter() { const [count, setCount] = useState(0); useEffect(() = { const timer = setInterval(() = { setCount(count + 1); // count永远是0,闭包陷阱! }, 1000); return () = clearInterval(timer); }, []); // 依赖数组为空,只执行一次 }解决方案:方法1:使用函数式更新setCount(prevCount = prevCount + 1);方法2:添加依赖useEffect(() = { const timer = setInterval(() = { setCount(count + 1); }, 1000); return () = clearInterval(timer); }, [count]); // 每次count变化重新创建定时器方法3:使用useRefconst countRef = useRef(count); countRef.current = count;23. React Router的原理?两种模式:1. Hash模式:URL:http://example.com/#/home监听:window.addEventListener('hashchange', fn)特点:兼容性好,但URL有#号2. History模式(主流):URL:http://example.com/homeAPI:history.pushState()、history.replaceState()监听:window.addEventListener('popstate', fn)注意:需要服务端配置,否则刷新404实现原理:通过Context传递路由信息监听URL变化匹配路由组件渲染对应组件24. React事件机制(合成事件)?特点:

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询