#
經過幾次搶購,相信有些 unwire 讀者已經買到 Letv X50 Air 超級智能電視,在家享受它的豐富內容,以及準備欣賞 HKTV 直播劇集了吧。
而它提供的內容中,最吸引的肯定是 4K 影片及劇集。相信大家都知道,4K 內容檔案本身容量十分大,還要透過網絡進行串流,一般情況也會「窒下窒下」,但為何在 X50 Air 上會如此順暢?以下小編就為大家解構一下:
好了,謎底揭曉!
其實很多時候欣賞串流內容(streaming)時要等,是因為 cache 時間十分長,導致影響載入時候。
而 Letv 就採用了 CDN(Content Delivery / Distribution Network;內容傳遞網路)網路,它的總承載量比單一骨幹最大的頻寬還要大,而且有異地備援,萬一某個伺服器出現故障,系統就會自動調用其他鄰近地區的伺服器資源,所以可靠度極之接近 100%;
就算沒有故障時,樂視香港的 CDN 網絡亦可有效回避繁忙擠塞的網絡,並自動尋找距離用家最接近的快取伺服器接收內容,因此可以改善內容存取速度,大大縮短下載時間,自然可以用串流網絡,順暢欣賞極致 4K 影片內容啦。
有非常非常多的 jQuery 插件,这些插件可以简化你的 Web 应用开发。今天我们向你推荐 15 个用于布局和 UI 增强的 jQuery 插件。
Superscrollorama

jQuery File Upload Demo

jQuery Knob

jQuery Complexify

rcarousel

turn.js

jQuery HiddenPosition

Fancy Input

pickadate.js

Cool Kitten

stellar.js

windows

Infinite Scrolling

Autobrowse jQuery Infinite scrolling plugin using Ajax

jScrollPane

