应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

面试官线程池灵魂8连问,你挡的住吗?

  大家好,这篇文章主要跟大家聊下Java线程池面试中可能会问到的一些问题。
  全程干货,耐心看完,你能轻松应对各种线程池面试。
  相信各位Javaer在面试中或多或少肯定被问到过线程池相关问题吧,线程池是一个相对比较复杂的体系,基于此可以问出各种各样、五花八门的问题。
  若你很熟悉线程池,如果可以,完全可以滔滔不绝跟面试官扯一个小时线程池,一般面试也就一个小时左右,那么这样留给面试官问其他问题的时间就很少了,或者其他问题可能问的也就不深入了,那你通过面试的几率是不就更大点了呢。
  下面我们开始列下线程池面试可能会被问到的问题以及该怎么回答,以下只是参考答案,你也可以加入自己的理解。
  1。面试官:日常工作中有用到线程池吗?什么是线程池?为什么要使用线程池?
  一般面试官考察你线程池相关知识前,大概率会先问这个问题,如果你说没用过,不了解,ok,那就没以下问题啥事了,估计你的面试结果肯定也凶多吉少了。
  作为JUC包下的门面担当,线程池是名副其实的JUC一哥,不了解线程池,那说明你对JUC包其他工具也了解的不咋样吧,对JUC没深入研究过,那就是没掌握到Java的精髓,给面试官这样一个印象,那结果可想而知了。
  所以说,这一分一定要吃下,那我们应该怎么回答好这问题呢?
  可以这样说:
  计算机发展到现在,摩尔定律在现有工艺水平下已经遇到难易突破的物理瓶颈,通过多核CPU并行计算来提升服务器的性能已经成为主流,随之出现了多线程技术。
  线程作为操作系统宝贵的资源,对它的使用需要进行控制管理,线程池就是采用池化思想(类似连接池、常量池、对象池等)管理线程的工具。
  JUC给我们提供了ThreadPoolExecutor体系类来帮助我们更方便的管理线程、并行执行任务。
  下图是Java线程池继承体系:
  使用线程池可以带来以下好处:降低资源消耗。降低频繁创建、销毁线程带来的额外开销,复用已创建线程
  降低使用复杂度。将任务的提交和执行进行解耦,我们只需要创建一个线程池,然后往里面提交任务就行,具体执行流程由线程池自己管理,降低使用复杂度
  提高线程可管理性。能安全有效的管理线程资源,避免不加限制无限申请造成资源耗尽风险
  提高响应速度。任务到达后,直接复用已创建好的线程执行
  线程池的使用场景简单来说可以有:快速响应用户请求,响应速度优先。比如一个用户请求,需要通过RPC调用好几个服务去获取数据然后聚合返回,此场景就可以用线程池并行调用,响应时间取决于响应最慢的那个RPC接口的耗时;又或者一个注册请求,注册完之后要发送短信、邮件通知,为了快速返回给用户,可以将该通知操作丢到线程池里异步去执行,然后直接返回客户端成功,提高用户体验。
  单位时间处理更多请求,吞吐量优先。比如接受MQ消息,然后去调用第三方接口查询数据,此场景并不追求快速响应,主要利用有限的资源在单位时间内尽可能多的处理任务,可以利用队列进行任务的缓冲
  2。面试官:ThreadPoolExecutor都有哪些核心参数?
  其实一般面试官问你这个问题并不是简单听你说那几个参数,而是想要你描述下线程池执行流程。青铜回答:
  包含核心线程数(corePoolSize)、最大线程数(maximumPoolSize),空闲线程超时时间(keepAliveTime)、时间单位(unit)、阻塞队列(workQueue)、拒绝策略(handler)、线程工厂(ThreadFactory)这7个参数。钻石回答:
  回答完包含这几个参数之后,会再主动描述下线程池的执行流程,也就是execute()方法执行流程。
  execute()方法执行逻辑如下:
  publicvoidexecute(Runnablecommand){
  if(commandnull)
  thrownewNullPointerException();
  intcctl。get();
  if(workerCountOf(c)corePoolSize){
  if(addWorker(command,true))
  return;
  cctl。get();
  }
  if(isRunning(c)workQueue。offer(command)){
  intrecheckctl。get();
  if(!isRunning(recheck)remove(command))
  reject(command);
  elseif(workerCountOf(recheck)0)
  addWorker(null,false);
  }
  elseif(!addWorker(command,false))
  reject(command);
  }
  可以总结出如下主要执行流程,当然看上述代码会有一些异常分支判断,可以自己顺理加到下述执行主流程里判断线程池的状态,如果不是RUNNING状态,直接执行拒绝策略
  如果当前线程数核心线程池,则新建一个线程来处理提交的任务
  如果当前线程数核心线程数且任务队列没满,则将任务放入阻塞队列等待执行
  如果核心线程池当前线程池数最大线程数,且任务队列已满,则创建新的线程执行提交的任务
  如果当前线程数最大线程数,且队列已满,则执行拒绝策略拒绝该任务
  王者回答:
  在回答完包含哪些参数及execute方法的执行流程后。然后可以说下这个执行流程是JUC标准线程池提供的执行流程,主要用在CPU密集型场景下。
  像Tomcat、Dubbo这类框架,他们内部的线程池主要用来处理网络IO任务的,所以他们都对JUC线程池的执行流程进行了调整来支持IO密集型场景使用。
  他们提供了阻塞队列TaskQueue,该队列继承LinkedBlockingQueue,重写了offer()方法来实现执行流程的调整。
  Override
  publicbooleanoffer(Runnableo){
  wecantdoanychecks
  if(parentnull)returnsuper。offer(o);
  wearemaxedoutonthreads,simplyqueuetheobject
  if(parent。getPoolSize()parent。getMaximumPoolSize())returnsuper。offer(o);
  wehaveidlethreads,justaddittothequeue
  if(parent。getSubmittedCount()(spanstylecolor:C678DD;ttdarkmodecolor:C678DD;parent。getPoolSize()))returnsuper。offer(o);
  spanifwehavelessthreadsthanmaximumforcecreationofanewthread
  if(parent。getPoolSize()spanstylecolor:C678DD;ttdarkmodecolor:C678DD;parent。getMaximumPoolSize())returnfalse;
  spanifwereachedhere,weneedtoaddittothequeue
  returnsuper。offer(o);
  }
  可以看到他在入队之前做了几个判断,这里的parent就是所属的线程池对象1。如果parent为null,直接调用父类offer方法入队
  2。如果当前线程数等于最大线程数,则直接调用父类offer()方法入队
  3。如果当前未执行的任务数量小于等于当前线程数,仔细思考下,是不是说明有空闲的线程呢,那么直接调用父类offer()入队后就马上有线程去执行它
  4。如果当前线程数小于最大线程数量,则直接返回false,然后回到JUC线程池的执行流程回想下,是不是就去添加新线程去执行任务了呢
  5。其他情况都直接入队
  可以看出当当前线程数大于核心线程数时,JUC原生线程池首先是把任务放到队列里等待执行,而不是先创建线程执行。
  如果Tomcat接收的请求数量大于核心线程数,请求就会被放到队列中,等待核心线程处理,这样会降低请求的总体响应速度。
  所以Tomcat并没有使用JUC原生线程池,利用TaskQueue的offer()方法巧妙的修改了JUC线程池的执行流程,改写后Tomcat线程池执行流程如下:判断如果当前线程数小于核心线程池,则新建一个线程来处理提交的任务
  如果当前当前线程池数大于核心线程池,小于最大线程数,则创建新的线程执行提交的任务
  如果当前线程数等于最大线程数,则将任务放入任务队列等待执行
  如果队列已满,则执行拒绝策略
  然后还可以再说下线程池的Worker线程模型,继承AQS实现了锁机制。线程启动后执行runWorker()方法,runWorker()方法中调用getTask()方法从阻塞队列中获取任务,获取到任务后先执行beforeExecute()钩子函数,再执行任务,然后再执行afterExecute()钩子函数。若超时获取不到任务会调用processWorkerExit()方法执行Worker线程的清理工作。
  3。面试官:什么是阻塞队列?说说常用的阻塞队列有哪些?
  阻塞队列BlockingQueue继承Queue,是我们熟悉的基本数据结构队列的一种特殊类型。
  当从阻塞队列中获取数据时,如果队列为空,则等待直到队列有元素存入。当向阻塞队列中存入元素时,如果队列已满,则等待直到队列中有元素被移除。提供offer()、put()、take()、poll()等常用方法。
  JDK提供的阻塞队列的实现有以下几种:
  1)ArrayBlockingQueue:由数组实现的有界阻塞队列,该队列按照FIFO对元素进行排序。维护两个整形变量,标识队列头尾在数组中的位置,在生产者放入和消费者获取数据共用一个锁对象,意味着两者无法真正的并行运行,性能较低。
  2)LinkedBlockingQueue:由链表组成的有界阻塞队列,如果不指定大小,默认使用Integer。MAXVALUE作为队列大小,该队列按照FIFO对元素进行排序,对生产者和消费者分别维护了独立的锁来控制数据同步,意味着该队列有着更高的并发性能。
  3)SynchronousQueue:不存储元素的阻塞队列,无容量,可以设置公平或非公平模式,插入操作必须等待获取操作移除元素,反之亦然。
  4)PriorityBlockingQueue:支持优先级排序的无界阻塞队列,默认情况下根据自然序排序,也可以指定Comparator。
  5)DelayQueue:支持延时获取元素的无界阻塞队列,创建元素时可以指定多久之后才能从队列中获取元素,常用于缓存系统或定时任务调度系统。
  6)LinkedTransferQueue:一个由链表结构组成的无界阻塞队列,与LinkedBlockingQueue相比多了transfer和tryTranfer方法,该方法在有消费者等待接收元素时会立即将元素传递给消费者。
  7)LinkedBlockingDeque:一个由链表结构组成的双端阻塞队列,可以从队列的两端插入和删除元素。
  4。面试官:你刚说到了Worker继承AQS实现了锁机制,那ThreadPoolExecutor都用到了哪些锁?为什么要用锁?
  1)mainLock锁
  ThreadPoolExecutor内部维护了ReentrantLock类型锁mainLock,在访问workers成员变量以及进行相关数据统计记账(比如访问largestPoolSize、completedTaskCount)时需要获取该重入锁。
  面试官:为什么要有mainLock?
  privatefinalReentrantLockmainLocknewReentrantLock();
  Setcontainingallworkerthreadsinpool。Accessedonlywhen
  holdingmainLock。
  privatefinalHashSetworkersnewHashSet();
  Trackslargestattainedpoolsize。Accessedonlyunder
  mainLock。
  privateintlargestPoolSize;
  Counterforcompletedtasks。Updatedonlyonterminationof
  workerthreads。AccessedonlyundermainLock。
  privatelongcompletedTaskCount;
  可以看到workers变量用的HashSet是线程不安全的,是不能用于多线程环境的。largestPoolSize、completedTaskCount也是没用volatile修饰,所以需要在锁的保护下进行访问。
  面试官:为什么不直接用个线程安全容器呢?
  其实Doug老爷子在mainLock变量的注释上解释了,意思就是说事实证明,相比于线程安全容器,此处更适合用lock,主要原因之一就是串行化interruptIdleWorkers()方法,避免了不必要的中断风暴
  面试官:怎么理解这个中断风暴呢?
  其实简单理解就是如果不加锁,interruptIdleWorkers()方法在多线程访问下就会发生这种情况。一个线程调用interruptIdleWorkers()方法对Worker进行中断,此时该Worker出于中断中状态,此时又来一个线程去中断正在中断中的Worker线程,这就是所谓的中断风暴。
  面试官:那largestPoolSize、completedTaskCount变量加个volatile关键字修饰是不是就可以不用mainLock了?
  这个其实Doug老爷子也考虑到了,其他一些内部变量能用volatile的都加了volatile修饰了,这两个没加主要就是为了保证这两个参数的准确性,在获取这两个值时,能保证获取到的一定是修改方法执行完成后的值。如果不加锁,可能在修改方法还没执行完成时,此时来获取该值,获取到的就是修改前的值。
  2)Worker线程锁
  刚也说了Worker线程继承AQS,实现了Runnable接口,内部持有一个Thread变量,一个firstTask,及completedTasks三个成员变量。
  基于AQS的acquire()、tryAcquire()实现了lock()、tryLock()方法,类上也有注释,该锁主要是用来维护运行中线程的中断状态。在runWorker()方法中以及刚说的interruptIdleWorkers()方法中用到了。
  面试官:这个维护运行中线程的中断状态怎么理解呢?
  protectedbooleantryAcquire(intunused){
  if(compareAndSetState(0,1)){
  setExclusiveOwnerThread(Thread。currentThread());
  returntrue;
  }
  returnfalse;
  }
  publicvoidlock(){acquire(1);}
  publicbooleantryLock(){returntryAcquire(1);}
  在runWorker()方法中获取到任务开始执行前,需要先调用w。lock()方法,lock()方法会调用tryAcquire()方法,tryAcquire()实现了一把非重入锁,通过CAS实现加锁。
  interruptIdleWorkers()方法会中断那些等待获取任务的线程,会调用w。tryLock()方法来加锁,如果一个线程已经在执行任务中,那么tryLock()就获取锁失败,就保证了不能中断运行中的线程了。
  所以Worker继承AQS主要就是为了实现了一把非重入锁,维护线程的中断状态,保证不能中断运行中的线程。
  5。面试官:你在项目中是怎样使用线程池的?Executors了解吗?
  这里面试官主要想知道你日常工作中使用线程池的姿势,现在大多数公司都在遵循阿里巴巴Java开发规范,该规范里明确说明不允许使用Executors创建线程池,而是通过ThreadPoolExecutor显示指定参数去创建
  你可以这样说,知道Executors工具类,很久之前有用过,也踩过坑,Executors创建的线程池有发生OOM的风险。
  Executors。newFixedThreadPool和Executors。SingleThreadPool创建的线程池内部使用的是无界(Integer。MAXVALUE)的LinkedBlockingQueue队列,可能会堆积大量请求,导致OOM
  Executors。newCachedThreadPool和Executors。scheduledThreadPool创建的线程池最大线程数是用的Integer。MAXVALUE,可能会创建大量线程,导致OOM
  自己在日常工作中也有封装类似的工具类,但是都是内存安全的,参数需要自己指定适当的值,也有基于LinkedBlockingQueue实现了内存安全阻塞队列MemorySafeLinkedBlockingQueue,当系统内存达到设置的剩余阈值时,就不在往队列里添加任务了,避免发生OOM
  我们一般都是在Spring环境中使用线程池的,直接使用JUC原生ThreadPoolExecutor有个问题,Spring容器关闭的时候可能任务队列里的任务还没处理完,有丢失任务的风险。
  我们知道Spring中的Bean是有生命周期的,如果Bean实现了Spring相应的生命周期接口(InitializingBean、DisposableBean接口),在Bean初始化、容器关闭的时候会调用相应的方法来做相应处理。
  所以最好不要直接使用ThreadPoolExecutor在Spring环境中,可以使用Spring提供的ThreadPoolTaskExecutor,或者DynamicTp框架提供的DtpExecutor线程池实现。
  也会按业务类型进行线程池隔离,各任务执行互不影响,避免共享一个线程池,任务执行参差不齐,相互影响,高耗时任务会占满线程池资源,导致低耗时任务没机会执行;同时如果任务之间存在父子关系,可能会导致死锁的发生,进而引发OOM。
  6。面试官:刚你说到了通过ThreadPoolExecutor来创建线程池,那核心参数设置多少合适呢?
  这个问题该怎么回答呢?
  可能很多人都看到过《Java并发编程事件》这本书里介绍的一个线程数计算公式:
  NcpuCPU核数
  Ucpu目标CPU利用率,0Ucpu1
  WC等待时间计算时间的比例
  要程序跑到CPU的目标利用率,需要的线程数为:
  NthreadsNcpuUcpu(1WC)
  这公式太偏理论化了,很难实际落地下来,首先很难获取准确的等待时间和计算时间。再着一个服务中会运行着很多线程,比如Tomcat有自己的线程池、Dubbo有自己的线程池、GC也有自己的后台线程,我们引入的各种框架、中间件都有可能有自己的工作线程,这些线程都会占用CPU资源,所以通过此公式计算出来的误差一定很大。
  所以说怎么确定线程池大小呢?
  其实没有固定答案,需要通过压测不断的动态调整线程池参数,观察CPU利用率、系统负载、GC、内存、RT、吞吐量等各种综合指标数据,来找到一个相对比较合理的值。
  所以不要再问设置多少线程合适了,这个问题没有标准答案,需要结合业务场景,设置一系列数据指标,排除可能的干扰因素,注意链路依赖(比如连接池限制、三方接口限流),然后通过不断动态调整线程数,测试找到一个相对合适的值。
  7。面试官:你们线程池是咋监控的?
  因为线程池的运行相对而言是个黑盒,它的运行我们感知不到,该问题主要考察怎么感知线程池的运行情况。
  可以这样回答:
  我们自己对线程池ThreadPoolExecutor做了一些增强,做了一个线程池管理框架。主要功能有监控告警、动态调参。主要利用了ThreadPoolExecutor类提供
  的一些set、get方法以及一些钩子函数。
  动态调参是基于配置中心实现的,核心参数配置在配置中心,可以随时调整、实时生效,利用了线程池提供的set方法。
  监控,主要就是利用线程池提供的一些get方法来获取一些指标数据,然后采集数据上报到监控系统进行大盘展示。也提供了Endpoint实时查看线程池指标数据。
  同时定义了5种告警规则。线程池活跃度告警。活跃度activeCountmaximumPoolSize,当活跃度达到配置的阈值时,会进行事前告警。
  队列容量告警。容量使用率queueSizequeueCapacity,当队列容量达到配置的阈值时,会进行事前告警。
  拒绝策略告警。当触发拒绝策略时,会进行告警。
  任务执行超时告警。重写ThreadPoolExecutor的afterExecute()和beforeExecute(),根据当前时间和开始时间的差值算出任务执行时长,超过配置的阈值会触发告警。
  任务排队超时告警。重写ThreadPoolExecutor的beforeExecute(),记录提交任务时时间,根据当前时间和提交时间的差值算出任务排队时长,超过配置的阈值会触发告警
  通过监控告警可以让我们及时感知到我们业务线程池的执行负载情况,第一时间做出调整,防止事故的发生。
  8。面试官:你在使用线程池的过程中遇到过哪些坑或者需要注意的地方?
  这个问题其实也是在考察你对一些细节的掌握程度,就全甩锅给年轻刚毕业没经验的自己就行。可以适当多说些,也证明自己对线程池有着丰富的使用经验。
  1)OOM问题。刚开始使用线程都是通过Executors创建的,前面说了,这种方式创建的线程池会有发生OOM的风险。
  2)任务执行异常丢失问题。可以通过下述4种方式解决在任务代码中增加try、catch异常处理
  如果使用的Future方式,则可通过Future对象的get方法接收抛出的异常
  为工作线程设置setUncaughtExceptionHandler,在uncaughtException方法中处理异常
  可以重写afterExecute(Runnabler,Throwablet)方法,拿到异常t
  3)共享线程池问题。整个服务共享一个全局线程池,导致任务相互影响,耗时长的任务占满资源,短耗时任务得不到执行。同时父子线程间会导致死锁的发生,今儿导致OOM
  4)跟ThreadLocal配合使用,导致脏数据问题。我们知道Tomcat利用线程池来处理收到的请求,会复用线程,如果我们代码中用到了ThreadLocal,在请求处理完后没有去remove,那每个请求就有可能获取到之前请求遗留的脏值。
  5)ThreadLocal在线程池场景下会失效,可以考虑用阿里开源的Ttl来解决
  以上提到的线程池动态调参、通知告警在开源动态线程池项目DynamicTp中已经实现了,可以直接引入到自己项目中使用。
  关于DynamicTp
  DynamicTp是一个基于配置中心实现的轻量级动态线程池管理工具,主要功能可以总结为动态调参、通知报警、运行监控、三方包线程池管理等几大类。
  经过多个版本迭代,目前最新版本v1。0。8具有以下特性
  特性代码零侵入:所有配置都放在配置中心,对业务代码零侵入轻量简单:基于springboot实现,引入starter,接入只需简单4步就可完成,顺利3分钟搞定高可扩展:框架核心功能都提供SPI接口供用户自定义个性化实现(配置中心、配置文件解析、通知告警、监控数据采集、任务包装等等)线上大规模应用:参考美团线程池实践(https:tech。meituan。com20200402javapoolingpraticeinmeituan。html),美团内部已经有该理论成熟的应用经验多平台通知报警:提供多种报警维度(配置变更通知、活性报警、容量阈值报警、拒绝触发报警、任务执行或等待超时报警),已支持企业微信、钉钉、飞书报警,同时提供SPI接口可自定义扩展实现监控:定时采集线程池指标数据,支持通过MicroMeter、JsonLog日志输出、Endpoint三种方式,可通过SPI接口自定义扩展实现任务增强:提供任务包装功能,实现TaskWrapper接口即可,如MdcTaskWrapper、TtlTaskWrapper、SwTraceTaskWrapper,可以支持线程池上下文信息传递兼容性:JUC普通线程池和Spring中的ThreadPoolTaskExecutor也可以被框架监控,Bean定义时加DynamicTp注解即可可靠性:框架提供的线程池实现Spring生命周期方法,可以在Spring容器关闭前尽可能多的处理队列中的任务多模式:参考Tomcat线程池提供了IO密集型场景使用的EagerDtpExecutor线程池支持多配置中心:基于主流配置中心实现线程池参数动态调整,实时生效,已支持Nacos、Apollo、Zookeeper、Consul、Etcd,同时也提供SPI接口可自定义扩展实现中间件线程池管理:集成管理常用第三方组件的线程池,已集成Tomcat、Jetty、Undertow、Dubbo、RocketMq、Hystrix等组件的线程池管理(调参、监控报警)
  项目地址
  官网:https:dynamictp。cn
  gitee地址:https:gitee。comdromaradynamictp
  原文链接:https:mp。weixin。qq。comsnj9tnz1JI3ZsLeuk8S5DTg