如果有人问你,作为一个软件架构师需要哪些特质的话,你会怎么回答?从技术层面上讲,架构师的技术要求是首位的。除此之外在做人处事方面,更有魅力的架构师则更受欢迎。 最近有个同事问我,是什么成就了一个架构师。下文就是我的回答,适用于各个技术领域。其中我故意不考虑企业架构相关的问题。 1、了解相关领域的技术知识 在你想要成为架构师的相关技术领域,必须具备扎实的专业知识和过人的本领。 2、超强的分析、设计能力 不管怎样,具备很强的分析和设计能力都是必杀技。另外就是能够运用设计模式方式解决各种各样的问题。 3、编码与验证性测试(POC) 熟悉该组织整个技术栈,并能使用各层的技术熟练地编码。 能快速实现验证性测试。 4、架构设计的实力 能为原始需求提供架构方案。 考虑周全:工具和框架的采用、安全性、性能和扩展性、依赖关系、集成、效益。 熟悉软件开发生命周期(SDLC):需求、分析、设计、测试、打包、部署。 5、建模语言或工具 能使用不同的建模语言或工具,向其他架构师、开发者、项目经理等人,阐述架构。 6、架构框架 能证明架构的可行性,包括其业务、应用、数据、基础设置方面。 了解TOGAF和ZACHMAN框架就更好了。 7、沟通能力 能与开发人员、测试人员、商业分析师、上级经理沟通无阻,无论在口头上和书面上。 8、布道 能讲解该行业的市场、技术知识。 能为全队提供培训课程。 9、销售、甚至售前 能参与售前工作(尤其对于软件服务业):制定技术方案、使用各种预算工具估计方案的规模和成本、与销售对象互动。 10、演讲技巧 优秀的演讲技巧,有助于以下活动:华丽的计划书和技术文档、PPT演讲、布道。
在pom.xml中加入JAR包
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
ZipUtil.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ZipUtil {
private static Logger logger = LoggerFactory.getLogger(ZipUtil.class);
public static void extractFolder(InputStream inputStream, String outputFolder) throws IOException
{
ZipInputStream zis = null;
try {
Charset GBK = Charset.forName("GBK");
zis = new ZipInputStream(inputStream, GBK);
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
// Create a file on HDD in the destinationPath directory
// destinationPath is a "root" folder, where you want to extract your ZIP file
String encoding = System.getProperty("file.encoding");
logger.info("encoding:"+encoding);
String fileName = new String(entry.getName().getBytes("GBK"), encoding);
File entryFile = new File(outputFolder, fileName);
// File entryFile = new File(outputFolder, entry.getName());
if (entry.isDirectory()) {
if (entryFile.exists()) {
logger.warn("Directory {0} already exists!", entryFile);
} else {
entryFile.mkdirs();
}
} else {
// Make sure all folders exists (they should, but the safer, the better ;-))
if (entryFile.getParentFile() != null && !entryFile.getParentFile().exists()) {
entryFile.getParentFile().mkdirs();
}
// Create file on disk
if (!entryFile.exists()) {
entryFile.createNewFile();
}
// and rewrite data from stream
OutputStream os = null;
try {
os = new FileOutputStream(entryFile);
IOUtils.copy(zis, os);
} finally {
// os.close();
IOUtils.closeQuietly(os);
zis.closeEntry();
}
}
}
} finally {
IOUtils.closeQuietly(zis);
}
}
public static void main(String [] args) throws IOException
{
final String INPUT_ZIP_FILE = "D:TESTING-FILE/ZIP/INPUT/应用.zip";
String OUTPUT_FOLDER = "D:/TESTING-FILE/ZIP/OUTPUT";
OUTPUT_FOLDER += File.separator + UUID.randomUUID().toString();
InputStream inputStream = new FileInputStream(new File(INPUT_ZIP_FILE));
extractFolder(inputStream, OUTPUT_FOLDER);
/*File file = new File(OUTPUT_FOLDER);
FileUtil.deleteFolder(file);*/
}
}
pom.xml回入以下包:
<dependency>
<groupId>net.sf.jxls</groupId>
<artifactId>jxls-core</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jxls</groupId>
<artifactId>jxls-reader</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jxls</groupId>
<artifactId>jxls-examples</artifactId>
</dependency>
转换的配置文件:
<workbook>
<worksheet name="Sheet1">
<section startRow="0" endRow="0" />
<loop startRow="1" endRow="1" items="result" var="app" varType="n.app.valueobject.App">
<section startRow="1" endRow="1">
<mapping row="1" col="0">app.title</mapping>
<mapping row="1" col="1">app.categoryId</mapping>
<mapping row="1" col="2">app.updateContent</mapping>
<mapping row="1" col="3">app.rank</mapping>
<mapping row="1" col="4">app.installedQty</mapping>
<mapping row="1" col="5">app.installedType</mapping>
<mapping row="1" col="6">app.discuss</mapping>
<mapping row="1" col="7">app.summary</mapping>
<mapping row="1" col="8">app.deviceTypes</mapping>
<mapping row="1" col="9">app.description</mapping>
<mapping row="1" col="10">app.newFeatures</mapping>
<mapping row="1" col="11">app.shortRecommend</mapping>
<mapping row="1" col="12">app.appUrl</mapping>
</section>
<loopbreakcondition>
<rowcheck offset="0">
<cellcheck offset="0" />
</rowcheck>
</loopbreakcondition>
</loop>
</worksheet>
</workbook>
JAVA代码:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jxls.reader.ReaderBuilder;
import net.sf.jxls.reader.XLSReader;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import application.app.valueobject.App;
public class ExcelUtil<T> {
private static Logger logger = LoggerFactory.getLogger(ExcelUtil.class);
public List<T> parseExcelFileToBeans(InputStream xlsFileInputStream, InputStream jxlsConfigInputStream) throws IOException, SAXException, InvalidFormatException {
List<T> result = new ArrayList<T>();
Map<String, Object> beans = new HashMap<String, Object>();
beans.put("result", result);
InputStream inputStream = null;
try {
XLSReader xlsReader = ReaderBuilder.buildFromXML(jxlsConfigInputStream);
inputStream = new BufferedInputStream(xlsFileInputStream);
xlsReader.read(inputStream, beans);
} catch (IOException e) {
logger.error(e.getMessage(), e);
throw e;
} catch (SAXException e) {
logger.error(e.getMessage(), e);
throw e;
} catch (InvalidFormatException e) {
logger.error(e.getMessage(), e);
throw e;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception e) {
}
}
}
return result;
}
public static void main(String[] args) throws Exception {
String path = "D:/DATA/TESTING-FILE/EXCEL";
path = System.getProperty("user.home");
ExcelUtil<App> util = new ExcelUtil<App>();
String excelFilePath = path + File.separator + "appData.xls";
InputStream configInputStream =
ExcelUtil.class.getResourceAsStream("/excel/template/config/app_config.xml");
InputStream xlsFileInputStream = new FileInputStream(excelFilePath);
List<App> appList = util.parseExcelFileToBeans(xlsFileInputStream, configInputStream);
for (App app : appList) {
System.out.println(app.toString());
}
/*String [] args2 = {""};
GroupingSample.main(args2);*/
}
}
http://www.yihaomen.com/article/java/530.htm
import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* <一句话功能简述>
* <功能详细描述>
*
* @author Administrator
* @version [版本号, 2014年3月7日]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
@Component
@Scope("prototype")
@RequestMapping("/downloadFile")
public class DownloadAction
{
@RequestMapping("download")
public ResponseEntity<byte[]> download() throws IOException {
String path="D:\\workspace\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\springMVC\\WEB-INF\\upload\\图片10(定价后).xlsx";
File file=new File(path);
HttpHeaders headers = new HttpHeaders();
String fileName=new String("你好.xlsx".getBytes("UTF-8"),"iso-8859-1");//为了解决中文名称乱码问题
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}
}
JSP
<a href="./downloadFile/download" >下载</a>
https://github.com/spring-projects/spring-sync-samples/tree/master/spring-rest-todos
package todos;
import static org.hamcrest.Matchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author Roy Clarkson
*/
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = Application.class)
@Ignore
public class MainControllerTest {
@Autowired
private WebApplicationContext context;
@Mock
private TodoRepository repository;
@InjectMocks
TodoController mainController;
private MockMvc mvc;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mvc = MockMvcBuilders.standaloneSetup(mainController).build();
}
@Test
public void testList() throws Exception {
final Todo a = new Todo(1L, "a", false);
final Todo b = new Todo(2L, "b", false);
final Todo c = new Todo(3L, "c", false);
when(repository.findAll()).thenReturn(Arrays.asList(a, b, c));
mvc.perform(get("/todos")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$", hasSize(3)))
.andExpect(jsonPath("$[0].id", is(1)))
.andExpect(jsonPath("$[0].description", is("a")))
.andExpect(jsonPath("$[0].complete", is(false)))
.andExpect(jsonPath("$[1].id", is(2)))
.andExpect(jsonPath("$[1].description", is("b")))
.andExpect(jsonPath("$[1].complete", is(false)))
.andExpect(jsonPath("$[2].id", is(3)))
.andExpect(jsonPath("$[2].description", is("c")))
.andExpect(jsonPath("$[2].complete", is(false)));
verify(repository, times(1)).findAll();
verifyNoMoreInteractions(repository);
}
@Ignore
@Test
public void testPatch() throws Exception {
}
@Test
public void testCreate() throws Exception {
final Todo todo = new Todo(1L, "a", false);
ObjectMapper objectMapper = new ObjectMapper();
final byte[] bytes = objectMapper.writeValueAsBytes(todo);
when(repository.save(Mockito.any(Todo.class))).thenReturn(todo);
mvc.perform(post("/todos")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.content(bytes))
.andExpect(status().isOk())
.andExpect(jsonPath("$.id", is(1)))
.andExpect(jsonPath("$.description", is("a")))
.andExpect(jsonPath("$.complete", is(false)));
verify(repository, times(1)).save(Mockito.any(Todo.class));
verifyNoMoreInteractions(repository);
}
@Test
public void testUpdateSameIds() throws Exception {
final Todo updatedTodo = new Todo(1L, "z", true);
ObjectMapper objectMapper = new ObjectMapper();
byte[] bytes = objectMapper.writeValueAsBytes(updatedTodo);
when(repository.save(Mockito.any(Todo.class))).thenReturn(updatedTodo);
mvc.perform(put("/todos/{id}", 1L)
.contentType(MediaType.APPLICATION_JSON)
.content(bytes))
.andExpect(status().isNoContent());
verify(repository, times(0)).delete(1L);
verify(repository, times(1)).save(Mockito.any(Todo.class));
verifyNoMoreInteractions(repository);
}
@Test
public void testUpdateDifferentIds() throws Exception {
final Todo updatedTodo = new Todo(99L, "z", true);
ObjectMapper objectMapper = new ObjectMapper();
byte[] bytes = objectMapper.writeValueAsBytes(updatedTodo);
when(repository.save(Mockito.any(Todo.class))).thenReturn(updatedTodo);
mvc.perform(put("/todos/{id}", 1L)
.contentType(MediaType.APPLICATION_JSON)
.content(bytes))
.andExpect(status().isNoContent());
verify(repository, times(1)).delete(1L);
verify(repository, times(1)).save(Mockito.any(Todo.class));
verifyNoMoreInteractions(repository);
}
@Test
public void testDelete() throws Exception {
// this is how to test a void method with Mockito
// doThrow(new IllegalArgumentException()).when(repository).delete(null);
mvc.perform(delete("/todos/{id}", 1L))
.andExpect(status().isNoContent());
}
}
关于系统用例的书籍,太多。不想在这里去解释什么是系统用例。但为什么要写系统用例呢,又如何写好呢?
写系统用例是为了更清晰的展示系统的业务场景的功能实现。也是为了给程序员参考的一个图。同时也是与客户沟通的桥梁。很多东西,千言万语,不如一张图那么直观。但在很多项目中,用例分析这个过程被忽略而过。
程序员往往只看到文本的需求,就自己开始做了,对于小项目或许这样可以,如果是大项目,后期肯定崩溃。
一个良好的系统用例,用图形的方式描述了客户的要求:
1. 有那些人去参与这个事件。
2.这些人具体要做什么 (可以理解为调用的方法)
3.这些人做这个事情,需要什么先决条件 (可以理解为参数,包括权限等等)
4.这些在做这些事情的时候,需要第三方帮忙吗?或者需要第三方系统接口吗?
5.做完这些事情,应该达到一个什么样的目的,也就是结果,这个结果会是下一个用例的输入吗?
当你有着人物,事件,参数,输入,输出的一张图 摆在眼前的时候,所有的事情的都清晰了。
看着这张图,就可以写出 相关的接口程序,实现方法等。
通过大量的系统用例,可以提取出公共的用例,比如权限等。从而抽象出公共的实现方法,才不会导致同一个方法,不同的程序员各自实现了一套。
以图书为例子,列表说明一个用例的主要部分,以及要表达清楚的地方。
用例名称 | bu_借阅图书 |
用例描述 | 借阅人通过此用例向系统查询并提交借书请求 |
执行者 | 借阅人 |
前置条件 | 1. 借阅人借阅证件在有效期内 2. 借阅人没有逾期未归还的图书 |
后置条件 | 1. 创建借书定单 2. 更新借阅人借阅记录 |
主过程描述 | 1用户用借阅证提供的帐号登录系统,计算机显示我的图书馆界面 2.用户选择查询图书,计算机显示查询界面 3.用户按书名、作者、出版社查询,计算机显示查询结果 4.用户可单选或多选书本,并确认借阅。计算机显示确认借阅图书清单。 5.用户选择确认借阅,计算机显示借阅定单及费用 6用户选择提交定单,计算机显示提交结果和定单号 7.计算机执行后置条件。用例结束 |
分支过程描述 | 2.1.1用户选择查看原有定单,计算机执行4; 4.1.1用户可单选或多选书本,放入借书篮,计算机显示借书篮现有内容 4.1.2.1.1用户选择继续借书,计算机执行2; 4.1.2.2.1用户选择提交借书篮,计算机执行4 4.2.1 用户选择放弃,计算机执行2; 6.1.1用户选择保存定单,计算机保存并执行1; 6.2.1用户选择放弃,计算机执行1; |
异常过程描述 | 1.1.1借阅证已过期,拒绝登录,用例结束 1.2.1借阅人有逾期未归还书本,启动bu_归还图书用例 5.1.1用户余额不足,计算机显示余额和所需金额 5.1.2.1.1用户选择续费,启动bu_交纳借阅费用例 5.1.2.2.1用户选择放弃,计算机执行1 |
业务规则 | 4.至少选择一本,至多选择三本 |
涉及的业务实体 | Be_费用记录 Be_图书 Be_借书篮 Be_借阅定单 Be_借阅证 |
启动STORAGE SERVER
fdfs_storaged /etc/fdfs/storage.conf
启动TRACKER SERVER
fdfs_trackerd /etc/fdfs/tracker.conf
启动NGINX
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
观看LOG
tail -f /home/storage1/fastdfs/logs/storaged.log
检查STORAGE SERVER
fdfs_monitor /etc/fdfs/client.conf
删除STORAGE SERVER
fdfs_monitor /etc/fdfs/client.conf delete group1 10.120.151.114
重启
/usr/local/bin/restart.sh fdfs_storaged /etc/fdfs/storage.conf
/usr/local/bin/restart.sh fdfs_trackerd /etc/fdfs/storage.conf
停止
/usr/local/bin/stop.sh fdfs_storaged /etc/fdfs/storage.conf
/usr/local/bin/stop.sh fdfs_trackerd /etc/fdfs/storage.conf
测试上传
fdfs_test /etc/fdfs/client.conf upload /usr/include/stdlib.h
查询文件是否存在
fdfs_file_info /etc/fdfs/client.conf group1/M00/00/D1/CniXclQ0vdfCNdkzAABGC4v7nb4822.png