心居冯绍峰本色出演,告别赵丽颖,他依旧能打出一副王炸电视剧《心居》正在热播中,在剧中出现了不少熟悉的面孔。冯绍峰在剧中饰演施源一角,是个经济拮据却一直保持着积极向上的生活态度的人。在不少人看来,剧中冯绍峰绝对是本色出演,从……中老年糖友必知春节这样吃,血糖才能不飙升俗话说民以食为天,在春节这个亲友团聚的美好日子里,大家走访亲友,各种聚会聚餐层出不穷,餐桌上鸡鸭猪海鲜甜食水果等各种美食佳肴更是让人食欲大增。每每这时候,很多中老年糖友都……锌被誉为智力之源,家有孩子别心疼钱,记得多吃5种高锌食物小智今年上五年级了,可是学习成绩却一直不如意。小智的妈妈因为孩子成绩差的问题也比较头疼,虽然不指望小智能做到班级前十名的好成绩,但是希望小智也能混个中等吧,于是小智妈妈开始到处……无缘世界杯后意大利国家队在更衣室大搞破坏引公愤据意大利媒体报道,奋斗在意大利综合编译:近日,在意大利社交媒体上疯传一组视频和照片,这些内容展示了在意大利国家足球队在西西里的芭贝拉体育场以0比1不敌北马其顿后,在更衣室里大搞……6记三分!库里伤退他单节19分,绿军派两人夹击,库里接班人确nba常规赛继续进行,今天勇士队坐镇主场迎战凯尔特人队。最终他们以88:110不敌凯尔特人队。本场比赛库里打了十几分钟便受伤离场。由于本场比赛库里遭遇受伤的情况,再加上维金斯,……赵岩昊2756全队14记三分广厦大胜双杀江苏以常规赛第二名收北京时间3月22日15点30分,CBA常规赛一场比赛,广厦对阵江苏。经过四节激烈较量,最终广厦9780战胜江苏。在取得本场比赛胜利后,广厦常规赛战绩为31胜7负,排名第2名;江……时隔4年,丁彦雨航又要打季后赛了!只是,不一样了CBA季后赛的12路诸侯,已经尘埃落定。这些球队分别是:辽宁、广厦、上海、浙江、广东、深圳、北京、广州、山西、吉林、天津和山东。山东队挤掉了北控、新疆等球队,搭上了……塞尔维亚球迷拉横幅历数北约战争史,中方表态3月21日,外交部发言人汪文斌主持例行记者会。有记者提问,近日,在塞尔维亚首都贝尔格莱德举行的欧罗巴联赛16强比赛中,现场观众拉起多条巨型横幅,历数美国、北约过去数十年中……399元,小米对讲机3发布,支持4G全网通可5000公里对讲小米对讲机34G全国版今日正式发布,售价399元,已开启预约。主要功能亮点包括:全国4G公网5000公里对讲,100小时超长待机,快捷组队,1对1语音通话。网络方面,小米……一碗神仙粥,粥到病除!家家必学我国民间流传的神仙粥歌诀是:一把糯米煮成汤,七根葱白七片姜,熬熟兑入半杯醋,伤风感冒保安康。此粥专治由风寒引起的头痛、浑身酸懒、乏力、发热等症,特别是患病3天内服用,即可……测试下你是不是真的吃货,当你看到几道美味下饭菜会不会流口水?家庭美食大赏大家好,欢迎大家来到我的自媒体,我是美食作者锦绣V山东,现在是春暖花开,万物复苏时节,春天是一个生长的季节,也是孩子长个的黄金期,家长们在这个季节一定不能忽视……位置不同,不必解释一个人站在了山巅,告诉别人他看到了一片汪洋,风景美不胜收。而另一个人只走到了半山腰,告诉别人没有景色,只有满目的荒凉。位置决定了层次,也决定了看问题的角度。庄……
活着就是一种受罪人本身活着就是一种受罪,这个不言而喻。从出生就面对死亡的到来,就像田野的一颗刚发苗的小草一样,秋天后,经过风吹雨打枝繁叶茂后会枯萎一样。人活着在他短暂的几十年里就是让他人让自己……德乙赛程前瞻桑德豪森VS达姆施塔!德乙比分回放LDSPORTS桑德豪森目前在18轮德甲联赛后积19分排名在12,此前两个赛季分别排名在14和15。桑德豪森本赛季8个主场比赛取得3胜2平3负。达姆施塔特目前在18轮德甲……食品黑名单!千万别给孩子吃!家长们注意有些成人过年解馋的零食对孩子的健康可能造成威胁每年都有孩子误食和亲戚喂食造成的悲剧父母应时刻警惕,提醒身边人不要给孩子喂这些食物孩子被哄逗喝酒……9月京东手机销量苹果大赢家iphone13亮眼,国产还是弟弟在互联网买手机,很多人会选择在京东上买,快捷方便售后保障好,所以有很多人选在在京东买手机,每年618和双十一的电商节,京东也是手机厂家的主战场,所以,京东手机销量榜很有代表性,……狼队零封XYG,上演金蝉教学,张大仙感叹狼队比E星还可怕苦瓜原创,翻版必究!《苦瓜电竞》让你体验不一样的电竞主播圈!KPL精彩赛事依旧在企鹅电竞火热进行中,这一次是狼队和XYG的对决,S组的大战,每一场都让人关注,确实是……沈梦辰不再隐忍,揭开杜海涛真面目,9年恋爱不婚,吴昕成背锅侠谁也没想到,杜海涛和另一档节目的沈梦辰在一起了,谁也没想到,大大咧咧的沈梦辰,在恋爱里,是这么的小女生。更是谁也没想到,这段恋情竟然让全网都羡慕了起来,不过再令人羡慕的恋……新机华为新机开始量产骁龙新旗舰又改名了OPPOFindN曝光vivoY32手机入网近日据外媒消息,vivo一款Y系列新机近日在工信部入网,产品证件照曝光。这款手机代号V2158A,名称为vivoY32,采用了轻薄的直屏设计。……原神无相之岩新手攻略保姆级教学原神手游属于是开放世界的游戏,有很多好玩的场景提供跟玩家们挑战,其中无相之岩很多玩家都很熟悉,有不少的小伙伴对于无相之岩很头疼,不知道该怎么打,今天小编就为大家带来无相之岩的新……幼儿园猴妈妈的信中班语言教案活动目标:1、在故事的情境中能大胆感知、理解、表述读图画信。2、进一步感知信的格式,并尝试写信。3、在听听、讲讲、做做中发展其倾听能力、表达能力、动手操作能力……联想17英寸ThinkBookPlus泄露运行Windows10月,泄密大神EvanBlass泄露了联想的一款独特的笔记本电脑,这是一款17英寸的ThinkbookPlus,在键盘的右侧内置图形平板副屏。今天,他更新了新的图片,现在显示……田畑端制作游戏新情报将在2022年公布一款RPG新作在之前的报道中我们提到,《最终幻想15》制作人、已从SE离职的田畑端表示正在开发两部游戏大作,而田畑端近期在接受FAMI通采访时透露,将在2022年公布一款全新RPG。该……33岁的释小龙,从顶流武打童星,到无戏可拍,他经历了什么?4岁那年,第一次拍戏的释小龙因为被威亚吊在半空中,吓得他哇哇大哭。冷着脸的陈同山见状,发出一声怒喝:释小龙,你给我像个男子汉一点!一旁的导演有些讶异,心想:怎么会有……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网